service: hid: Introduce proper AppletResource emulation

This commit is contained in:
Narr the Reg 2023-12-05 18:39:18 -06:00
parent 167efb2d2b
commit e445ef9d60
10 changed files with 526 additions and 13 deletions

View File

@ -541,6 +541,8 @@ add_library(core STATIC
hle/service/hid/xcd.cpp hle/service/hid/xcd.cpp
hle/service/hid/xcd.h hle/service/hid/xcd.h
hle/service/hid/errors.h hle/service/hid/errors.h
hle/service/hid/controllers/applet_resource.cpp
hle/service/hid/controllers/applet_resource.h
hle/service/hid/controllers/console_six_axis.cpp hle/service/hid/controllers/console_six_axis.cpp
hle/service/hid/controllers/console_six_axis.h hle/service/hid/controllers/console_six_axis.h
hle/service/hid/controllers/controller_base.cpp hle/service/hid/controllers/controller_base.cpp

View File

@ -0,0 +1,199 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/core.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/service/hid/controllers/applet_resource.h"
#include "core/hle/service/hid/errors.h"
namespace Service::HID {
AppletResource::AppletResource(Core::System& system_) : system{system_} {}
AppletResource::~AppletResource() = default;
Result AppletResource::CreateAppletResource(u64 aruid) {
const u64 index = GetIndexFromAruid(aruid);
if (index >= AruidIndexMax) {
return ResultAruidNotRegistered;
}
if (data[index].flag.is_assigned) {
return ResultAruidAlreadyRegistered;
}
// TODO: Here shared memory is created for the process we don't quite emulate this part so
// obtain this pointer from system
auto& shared_memory = system.Kernel().GetHidSharedMem();
data[index].shared_memory_handle = &shared_memory;
data[index].flag.is_assigned.Assign(true);
// TODO: InitializeSixAxisControllerConfig(false);
active_aruid = aruid;
return ResultSuccess;
}
Result AppletResource::RegisterAppletResourceUserId(u64 aruid, bool enable_input) {
const u64 index = GetIndexFromAruid(aruid);
if (index < AruidIndexMax) {
return ResultAruidAlreadyRegistered;
}
std::size_t data_index = AruidIndexMax;
for (std::size_t i = 0; i < AruidIndexMax; i++) {
if (!data[i].flag.is_initialized) {
data_index = i;
break;
}
}
if (data_index == AruidIndexMax) {
return ResultAruidNoAvailableEntries;
}
AruidData& aruid_data = data[data_index];
aruid_data.aruid = aruid;
aruid_data.flag.is_initialized.Assign(true);
if (enable_input) {
aruid_data.flag.enable_pad_input.Assign(true);
aruid_data.flag.enable_six_axis_sensor.Assign(true);
aruid_data.flag.bit_18.Assign(true);
aruid_data.flag.enable_touchscreen.Assign(true);
}
data_index = AruidIndexMax;
for (std::size_t i = 0; i < AruidIndexMax; i++) {
if (registration_list.flag[i] == RegistrationStatus::Initialized) {
if (registration_list.aruid[i] != aruid) {
continue;
}
data_index = i;
break;
}
if (registration_list.flag[i] == RegistrationStatus::None) {
data_index = i;
break;
}
}
if (data_index == AruidIndexMax) {
return ResultSuccess;
}
registration_list.flag[data_index] = RegistrationStatus::Initialized;
registration_list.aruid[data_index] = aruid;
return ResultSuccess;
}
void AppletResource::UnregisterAppletResourceUserId(u64 aruid) {
u64 index = GetIndexFromAruid(aruid);
if (index < AruidIndexMax) {
if (data[index].flag.is_assigned) {
data[index].shared_memory_handle = nullptr;
data[index].flag.is_assigned.Assign(false);
}
}
index = GetIndexFromAruid(aruid);
if (index < AruidIndexMax) {
DestroySevenSixAxisTransferMemory();
data[index].flag.raw = 0;
data[index].aruid = 0;
index = GetIndexFromAruid(aruid);
if (index < AruidIndexMax) {
registration_list.flag[index] = RegistrationStatus::PendingDelete;
}
}
}
u64 AppletResource::GetActiveAruid() {
return active_aruid;
}
Result AppletResource::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) {
u64 index = GetIndexFromAruid(aruid);
if (index >= AruidIndexMax) {
return ResultAruidNotRegistered;
}
*out_handle = data[index].shared_memory_handle;
return ResultSuccess;
}
u64 AppletResource::GetIndexFromAruid(u64 aruid) {
for (std::size_t i = 0; i < AruidIndexMax; i++) {
if (registration_list.flag[i] == RegistrationStatus::Initialized &&
registration_list.aruid[i] == aruid) {
return i;
}
}
return AruidIndexMax;
}
Result AppletResource::DestroySevenSixAxisTransferMemory() {
// TODO
return ResultSuccess;
}
void AppletResource::EnableInput(u64 aruid, bool is_enabled) {
const u64 index = GetIndexFromAruid(aruid);
if (index >= AruidIndexMax) {
return;
}
data[index].flag.enable_pad_input.Assign(is_enabled);
data[index].flag.enable_touchscreen.Assign(is_enabled);
}
void AppletResource::EnableSixAxisSensor(u64 aruid, bool is_enabled) {
const u64 index = GetIndexFromAruid(aruid);
if (index >= AruidIndexMax) {
return;
}
data[index].flag.enable_six_axis_sensor.Assign(is_enabled);
}
void AppletResource::EnablePadInput(u64 aruid, bool is_enabled) {
const u64 index = GetIndexFromAruid(aruid);
if (index >= AruidIndexMax) {
return;
}
data[index].flag.enable_pad_input.Assign(is_enabled);
}
void AppletResource::EnableTouchScreen(u64 aruid, bool is_enabled) {
const u64 index = GetIndexFromAruid(aruid);
if (index >= AruidIndexMax) {
return;
}
data[index].flag.enable_touchscreen.Assign(is_enabled);
}
void AppletResource::SetIsPalmaConnectable(u64 aruid, bool is_connectable) {
const u64 index = GetIndexFromAruid(aruid);
if (index >= AruidIndexMax) {
return;
}
data[index].flag.is_palma_connectable.Assign(is_connectable);
}
void AppletResource::EnablePalmaBoostMode(u64 aruid, bool is_enabled) {
const u64 index = GetIndexFromAruid(aruid);
if (index >= AruidIndexMax) {
return;
}
data[index].flag.enable_palma_boost_mode.Assign(is_enabled);
}
} // namespace Service::HID

View File

@ -0,0 +1,87 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <array>
#include "common/bit_field.h"
#include "common/common_types.h"
#include "core/hle/result.h"
namespace Core {
class System;
}
namespace Kernel {
class KSharedMemory;
}
namespace Service::HID {
class AppletResource {
public:
explicit AppletResource(Core::System& system_);
~AppletResource();
Result CreateAppletResource(u64 aruid);
Result RegisterAppletResourceUserId(u64 aruid, bool enable_input);
void UnregisterAppletResourceUserId(u64 aruid);
u64 GetActiveAruid();
Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid);
u64 GetIndexFromAruid(u64 aruid);
Result DestroySevenSixAxisTransferMemory();
void EnableInput(u64 aruid, bool is_enabled);
void EnableSixAxisSensor(u64 aruid, bool is_enabled);
void EnablePadInput(u64 aruid, bool is_enabled);
void EnableTouchScreen(u64 aruid, bool is_enabled);
void SetIsPalmaConnectable(u64 aruid, bool is_connectable);
void EnablePalmaBoostMode(u64 aruid, bool is_enabled);
private:
static constexpr std::size_t AruidIndexMax = 0x20;
enum RegistrationStatus : u32 {
None,
Initialized,
PendingDelete,
};
struct DataStatusFlag {
union {
u32 raw{};
BitField<0, 1, u32> is_initialized;
BitField<1, 1, u32> is_assigned;
BitField<16, 1, u32> enable_pad_input;
BitField<17, 1, u32> enable_six_axis_sensor;
BitField<18, 1, u32> bit_18;
BitField<19, 1, u32> is_palma_connectable;
BitField<20, 1, u32> enable_palma_boost_mode;
BitField<21, 1, u32> enable_touchscreen;
};
};
struct AruidRegisterList {
std::array<RegistrationStatus, AruidIndexMax> flag{};
std::array<u64, AruidIndexMax> aruid{};
};
static_assert(sizeof(AruidRegisterList) == 0x180, "AruidRegisterList is an invalid size");
struct AruidData {
DataStatusFlag flag{};
u64 aruid{};
Kernel::KSharedMemory* shared_memory_handle{nullptr};
};
u64 active_aruid{};
AruidRegisterList registration_list{};
std::array<AruidData, AruidIndexMax> data{};
Core::System& system;
};
} // namespace Service::HID

View File

@ -19,6 +19,11 @@ constexpr Result NpadIsSameType{ErrorModule::HID, 602};
constexpr Result InvalidNpadId{ErrorModule::HID, 709}; constexpr Result InvalidNpadId{ErrorModule::HID, 709};
constexpr Result NpadNotConnected{ErrorModule::HID, 710}; constexpr Result NpadNotConnected{ErrorModule::HID, 710};
constexpr Result InvalidArraySize{ErrorModule::HID, 715}; constexpr Result InvalidArraySize{ErrorModule::HID, 715};
constexpr Result ResultAruidNoAvailableEntries{ErrorModule::HID, 1044};
constexpr Result ResultAruidAlreadyRegistered{ErrorModule::HID, 1046};
constexpr Result ResultAruidNotRegistered{ErrorModule::HID, 1047};
constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302}; constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302};
} // namespace Service::HID } // namespace Service::HID

View File

@ -1,6 +1,8 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/service/hid/hid.h" #include "core/hle/service/hid/hid.h"
#include "core/hle/service/hid/hid_debug_server.h" #include "core/hle/service/hid/hid_debug_server.h"
#include "core/hle/service/hid/hid_firmware_settings.h" #include "core/hle/service/hid/hid_firmware_settings.h"
@ -20,6 +22,12 @@ void LoopProcess(Core::System& system) {
std::shared_ptr<HidFirmwareSettings> firmware_settings = std::shared_ptr<HidFirmwareSettings> firmware_settings =
std::make_shared<HidFirmwareSettings>(); std::make_shared<HidFirmwareSettings>();
// TODO: Remove this hack until this service is emulated properly.
const auto process_list = system.Kernel().GetProcessList();
if (!process_list.empty()) {
resouce_manager->RegisterAppletResourceUserId(process_list[0]->GetId(), true);
}
server_manager->RegisterNamedService( server_manager->RegisterNamedService(
"hid", std::make_shared<IHidServer>(system, resouce_manager, firmware_settings)); "hid", std::make_shared<IHidServer>(system, resouce_manager, firmware_settings));
server_manager->RegisterNamedService( server_manager->RegisterNamedService(

View File

@ -224,8 +224,13 @@ void IHidServer::CreateAppletResource(HLERequestContext& ctx) {
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);
Result result = GetResourceManager()->CreateAppletResource(applet_resource_user_id);
if (result.IsSuccess()) {
result = GetResourceManager()->GetNpad()->Activate(applet_resource_user_id);
}
IPC::ResponseBuilder rb{ctx, 2, 0, 1}; IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess); rb.Push(result);
rb.PushIpcInterface<IAppletResource>(system, resource_manager); rb.PushIpcInterface<IAppletResource>(system, resource_manager);
} }

View File

@ -3,6 +3,7 @@
#include "core/hid/hid_core.h" #include "core/hid/hid_core.h"
#include "core/hle/service/hid/controllers/npad.h" #include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/hid/controllers/palma.h"
#include "core/hle/service/hid/controllers/touchscreen.h" #include "core/hle/service/hid/controllers/touchscreen.h"
#include "core/hle/service/hid/errors.h" #include "core/hle/service/hid/errors.h"
#include "core/hle/service/hid/hid_system_server.h" #include "core/hle/service/hid/hid_system_server.h"
@ -63,13 +64,13 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour
{329, nullptr, "DetachAbstractedPadAll"}, {329, nullptr, "DetachAbstractedPadAll"},
{330, nullptr, "CheckAbstractedPadConnection"}, {330, nullptr, "CheckAbstractedPadConnection"},
{500, nullptr, "SetAppletResourceUserId"}, {500, nullptr, "SetAppletResourceUserId"},
{501, nullptr, "RegisterAppletResourceUserId"}, {501, &IHidSystemServer::RegisterAppletResourceUserId, "RegisterAppletResourceUserId"},
{502, nullptr, "UnregisterAppletResourceUserId"}, {502, &IHidSystemServer::UnregisterAppletResourceUserId, "UnregisterAppletResourceUserId"},
{503, nullptr, "EnableAppletToGetInput"}, {503, &IHidSystemServer::EnableAppletToGetInput, "EnableAppletToGetInput"},
{504, nullptr, "SetAruidValidForVibration"}, {504, nullptr, "SetAruidValidForVibration"},
{505, nullptr, "EnableAppletToGetSixAxisSensor"}, {505, &IHidSystemServer::EnableAppletToGetSixAxisSensor, "EnableAppletToGetSixAxisSensor"},
{506, nullptr, "EnableAppletToGetPadInput"}, {506, &IHidSystemServer::EnableAppletToGetPadInput, "EnableAppletToGetPadInput"},
{507, nullptr, "EnableAppletToGetTouchScreen"}, {507, &IHidSystemServer::EnableAppletToGetTouchScreen, "EnableAppletToGetTouchScreen"},
{510, nullptr, "SetVibrationMasterVolume"}, {510, nullptr, "SetVibrationMasterVolume"},
{511, nullptr, "GetVibrationMasterVolume"}, {511, nullptr, "GetVibrationMasterVolume"},
{512, nullptr, "BeginPermitVibrationSession"}, {512, nullptr, "BeginPermitVibrationSession"},
@ -420,6 +421,129 @@ void IHidSystemServer::GetIrSensorState(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
} }
void IHidSystemServer::RegisterAppletResourceUserId(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
bool enable_input;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_INFO(Service_HID, "called, enable_input={}, applet_resource_user_id={}",
parameters.enable_input, parameters.applet_resource_user_id);
Result result = GetResourceManager()->RegisterAppletResourceUserId(
parameters.applet_resource_user_id, parameters.enable_input);
if (result.IsSuccess()) {
// result = GetResourceManager()->GetNpad()->RegisterAppletResourceUserId(
// parameters.applet_resource_user_id);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IHidSystemServer::UnregisterAppletResourceUserId(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
u64 applet_resource_user_id{rp.Pop<u64>()};
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
GetResourceManager()->UnregisterAppletResourceUserId(applet_resource_user_id);
// GetResourceManager()->GetNpad()->UnregisterAppletResourceUserId(applet_resource_user_id);
// GetResourceManager()->GetPalma()->UnregisterAppletResourceUserId(applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IHidSystemServer::EnableAppletToGetInput(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
bool is_enabled;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_INFO(Service_HID, "called, is_enabled={}, applet_resource_user_id={}",
parameters.is_enabled, parameters.applet_resource_user_id);
GetResourceManager()->EnableInput(parameters.applet_resource_user_id, parameters.is_enabled);
// GetResourceManager()->GetNpad()->EnableInput(parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IHidSystemServer::EnableAppletToGetSixAxisSensor(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
bool is_enabled;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_INFO(Service_HID, "called, is_enabled={}, applet_resource_user_id={}",
parameters.is_enabled, parameters.applet_resource_user_id);
GetResourceManager()->EnableTouchScreen(parameters.applet_resource_user_id,
parameters.is_enabled);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IHidSystemServer::EnableAppletToGetPadInput(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
bool is_enabled;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_INFO(Service_HID, "called, is_enabled={}, applet_resource_user_id={}",
parameters.is_enabled, parameters.applet_resource_user_id);
GetResourceManager()->EnablePadInput(parameters.applet_resource_user_id, parameters.is_enabled);
// GetResourceManager()->GetNpad()->EnableInput(parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IHidSystemServer::EnableAppletToGetTouchScreen(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
bool is_enabled;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x10, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_INFO(Service_HID, "called, is_enabled={}, applet_resource_user_id={}",
parameters.is_enabled, parameters.applet_resource_user_id);
GetResourceManager()->EnableTouchScreen(parameters.applet_resource_user_id,
parameters.is_enabled);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IHidSystemServer::AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx) { void IHidSystemServer::AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx) {
LOG_INFO(Service_AM, "(STUBBED) called"); LOG_INFO(Service_AM, "(STUBBED) called");

View File

@ -38,6 +38,12 @@ private:
void HasLeftRightBattery(HLERequestContext& ctx); void HasLeftRightBattery(HLERequestContext& ctx);
void GetUniquePadsFromNpad(HLERequestContext& ctx); void GetUniquePadsFromNpad(HLERequestContext& ctx);
void GetIrSensorState(HLERequestContext& ctx); void GetIrSensorState(HLERequestContext& ctx);
void RegisterAppletResourceUserId(HLERequestContext& ctx);
void UnregisterAppletResourceUserId(HLERequestContext& ctx);
void EnableAppletToGetInput(HLERequestContext& ctx);
void EnableAppletToGetSixAxisSensor(HLERequestContext& ctx);
void EnableAppletToGetPadInput(HLERequestContext& ctx);
void EnableAppletToGetTouchScreen(HLERequestContext& ctx);
void AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx); void AcquireConnectionTriggerTimeoutEvent(HLERequestContext& ctx);
void AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx); void AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx);
void GetRegisteredDevices(HLERequestContext& ctx); void GetRegisteredDevices(HLERequestContext& ctx);

View File

@ -9,6 +9,7 @@
#include "core/hle/service/hid/resource_manager.h" #include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/hid/controllers/applet_resource.h"
#include "core/hle/service/hid/controllers/console_six_axis.h" #include "core/hle/service/hid/controllers/console_six_axis.h"
#include "core/hle/service/hid/controllers/debug_pad.h" #include "core/hle/service/hid/controllers/debug_pad.h"
#include "core/hle/service/hid/controllers/gesture.h" #include "core/hle/service/hid/controllers/gesture.h"
@ -33,7 +34,9 @@ constexpr auto mouse_keyboard_update_ns = std::chrono::nanoseconds{8 * 1000 * 10
constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz) constexpr auto motion_update_ns = std::chrono::nanoseconds{5 * 1000 * 1000}; // (5ms, 200Hz)
ResourceManager::ResourceManager(Core::System& system_) ResourceManager::ResourceManager(Core::System& system_)
: system{system_}, service_context{system_, "hid"} {} : system{system_}, service_context{system_, "hid"} {
applet_resource = std::make_shared<AppletResource>(system);
}
ResourceManager::~ResourceManager() = default; ResourceManager::~ResourceManager() = default;
@ -77,6 +80,11 @@ void ResourceManager::Initialize() {
system.HIDCore().ReloadInputDevices(); system.HIDCore().ReloadInputDevices();
is_initialized = true; is_initialized = true;
} }
std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const {
return applet_resource;
}
std::shared_ptr<CaptureButton> ResourceManager::GetCaptureButton() const { std::shared_ptr<CaptureButton> ResourceManager::GetCaptureButton() const {
return capture_button; return capture_button;
} }
@ -137,6 +145,46 @@ std::shared_ptr<UniquePad> ResourceManager::GetUniquePad() const {
return unique_pad; return unique_pad;
} }
Result ResourceManager::CreateAppletResource(u64 aruid) {
std::scoped_lock lock{shared_mutex};
return applet_resource->CreateAppletResource(aruid);
}
Result ResourceManager::RegisterAppletResourceUserId(u64 aruid, bool bool_value) {
std::scoped_lock lock{shared_mutex};
return applet_resource->RegisterAppletResourceUserId(aruid, bool_value);
}
void ResourceManager::UnregisterAppletResourceUserId(u64 aruid) {
std::scoped_lock lock{shared_mutex};
applet_resource->UnregisterAppletResourceUserId(aruid);
}
Result ResourceManager::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) {
std::scoped_lock lock{shared_mutex};
return applet_resource->GetSharedMemoryHandle(out_handle, aruid);
}
void ResourceManager::EnableInput(u64 aruid, bool is_enabled) {
std::scoped_lock lock{shared_mutex};
applet_resource->EnableInput(aruid, is_enabled);
}
void ResourceManager::EnableSixAxisSensor(u64 aruid, bool is_enabled) {
std::scoped_lock lock{shared_mutex};
applet_resource->EnableSixAxisSensor(aruid, is_enabled);
}
void ResourceManager::EnablePadInput(u64 aruid, bool is_enabled) {
std::scoped_lock lock{shared_mutex};
applet_resource->EnablePadInput(aruid, is_enabled);
}
void ResourceManager::EnableTouchScreen(u64 aruid, bool is_enabled) {
std::scoped_lock lock{shared_mutex};
applet_resource->EnableTouchScreen(aruid, is_enabled);
}
void ResourceManager::UpdateControllers(std::uintptr_t user_data, void ResourceManager::UpdateControllers(std::uintptr_t user_data,
std::chrono::nanoseconds ns_late) { std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming(); auto& core_timing = system.CoreTiming();
@ -172,14 +220,12 @@ void ResourceManager::UpdateMotion(std::uintptr_t user_data, std::chrono::nanose
} }
IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource) IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<ResourceManager> resource)
: ServiceFramework{system_, "IAppletResource"} { : ServiceFramework{system_, "IAppletResource"}, resource_manager{resource} {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
}; };
RegisterHandlers(functions); RegisterHandlers(functions);
resource->Initialize();
// Register update callbacks // Register update callbacks
npad_update_event = Core::Timing::CreateEvent( npad_update_event = Core::Timing::CreateEvent(
"HID::UpdatePadCallback", "HID::UpdatePadCallback",
@ -233,9 +279,13 @@ IAppletResource::~IAppletResource() {
void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) { void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) {
LOG_DEBUG(Service_HID, "called"); LOG_DEBUG(Service_HID, "called");
Kernel::KSharedMemory* handle;
const u64 applet_resource_user_id = resource_manager->GetAppletResource()->GetActiveAruid();
const auto result = resource_manager->GetSharedMemoryHandle(&handle, applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(ResultSuccess); rb.Push(result);
rb.PushCopyObjects(&system.Kernel().GetHidSharedMem()); rb.PushCopyObjects(handle);
} }
} // namespace Service::HID } // namespace Service::HID

View File

@ -6,11 +6,20 @@
#include "core/hle/service/kernel_helpers.h" #include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Core::Timing { namespace Core::Timing {
struct EventType; struct EventType;
} }
namespace Kernel {
class KSharedMemory;
}
namespace Service::HID { namespace Service::HID {
class AppletResource;
class Controller_Stubbed; class Controller_Stubbed;
class ConsoleSixAxis; class ConsoleSixAxis;
class DebugPad; class DebugPad;
@ -38,6 +47,7 @@ public:
void Initialize(); void Initialize();
std::shared_ptr<AppletResource> GetAppletResource() const;
std::shared_ptr<CaptureButton> GetCaptureButton() const; std::shared_ptr<CaptureButton> GetCaptureButton() const;
std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const; std::shared_ptr<ConsoleSixAxis> GetConsoleSixAxis() const;
std::shared_ptr<DebugMouse> GetDebugMouse() const; std::shared_ptr<DebugMouse> GetDebugMouse() const;
@ -54,6 +64,18 @@ public:
std::shared_ptr<TouchScreen> GetTouchScreen() const; std::shared_ptr<TouchScreen> GetTouchScreen() const;
std::shared_ptr<UniquePad> GetUniquePad() const; std::shared_ptr<UniquePad> GetUniquePad() const;
Result CreateAppletResource(u64 aruid);
Result RegisterAppletResourceUserId(u64 aruid, bool bool_value);
void UnregisterAppletResourceUserId(u64 aruid);
Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid);
void EnableInput(u64 aruid, bool is_enabled);
void EnableSixAxisSensor(u64 aruid, bool is_enabled);
void EnablePadInput(u64 aruid, bool is_enabled);
void EnableTouchScreen(u64 aruid, bool is_enabled);
void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
@ -62,6 +84,9 @@ public:
private: private:
bool is_initialized{false}; bool is_initialized{false};
mutable std::mutex shared_mutex;
std::shared_ptr<AppletResource> applet_resource = nullptr;
std::shared_ptr<CaptureButton> capture_button = nullptr; std::shared_ptr<CaptureButton> capture_button = nullptr;
std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr; std::shared_ptr<ConsoleSixAxis> console_six_axis = nullptr;
std::shared_ptr<DebugMouse> debug_mouse = nullptr; std::shared_ptr<DebugMouse> debug_mouse = nullptr;
@ -106,6 +131,8 @@ private:
std::shared_ptr<Core::Timing::EventType> default_update_event; std::shared_ptr<Core::Timing::EventType> default_update_event;
std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event; std::shared_ptr<Core::Timing::EventType> mouse_keyboard_update_event;
std::shared_ptr<Core::Timing::EventType> motion_update_event; std::shared_ptr<Core::Timing::EventType> motion_update_event;
std::shared_ptr<ResourceManager> resource_manager;
}; };
} // namespace Service::HID } // namespace Service::HID