Initial Resource Manager

This commit is contained in:
Narr the Reg 2023-08-11 23:02:50 -06:00
parent a13ece1ca5
commit 69f5f567d2
22 changed files with 2191 additions and 133 deletions

View File

@ -521,10 +521,19 @@ add_library(core STATIC
hle/service/hid/hidbus.h
hle/service/hid/irs.cpp
hle/service/hid/irs.h
hle/service/hid/resource_manager.cpp
hle/service/hid/resource_manager.h
hle/service/hid/xcd.cpp
hle/service/hid/xcd.h
hle/service/hid/hid_server/base_resource.cpp
hle/service/hid/hid_server/base_resource.h
hle/service/hid/hid_server/hid_result.h
hle/service/hid/hid_server/hid_types.h
hle/service/hid/hid_server/hid_util.h
hle/service/hid/hid_server/npad.cpp
hle/service/hid/hid_server/npad.h
hle/service/hid/hid_server/sixaxis.cpp
hle/service/hid/hid_server/sixaxis.h
hle/service/hid/hidbus/hidbus_result.h
hle/service/hid/hidbus/hidbus_types.h
hle/service/hid/irs/irs_result.h

View File

@ -67,6 +67,34 @@ enum class AppletId : u32 {
LoginShare = 0x18,
WebAuth = 0x19,
MyPage = 0x1A,
Gift = 0x1B,
UserMigration = 0x1C,
PreomiaSys = 0x1D,
Story = 0x1E,
PreomiaUsr = 0x1F,
PreomiaUsrDummy = 0x20,
Sample = 0x21,
PromoteQualification = 0x22,
Unknown35 = 0x35,
Unknown36 = 0x36,
Unknown37 = 0x37,
Unknown38 = 0x38,
DevlopmentTool = 0x3E8,
CombinationLA = 0x3F1,
AeSystemApplet = 0x3F2,
AeOverlayApplet = 0x3F3,
AeStarter = 0x3F4,
AeLibraryAppletAlone = 0x3F5,
AeLibraryApplet1 = 0x3F6,
AeLibraryApplet2 = 0x3F7,
AeLibraryApplet3 = 0x3F8,
AeLibraryApplet4 = 0x3F9,
AppletISA = 0x3FA,
AppletIOA = 0x3FB,
AppletISTA = 0x3FC,
AppletILA1 = 0x3FD,
AppletILA2 = 0x3FE,
};
enum class LibraryAppletMode : u32 {

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "core/core.h"
#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/hid/hid_debug_server.h"
#include "core/hle/service/hid/hid_server.h"
@ -15,11 +16,14 @@ namespace Service::HID {
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
std::shared_ptr<IAppletResource> applet_resource;
std::shared_ptr<ResourceManager> resouce_manager = std::make_shared<ResourceManager>(system);
server_manager->RegisterNamedService("hid", std::make_shared<IHidServer>(system));
server_manager->RegisterNamedService("hid:dbg", std::make_shared<IHidDebugServer>(system));
server_manager->RegisterNamedService("hid:sys", std::make_shared<IHidSystemServer>(system));
server_manager->RegisterNamedService("hid",
std::make_shared<IHidServer>(system, resouce_manager));
server_manager->RegisterNamedService(
"hid:dbg", std::make_shared<IHidDebugServer>(system, resouce_manager));
server_manager->RegisterNamedService(
"hid:sys", std::make_shared<IHidSystemServer>(system, resouce_manager));
server_manager->RegisterNamedService("hidbus", std::make_shared<IHidbusServer>(system));

View File

@ -1,11 +1,17 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/hid/hid_debug_server.h"
#include "core/hle/service/hid/hid_server/hid_result.h"
#include "core/hle/service/hid/hid_server/hid_types.h"
#include "core/hle/service/hid/hid_server/sixaxis.h"
#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/ipc_helpers.h"
namespace Service::HID {
IHidDebugServer::IHidDebugServer(Core::System& system_) : ServiceFramework{system_, "hid:dbg"} {
IHidDebugServer::IHidDebugServer(Core::System& system_, std::shared_ptr<ResourceManager> resource)
: ServiceFramework{system_, "hid:dbg"}, resource_manager{resource} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "DeactivateDebugPad"},
@ -45,22 +51,23 @@ IHidDebugServer::IHidDebugServer(Core::System& system_) : ServiceFramework{syste
{130, nullptr, "DeactivateCaptureButton"},
{131, nullptr, "SetCaptureButtonAutoPilotState"},
{132, nullptr, "UnsetCaptureButtonAutoPilotState"},
{133, nullptr, "SetShiftAccelerometerCalibrationValue"},
{134, nullptr, "GetShiftAccelerometerCalibrationValue"},
{135, nullptr, "SetShiftGyroscopeCalibrationValue"},
{136, nullptr, "GetShiftGyroscopeCalibrationValue"},
{133, &IHidDebugServer::SetShiftAccelerometerCalibrationValue, "SetShiftAccelerometerCalibrationValue"},
{134, &IHidDebugServer::GetShiftAccelerometerCalibrationValue, "GetShiftAccelerometerCalibrationValue"},
{135, &IHidDebugServer::SetShiftGyroscopeCalibrationValue, "SetShiftGyroscopeCalibrationValue"},
{136, &IHidDebugServer::GetShiftGyroscopeCalibrationValue, "GetShiftGyroscopeCalibrationValue"},
{140, nullptr, "SetSixAxisSensorMode"},
{140, nullptr, "DeactivateConsoleSixAxisSensor"},
{141, nullptr, "GetConsoleSixAxisSensorSamplingFrequency"},
{142, nullptr, "DeactivateSevenSixAxisSensor"},
{143, nullptr, "GetConsoleSixAxisSensorCountStates"},
{144, nullptr, "GetAccelerometerFsr"},
{145, nullptr, "SetAccelerometerFsr"},
{146, nullptr, "GetAccelerometerOdr"},
{147, nullptr, "SetAccelerometerOdr"},
{148, nullptr, "GetGyroscopeFsr"},
{149, nullptr, "SetGyroscopeFsr"},
{150, nullptr, "GetGyroscopeOdr"},
{151, nullptr, "SetGyroscopeOdr"},
{144, &IHidDebugServer::GetAccelerometerFsr, "GetAccelerometerFsr"},
{145, &IHidDebugServer::SetAccelerometerFsr, "SetAccelerometerFsr"},
{146, &IHidDebugServer::GetAccelerometerOdr, "GetAccelerometerOdr"},
{147, &IHidDebugServer::SetAccelerometerOdr, "SetAccelerometerOdr"},
{148, &IHidDebugServer::GetGyroscopeFsr, "GetGyroscopeFsr"},
{149, &IHidDebugServer::SetGyroscopeFsr, "SetGyroscopeFsr"},
{150, &IHidDebugServer::GetGyroscopeOdr, "GetGyroscopeOdr"},
{151, &IHidDebugServer::SetGyroscopeOdr, "SetGyroscopeOdr"},
{152, nullptr, "GetWhoAmI"},
{201, nullptr, "ActivateFirmwareUpdate"},
{202, nullptr, "DeactivateFirmwareUpdate"},
@ -140,6 +147,7 @@ IHidDebugServer::IHidDebugServer(Core::System& system_) : ServiceFramework{syste
{2001, nullptr, "SetDigitizerAutoPilotState"},
{2002, nullptr, "UnsetDigitizerAutoPilotState"},
{2002, nullptr, "ReloadFirmwareDebugSettings"},
{3000, nullptr, "ReloadFirmwareDebugSettings"},
};
// clang-format on
@ -148,4 +156,156 @@ IHidDebugServer::IHidDebugServer(Core::System& system_) : ServiceFramework{syste
IHidDebugServer::~IHidDebugServer() = default;
void IHidDebugServer::SetShiftAccelerometerCalibrationValue(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
SixAxisSensorHandle sixaxis_handle;
SixAxisSensorShiftAccelerometerCalibration accelerometer_calibration;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_DEBUG(Service_HID,
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
Result result = ResultSuccess;
std::array<u64, ARUID_MAX> aruid_list{};
std::shared_ptr<SixAxisSensorState> state = nullptr;
const auto sixaxis = GetResourceManager()->GetSixAxis();
sixaxis->GetAruidList(aruid_list);
for (const auto& aruid : aruid_list) {
result = sixaxis->GetSensorState(state, aruid, parameters.sixaxis_handle);
if (result.IsError()) {
break;
}
state->SetShiftAccelerometerCalibrationValue(parameters.accelerometer_calibration);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
}
void IHidDebugServer::GetShiftAccelerometerCalibrationValue(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
SixAxisSensorHandle sixaxis_handle;
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_DEBUG(Service_HID,
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
SixAxisSensorShiftAccelerometerCalibration accelerometer_calibration;
std::shared_ptr<SixAxisSensorState> state = nullptr;
const auto sixaxis = GetResourceManager()->GetSixAxis();
const auto result = sixaxis->GetSensorState(state, parameters.applet_resource_user_id,
parameters.sixaxis_handle);
if (result.IsSuccess()) {
accelerometer_calibration = state->GetShiftAccelerometerCalibrationValue();
}
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(result);
rb.PushRaw(accelerometer_calibration);
}
void IHidDebugServer::SetShiftGyroscopeCalibrationValue(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
SixAxisSensorHandle sixaxis_handle;
SixAxisSensorShiftGyroscopeCalibration gyroscope_calibration;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
static_assert(sizeof(Parameters) == 0x18, "Parameters has incorrect size.");
const auto parameters{rp.PopRaw<Parameters>()};
LOG_DEBUG(Service_HID,
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
Result result = ResultSuccess;
std::array<u64, ARUID_MAX> aruid_list{};
std::shared_ptr<SixAxisSensorState> state = nullptr;
const auto sixaxis = GetResourceManager()->GetSixAxis();
sixaxis->GetAruidList(aruid_list);
for (const auto& aruid : aruid_list) {
result = sixaxis->GetSensorState(state, aruid, parameters.sixaxis_handle);
if (result.IsError()) {
break;
}
state->SetShiftGyroscopeCalibrationValue(parameters.gyroscope_calibration);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
}
void IHidDebugServer::GetShiftGyroscopeCalibrationValue(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
SixAxisSensorHandle sixaxis_handle;
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_DEBUG(Service_HID,
"called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
SixAxisSensorShiftGyroscopeCalibration gyroscope_calibration;
std::shared_ptr<SixAxisSensorState> state = nullptr;
const auto sixaxis = GetResourceManager()->GetSixAxis();
const auto result = sixaxis->GetSensorState(state, parameters.applet_resource_user_id,
parameters.sixaxis_handle);
if (result.IsSuccess()) {
gyroscope_calibration = state->GetShiftGyroscopeCalibrationValue();
}
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(result);
rb.PushRaw(gyroscope_calibration);
}
void IHidDebugServer::GetAccelerometerFsr(HLERequestContext& ctx) {}
void IHidDebugServer::SetAccelerometerFsr(HLERequestContext& ctx) {}
void IHidDebugServer::GetAccelerometerOdr(HLERequestContext& ctx) {}
void IHidDebugServer::SetAccelerometerOdr(HLERequestContext& ctx) {}
void IHidDebugServer::GetGyroscopeFsr(HLERequestContext& ctx) {}
void IHidDebugServer::SetGyroscopeFsr(HLERequestContext& ctx) {}
void IHidDebugServer::GetGyroscopeOdr(HLERequestContext& ctx) {}
void IHidDebugServer::SetGyroscopeOdr(HLERequestContext& ctx) {}
std::shared_ptr<ResourceManager> IHidDebugServer::GetResourceManager() {
if (!is_resource_manager_initialized) {
resource_manager->Initialize();
is_resource_manager_initialized = true;
}
return resource_manager;
}
} // namespace Service::HID

View File

@ -10,11 +10,33 @@ class System;
}
namespace Service::HID {
class ResourceManager;
class IHidDebugServer final : public ServiceFramework<IHidDebugServer> {
public:
explicit IHidDebugServer(Core::System& system_);
explicit IHidDebugServer(Core::System& system_, std::shared_ptr<ResourceManager> resource);
~IHidDebugServer() override;
private:
// Service calls
void SetShiftAccelerometerCalibrationValue(HLERequestContext& ctx);
void GetShiftAccelerometerCalibrationValue(HLERequestContext& ctx);
void SetShiftGyroscopeCalibrationValue(HLERequestContext& ctx);
void GetShiftGyroscopeCalibrationValue(HLERequestContext& ctx);
void GetAccelerometerFsr(HLERequestContext& ctx);
void SetAccelerometerFsr(HLERequestContext& ctx);
void GetAccelerometerOdr(HLERequestContext& ctx);
void SetAccelerometerOdr(HLERequestContext& ctx);
void GetGyroscopeFsr(HLERequestContext& ctx);
void SetGyroscopeFsr(HLERequestContext& ctx);
void GetGyroscopeOdr(HLERequestContext& ctx);
void SetGyroscopeOdr(HLERequestContext& ctx);
std::shared_ptr<ResourceManager> GetResourceManager();
bool is_resource_manager_initialized{};
std::shared_ptr<ResourceManager> resource_manager = nullptr;
};
} // namespace Service::HID

File diff suppressed because it is too large Load Diff

View File

@ -10,11 +10,92 @@ class System;
}
namespace Service::HID {
class ResourceManager;
class IAppletResource final : public ServiceFramework<IAppletResource> {
public:
explicit IAppletResource(Core::System& system_);
~IAppletResource() override;
private:
void GetSharedMemoryHandle(HLERequestContext& ctx);
};
class IHidServer final : public ServiceFramework<IHidServer> {
public:
explicit IHidServer(Core::System& system_);
explicit IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> resource);
~IHidServer() override;
private:
// Service calls
void CreateAppletResource(HLERequestContext& ctx);
void ActivateDebugPad(HLERequestContext& ctx);
void ActivateTouchScreen(HLERequestContext& ctx);
void ActivateMouse(HLERequestContext& ctx);
void ActivateKeyboard(HLERequestContext& ctx);
void AcquireXpadIdEventHandle(HLERequestContext& ctx);
void ReleaseXpadIdEventHandle(HLERequestContext& ctx);
void ActivateXpad(HLERequestContext& ctx);
void GetXpadIds(HLERequestContext& ctx);
void ActivateJoyXpad(HLERequestContext& ctx);
void GetJoyXpadLifoHandle(HLERequestContext& ctx);
void GetJoyXpadIds(HLERequestContext& ctx);
void ActivateSixAxisSensor(HLERequestContext& ctx);
void DeactivateSixAxisSensor(HLERequestContext& ctx);
void GetSixAxisSensorLifoHandle(HLERequestContext& ctx);
void ActivateJoySixAxisSensor(HLERequestContext& ctx);
void DeactivateJoySixAxisSensor(HLERequestContext& ctx);
void GetJoySixAxisSensorLifoHandle(HLERequestContext& ctx);
void StartSixAxisSensor(HLERequestContext& ctx);
void StopSixAxisSensor(HLERequestContext& ctx);
void IsSixAxisSensorFusionEnabled(HLERequestContext& ctx);
void EnableSixAxisSensorFusion(HLERequestContext& ctx);
void SetSixAxisSensorFusionParameters(HLERequestContext& ctx);
void GetSixAxisSensorFusionParameters(HLERequestContext& ctx);
void ResetSixAxisSensorFusionParameters(HLERequestContext& ctx);
void SetAccelerometerParameters(HLERequestContext& ctx);
void GetAccelerometerParameters(HLERequestContext& ctx);
void ResetAccelerometerParameters(HLERequestContext& ctx);
void SetAccelerometerPlayMode(HLERequestContext& ctx);
void GetAccelerometerPlayMode(HLERequestContext& ctx);
void ResetAccelerometerPlayMode(HLERequestContext& ctx);
void SetGyroscopeZeroDriftMode(HLERequestContext& ctx);
void GetGyroscopeZeroDriftMode(HLERequestContext& ctx);
void ResetGyroscopeZeroDriftMode(HLERequestContext& ctx);
void IsSixAxisSensorAtRest(HLERequestContext& ctx);
void IsFirmwareUpdateAvailableForSixAxisSensor(HLERequestContext& ctx);
void EnableSixAxisSensorUnalteredPassthrough(HLERequestContext& ctx);
void IsSixAxisSensorUnalteredPassthroughEnabled(HLERequestContext& ctx);
void StoreSixAxisSensorCalibrationParameter(HLERequestContext& ctx);
void LoadSixAxisSensorCalibrationParameter(HLERequestContext& ctx);
void GetSixAxisSensorIcInformation(HLERequestContext& ctx);
void ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx);
bool IsDeviceManaged();
void InitializeDebugSettings();
std::shared_ptr<ResourceManager> GetResourceManager();
// Server state
bool is_debug_settings_initalized{};
bool is_resource_manager_initialized{};
// Debug settings
bool is_debugpad_enabled{};
bool is_device_managed{};
bool is_touch_i2c_managed{};
bool is_future_devices_emulated{};
bool is_mcu_hardware_error_emulated{};
bool is_rail_enabled{};
bool is_firmware_update_failure_emulated{};
std::array<u8, 4> is_firmware_update_failure{};
bool is_ble_disabled{};
bool is_dscale_disabled{};
bool is_handheld_forced{};
std::array<bool, 0xA8> is_features_per_id_disabled{};
bool is_touch_firmware_auto_update_disabled{};
std::shared_ptr<ResourceManager> resource_manager = nullptr;
std::shared_ptr<IAppletResource> applet_resource = nullptr;
};
} // namespace Service::HID

View File

@ -0,0 +1,37 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/am/applets/applets.h"
#include "core/hle/service/hid/hid_server/base_resource.h"
namespace Service::HID {
// TODO: Get the actual aruid to index table
static constexpr std::array<std::pair<u64, std::size_t>, ARUID_MAX> aruid_list{
std::pair<u64, std::size_t>{0, 0}, // Default
{135, 1}, // HID
};
BaseResource::BaseResource() {}
BaseResource::~BaseResource() = default;
std::size_t BaseResource::GetIndexFromAruid(const u64 aruid) const {
for (const auto& [applet_id, index] : aruid_list) {
if (applet_id == aruid) {
return index;
}
}
return ARUID_MAX;
}
void BaseResource::GetAruidList(std::span<u64> list) const {
const std::size_t list_size = std::min(aruid_list.size(), ARUID_MAX);
for (std::size_t index = 0; index < list_size; ++index) {
list[index] = aruid_list[index].first;
}
}
} // namespace Service::HID

View File

@ -0,0 +1,21 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/hid/resource_manager.h"
namespace Service::HID {
constexpr std::size_t ARUID_MAX = 0x20;
constexpr std::size_t PLAYERS_MAX = 10;
class BaseResource {
public:
explicit BaseResource();
~BaseResource();
std::size_t GetIndexFromAruid(const u64 aruid) const;
void GetAruidList(std::span<u64> list) const;
};
} // namespace Service::HID

View File

@ -19,6 +19,9 @@ constexpr Result NpadIsSameType{ErrorModule::HID, 602};
constexpr Result InvalidNpadId{ErrorModule::HID, 709};
constexpr Result NpadNotConnected{ErrorModule::HID, 710};
constexpr Result InvalidArraySize{ErrorModule::HID, 715};
constexpr Result ResultUnknown108{ErrorModule::HID, 108};
constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302};
} // namespace Service::HID

View File

@ -223,7 +223,7 @@ enum class NpadIdType : u32 {
// This is nn::hid::NpadStyleIndex
enum class NpadStyleIndex : u8 {
None = 0,
ProController = 3,
FullKey = 3,
Handheld = 4,
HandheldNES = 4,
JoyconDual = 5,
@ -284,6 +284,12 @@ enum class VibrationGcErmCommand : u64 {
StopHard = 2,
};
// This is nn::hid::debug::AccelerometerPlayMode
enum class AccelerometerPlayMode : u32 {
Loose = 0,
Tight = 1,
};
// This is nn::hid::GyroscopeZeroDriftMode
enum class GyroscopeZeroDriftMode : u32 {
Loose = 0,
@ -510,12 +516,37 @@ static_assert(sizeof(SixAxisSensorHandle) == 4, "SixAxisSensorHandle is an inval
// These parameters seem related to how much gyro/accelerometer is used
struct SixAxisSensorFusionParameters {
f32 parameter1{0.03f}; // Range 0.0 to 1.0, default 0.03
f32 parameter2{0.4f}; // Default 0.4
f32 parameter1{};
f32 parameter2{};
};
static_assert(sizeof(SixAxisSensorFusionParameters) == 8,
"SixAxisSensorFusionParameters is an invalid size");
// These parameters seem related to how much gyro/accelerometer is used
struct SixAxisSensorShiftAccelerometerCalibration {
f32 calibration1{};
f32 calibration2{};
};
static_assert(sizeof(SixAxisSensorShiftAccelerometerCalibration) == 8,
"SixAxisSensorShiftAccelerometerCalibration is an invalid size");
// These parameters seem related to how much gyro/accelerometer is used
struct SixAxisSensorShiftGyroscopeCalibration {
f32 calibration1{};
f32 calibration2{};
};
static_assert(sizeof(SixAxisSensorShiftGyroscopeCalibration) ==
8,
"SixAxisSensorShiftGyroscopeCalibration is an invalid size");
// These parameters seem related to how much gyro/accelerometer is used
struct SixAxisAccelerometerParameters {
f32 parameter1{};
f32 parameter2{};
};
static_assert(sizeof(SixAxisAccelerometerParameters) == 8,
"SixAxisSensorFusionParameters is an invalid size");
// This is nn::hid::server::SixAxisSensorProperties
struct SixAxisSensorProperties {
union {
@ -664,60 +695,4 @@ struct MouseState {
};
static_assert(sizeof(MouseState) == 0x28, "MouseState is an invalid size");
/// Converts a NpadIdType to an array index.
constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) {
switch (npad_id_type) {
case NpadIdType::Player1:
return 0;
case NpadIdType::Player2:
return 1;
case NpadIdType::Player3:
return 2;
case NpadIdType::Player4:
return 3;
case NpadIdType::Player5:
return 4;
case NpadIdType::Player6:
return 5;
case NpadIdType::Player7:
return 6;
case NpadIdType::Player8:
return 7;
case NpadIdType::Handheld:
return 8;
case NpadIdType::Other:
return 9;
default:
return 0;
}
}
/// Converts an array index to a NpadIdType
constexpr NpadIdType IndexToNpadIdType(size_t index) {
switch (index) {
case 0:
return NpadIdType::Player1;
case 1:
return NpadIdType::Player2;
case 2:
return NpadIdType::Player3;
case 3:
return NpadIdType::Player4;
case 4:
return NpadIdType::Player5;
case 5:
return NpadIdType::Player6;
case 6:
return NpadIdType::Player7;
case 7:
return NpadIdType::Player8;
case 8:
return NpadIdType::Handheld;
case 9:
return NpadIdType::Other;
default:
return NpadIdType::Invalid;
}
}
} // namespace Service::HID

View File

@ -0,0 +1,84 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/hid/hid_server/hid_types.h"
namespace Service::HID {
constexpr bool IsNpadIdValid(const NpadIdType npad_id) {
switch (npad_id) {
case NpadIdType::Player1:
case NpadIdType::Player2:
case NpadIdType::Player3:
case NpadIdType::Player4:
case NpadIdType::Player5:
case NpadIdType::Player6:
case NpadIdType::Player7:
case NpadIdType::Player8:
case NpadIdType::Other:
case NpadIdType::Handheld:
return true;
default:
return false;
}
}
/// Converts a NpadIdType to an array index.
constexpr size_t NpadIdTypeToIndex(NpadIdType npad_id_type) {
switch (npad_id_type) {
case NpadIdType::Player1:
return 0;
case NpadIdType::Player2:
return 1;
case NpadIdType::Player3:
return 2;
case NpadIdType::Player4:
return 3;
case NpadIdType::Player5:
return 4;
case NpadIdType::Player6:
return 5;
case NpadIdType::Player7:
return 6;
case NpadIdType::Player8:
return 7;
case NpadIdType::Handheld:
return 8;
case NpadIdType::Other:
return 9;
default:
return 0;
}
}
/// Converts an array index to a NpadIdType
constexpr NpadIdType IndexToNpadIdType(size_t index) {
switch (index) {
case 0:
return NpadIdType::Player1;
case 1:
return NpadIdType::Player2;
case 2:
return NpadIdType::Player3;
case 3:
return NpadIdType::Player4;
case 4:
return NpadIdType::Player5;
case 5:
return NpadIdType::Player6;
case 6:
return NpadIdType::Player7;
case 7:
return NpadIdType::Player8;
case 8:
return NpadIdType::Handheld;
case 9:
return NpadIdType::Other;
default:
return NpadIdType::Invalid;
}
}
} // namespace Service::HID

View File

@ -0,0 +1,14 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/hid/hid_server/hid_types.h"
#include "core/hle/service/hid/hid_server/hid_util.h"
#include "core/hle/service/hid/hid_server/npad.h"
namespace Service::HID {
Npad::Npad() {}
Npad::~Npad() = default;
} // namespace Service::HID

View File

@ -0,0 +1,29 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <array>
#include "core/hle/service/hid/hid_server/base_resource.h"
namespace Core {
class System;
}
namespace Service::HID {
} // namespace Service::HID
namespace Service::HID {
class Npad final : public BaseResource {
public:
explicit Npad();
~Npad();
bool IsFirmwareUpdateAvailableForSixAxisSensor(const SixAxisSensorHandle& handle);
private:
};
} // namespace Service::HID

View File

@ -0,0 +1,189 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/hid/hid_server/hid_types.h"
#include "core/hle/service/hid/hid_server/hid_util.h"
#include "core/hle/service/hid/hid_server/sixaxis.h"
namespace Service::HID {
SixAxis::SixAxis() {}
SixAxis::~SixAxis() = default;
Result SixAxis::GetSensorState(std::shared_ptr<SixAxisSensorState>& out_state, u64 aruid,
const SixAxisSensorHandle& handle) {
const auto state = GetStateFromAruid(aruid);
if (state == nullptr) {
return ResultUnknown;
}
out_state = state->GetSensorState(handle);
return ResultSuccess;
}
std::shared_ptr<SixAxisState> SixAxis::GetStateFromAruid(const u64 aruid) const {
const auto index = GetIndexFromAruid(aruid);
if (index >= ARUID_MAX) {
return nullptr;
}
return sixaxis_state[index];
}
SixAxisState::SixAxisState() {}
SixAxisState::~SixAxisState() = default;
std::shared_ptr<SixAxisSensorState> SixAxisState::GetSensorState(
const SixAxisSensorHandle& handle) const {
const auto npad_id = static_cast<NpadIdType>(handle.npad_id);
// This should crash console
ASSERT_MSG(IsNpadIdValid(npad_id), "ResultInvalidNpadId {}", npad_id);
const auto& player_state = state[NpadIdTypeToIndex(npad_id)];
switch (handle.npad_type) {
case NpadStyleIndex::FullKey:
return player_state.fullkey_state;
case NpadStyleIndex::Handheld:
return player_state.handheld_state;
case NpadStyleIndex::JoyconDual:
if (handle.device_index == DeviceIndex::Right) {
return player_state.dual_left_state;
}
if (handle.device_index == DeviceIndex::Left) {
return player_state.dual_left_state;
}
// This should crash console
ASSERT_MSG("Invalid device index");
return nullptr;
case NpadStyleIndex::JoyconLeft:
return player_state.left_state;
case NpadStyleIndex::JoyconRight:
return player_state.right_state;
default:
return player_state.unknown_state;
}
}
SixAxisSensorState::SixAxisSensorState() {
ResetFusionParameters();
ResetAccelerometerParameters();
ResetAccelerometerPlayMode();
ResetGyroscopeZeroDriftMode();
}
SixAxisSensorState::~SixAxisSensorState() = default;
void SixAxisSensorState::SetRunningState(const bool state) {
is_running = state;
}
void SixAxisSensorState::SetUnalteredPassthrough(const bool is_enabled) {
is_passthrough_enabled = is_enabled;
}
bool SixAxisSensorState::GetUnalteredPassthrough() {
return is_passthrough_enabled;
}
bool SixAxisSensorState::IsFusionEnabled() const {
return is_fusion_enabled;
}
void SixAxisSensorState::ResetFusionParameters() {
is_fusion_enabled = true;
fusion_parameter_1 = 0.03f;
fusion_parameter_2 = 0.4f;
}
void SixAxisSensorState::SetFusionState(const bool is_enabled) {
is_fusion_enabled = is_enabled;
}
void SixAxisSensorState::SetFusionParameters(const SixAxisSensorFusionParameters& parameters) {
fusion_parameter_1 = parameters.parameter1;
fusion_parameter_2 = parameters.parameter2;
}
SixAxisSensorFusionParameters SixAxisSensorState::GetFusionParameters() const {
return {
.parameter1 = fusion_parameter_1,
.parameter2 = fusion_parameter_2,
};
}
void SixAxisSensorState::ResetAccelerometerParameters() {
accelerometer_parameter_1 = 0.0f;
accelerometer_parameter_2 = 1.0f;
}
void SixAxisSensorState::SetAccelerometerParameters(
const SixAxisAccelerometerParameters& parameters) {
accelerometer_parameter_1 = parameters.parameter1;
accelerometer_parameter_2 = parameters.parameter2;
}
SixAxisAccelerometerParameters SixAxisSensorState::GetAccelerometerParameters() const {
return {
.parameter1 = accelerometer_parameter_1,
.parameter2 = accelerometer_parameter_2,
};
}
void SixAxisSensorState::SetShiftAccelerometerCalibrationValue(
const SixAxisSensorShiftAccelerometerCalibration& calibration) {
shift_accelerometer_calibration_1 = calibration.calibration1;
shift_accelerometer_calibration_2 = calibration.calibration1;
}
SixAxisSensorShiftAccelerometerCalibration
SixAxisSensorState::GetShiftAccelerometerCalibrationValue() const {
return {
.calibration1 = shift_accelerometer_calibration_1,
.calibration2 = shift_accelerometer_calibration_2,
};
}
void SixAxisSensorState::ResetAccelerometerPlayMode() {
play_mode = AccelerometerPlayMode::Tight;
}
void SixAxisSensorState::SetAccelerometerPlayMode(const AccelerometerPlayMode mode) {
play_mode = mode;
}
AccelerometerPlayMode SixAxisSensorState::GetAccelerometerPlayMode() const {
return play_mode;
}
void SixAxisSensorState::ResetGyroscopeZeroDriftMode() {
zero_drift_mode = GyroscopeZeroDriftMode::Standard;
}
void SixAxisSensorState::SetGyroscopeZeroDriftMode(const GyroscopeZeroDriftMode mode) {
zero_drift_mode = mode;
}
GyroscopeZeroDriftMode SixAxisSensorState::GetGyroscopeZeroDriftMode() const {
return zero_drift_mode;
}
void SixAxisSensorState::SetShiftGyroscopeCalibrationValue(
const SixAxisSensorShiftGyroscopeCalibration& calibration) {
shift_gyroscope_calibration_1 = calibration.calibration1;
shift_gyroscope_calibration_2 = calibration.calibration1;
}
SixAxisSensorShiftGyroscopeCalibration SixAxisSensorState::GetShiftGyroscopeCalibrationValue()
const {
return {
.calibration1 = shift_gyroscope_calibration_1,
.calibration2 = shift_gyroscope_calibration_2,
};
}
} // namespace Service::HID

View File

@ -0,0 +1,120 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <array>
#include "core/hle/service/hid/hid_server/base_resource.h"
namespace Core {
class System;
}
namespace Service::HID {
enum class AccelerometerPlayMode : u32;
enum class GyroscopeZeroDriftMode : u32;
struct SixAxisAccelerometerParameters;
struct SixAxisSensorFusionParameters;
struct SixAxisSensorHandle;
} // namespace Service::HID
namespace Service::HID {
class SixAxisSensorState {
public:
explicit SixAxisSensorState();
~SixAxisSensorState();
void SetRunningState(const bool state);
void SetUnalteredPassthrough(const bool is_enabled);
bool GetUnalteredPassthrough();
// Sensor fusion
bool IsFusionEnabled() const;
void ResetFusionParameters();
void SetFusionState(const bool is_enabled);
void SetFusionParameters(const SixAxisSensorFusionParameters& parameters);
SixAxisSensorFusionParameters GetFusionParameters() const;
// Accelerometer
void ResetAccelerometerParameters();
void SetAccelerometerParameters(const SixAxisAccelerometerParameters& parameters);
SixAxisAccelerometerParameters GetAccelerometerParameters() const;
void SetShiftAccelerometerCalibrationValue(
const SixAxisSensorShiftAccelerometerCalibration& calibration);
SixAxisSensorShiftAccelerometerCalibration GetShiftAccelerometerCalibrationValue() const;
void ResetAccelerometerPlayMode();
void SetAccelerometerPlayMode(const AccelerometerPlayMode mode);
AccelerometerPlayMode GetAccelerometerPlayMode() const;
// Gyroscope
void ResetGyroscopeZeroDriftMode();
void SetGyroscopeZeroDriftMode(const GyroscopeZeroDriftMode mode);
GyroscopeZeroDriftMode GetGyroscopeZeroDriftMode() const;
void SetShiftGyroscopeCalibrationValue(
const SixAxisSensorShiftGyroscopeCalibration& calibration);
SixAxisSensorShiftGyroscopeCalibration GetShiftGyroscopeCalibrationValue() const;
private:
bool is_running{};
bool is_passthrough_enabled{};
// Sensor fusion
bool is_fusion_enabled{};
float fusion_parameter_1{};
float fusion_parameter_2{};
// Accelerometer
float accelerometer_parameter_1{};
float accelerometer_parameter_2{};
float shift_accelerometer_calibration_1{};
float shift_accelerometer_calibration_2{};
AccelerometerPlayMode play_mode{};
// Gyroscope
float shift_gyroscope_calibration_1{};
float shift_gyroscope_calibration_2{};
GyroscopeZeroDriftMode zero_drift_mode{};
};
class SixAxisState {
public:
explicit SixAxisState();
~SixAxisState();
std::shared_ptr<SixAxisSensorState> GetSensorState(const SixAxisSensorHandle& handle) const;
private:
struct PlayerState {
std::shared_ptr<SixAxisSensorState> fullkey_state = nullptr;
std::shared_ptr<SixAxisSensorState> handheld_state = nullptr;
std::shared_ptr<SixAxisSensorState> dual_left_state = nullptr;
std::shared_ptr<SixAxisSensorState> dual_right_state = nullptr;
std::shared_ptr<SixAxisSensorState> left_state = nullptr;
std::shared_ptr<SixAxisSensorState> right_state = nullptr;
std::shared_ptr<SixAxisSensorState> unknown_state = nullptr;
};
std::array<PlayerState, PLAYERS_MAX> state;
};
class SixAxis final : public BaseResource {
public:
explicit SixAxis();
~SixAxis();
Result GetSensorState(std::shared_ptr<SixAxisSensorState>& out_state, const u64 aruid,
const SixAxisSensorHandle& handle);
private:
std::shared_ptr<SixAxisState> GetStateFromAruid(const u64 aruid) const;
std::array<std::shared_ptr<SixAxisState>, ARUID_MAX> sixaxis_state{};
};
} // namespace Service::HID

View File

@ -1,14 +1,16 @@
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/hid/hid_system_server.h"
#include "core/hle/service/hid/resource_manager.h"
namespace Service::HID {
IHidSystemServer::IHidSystemServer(Core::System& system_) : ServiceFramework{system_, "hid:sys"} {
IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<ResourceManager> resource)
: ServiceFramework{system_, "hid:sys"}, resource_manger{resource} {
// clang-format off
static const FunctionInfo functions[] = {
{31, nullptr, "SendKeyboardLockKeyEvent"},
{31, nullptr, "SendKeyboardLockKeyEvent"},
{101, nullptr, "AcquireHomeButtonEventHandle"},
{111, nullptr, "ActivateHomeButton"},
{121, nullptr, "AcquireSleepButtonEventHandle"},

View File

@ -10,11 +10,15 @@ class System;
}
namespace Service::HID {
class ResourceManager;
class IHidSystemServer final : public ServiceFramework<IHidSystemServer> {
public:
explicit IHidSystemServer(Core::System& system_);
explicit IHidSystemServer(Core::System& system_, std::shared_ptr<ResourceManager> resource);
~IHidSystemServer() override;
private:
std::shared_ptr<ResourceManager> resource_manger = nullptr;
};
} // namespace Service::HID

View File

@ -0,0 +1,119 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/hid/hid_server/hid_types.h"
#include "core/hle/service/hid/hid_server/hid_util.h"
#include "core/hle/service/hid/resource_manager.h"
namespace Service::HID {
DebugPad::DebugPad() {}
DebugPad::~DebugPad() = default;
Result DebugPad::Activate() {
return ResultSuccess;
}
Result DebugPad::Activate(u64 aruid) {
return ResultSuccess;
}
NpadSharedMemory::NpadSharedMemory() {}
bool NpadSharedMemory::IsAtRest() const {
return false;
}
SharedMemory::SharedMemory() {}
std::shared_ptr<NpadSharedMemory> SharedMemory::GetNpadSharedMemory(
SixAxisSensorHandle handle) const {
// TODO: THIS REE IS BROKEN
const auto npad_id = static_cast<NpadIdType>(handle.npad_id);
// This should crash console
ASSERT_MSG(IsNpadIdValid(npad_id), "ResultInvalidNpadId {}", npad_id);
const auto& player_memory = npad_shared_memory[NpadIdTypeToIndex(npad_id)];
DeviceIndex device_index = handle.device_index;
NpadStyleIndex style_index = handle.npad_type;
if (style_index == NpadStyleIndex::Handheld) {
u8 unknown_value_1 = 0;
u8 unknown_value_2 = 0;
u8 shared_mem_value = 0;
u8 unknown_data = 0;
if (unknown_value_1 == 2 && shared_mem_value == 2 || (unknown_value_2 >> 3 & 1) != 0) {
switch (npad_id) {
case NpadIdType::Player1:
case NpadIdType::Player2:
case NpadIdType::Player3:
case NpadIdType::Player4:
case NpadIdType::Player5:
case NpadIdType::Player6:
case NpadIdType::Player7:
unknown_data = 0;
break;
case NpadIdType::Other:
unknown_data = 0;
break;
case NpadIdType::Handheld:
unknown_data = 0;
break;
default:
// This should crash console
ASSERT_MSG("Invalid npad id");
break;
}
if (unknown_data != 0) {
return {};
}
}
} else if (style_index == NpadStyleIndex::FullKey) {
device_index = {};
}
return player_memory;
}
ResourceManager::ResourceManager(Core::System& system_) {}
ResourceManager::~ResourceManager() = default;
void ResourceManager::Initialize() {}
std::shared_ptr<DebugPad> ResourceManager::GetDebugPad() {
return debug_pad;
}
std::shared_ptr<DebugPad> ResourceManager::GetTouchScreen() {
return debug_pad;
}
std::shared_ptr<DebugPad> ResourceManager::GetMouse() {
return debug_pad;
}
std::shared_ptr<DebugPad> ResourceManager::GetKeyboard() {
return debug_pad;
}
std::shared_ptr<SixAxis> ResourceManager::GetSixAxis() {
return sixaxis;
}
std::shared_ptr<Npad> ResourceManager::GetNpad() {
return npad;
}
std::shared_ptr<NpadSharedMemory> ResourceManager::GetNpadSharedMemory(
SixAxisSensorHandle handle) const {
return shared_memory.GetNpadSharedMemory(handle);
}
} // namespace Service::HID

View File

@ -0,0 +1,68 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Service::HID {
struct SixAxisSensorHandle;
class SixAxis;
class Npad;
} // namespace Service::HID
namespace Service::HID {
class DebugPad {
public:
explicit DebugPad();
~DebugPad();
Result Activate();
Result Activate(u64 aruid);
};
class NpadSharedMemory {
public:
explicit NpadSharedMemory();
bool IsAtRest() const;
};
class SharedMemory {
public:
explicit SharedMemory();
std::shared_ptr<NpadSharedMemory> GetNpadSharedMemory(SixAxisSensorHandle handle) const;
private:
static constexpr std::size_t PLAYERS_MAX = 10;
std::array<std::shared_ptr<NpadSharedMemory>, PLAYERS_MAX> npad_shared_memory{};
};
class ResourceManager {
public:
explicit ResourceManager(Core::System& system_);
~ResourceManager();
void Initialize();
std::shared_ptr<DebugPad> GetDebugPad();
std::shared_ptr<DebugPad> GetTouchScreen();
std::shared_ptr<DebugPad> GetMouse();
std::shared_ptr<DebugPad> GetKeyboard();
std::shared_ptr<SixAxis> GetSixAxis();
std::shared_ptr<Npad> GetNpad();
std::shared_ptr<NpadSharedMemory> GetNpadSharedMemory(SixAxisSensorHandle handle) const;
std::shared_ptr<SixAxis> sixaxis = nullptr;
std::shared_ptr<Npad> npad = nullptr;
std::shared_ptr<DebugPad> debug_pad = nullptr;
SharedMemory shared_memory{};
};
} // namespace Service::HID

View File

@ -13,6 +13,7 @@
#include "core/hle/service/nfc/nfc_result.h"
#include "core/hle/service/time/clock_types.h"
#include "core/hle/service/time/time_manager.h"
#include "core/hle/service/hid/hid_server/hid_util.h"
namespace Service::NFC {

View File

@ -37,7 +37,7 @@ namespace {
bool IsControllerCompatible(Service::HID::NpadStyleIndex controller_type,
Core::Frontend::ControllerParameters parameters) {
switch (controller_type) {
case Service::HID::NpadStyleIndex::ProController:
case Service::HID::NpadStyleIndex::FullKey:
return parameters.allow_pro_controller;
case Service::HID::NpadStyleIndex::JoyconDual:
return parameters.allow_dual_joycons;
@ -466,7 +466,7 @@ Service::HID::NpadStyleIndex QtControllerSelectorDialog::GetControllerTypeFromIn
[index](const auto& pair) { return pair.first == index; });
if (it == pairs.end()) {
return Service::HID::NpadStyleIndex::ProController;
return Service::HID::NpadStyleIndex::FullKey;
}
return it->second;
@ -496,7 +496,7 @@ void QtControllerSelectorDialog::UpdateControllerIcon(std::size_t player_index)
const QString stylesheet = [this, player_index] {
switch (GetControllerTypeFromIndex(emulated_controllers[player_index]->currentIndex(),
player_index)) {
case Service::HID::NpadStyleIndex::ProController:
case Service::HID::NpadStyleIndex::FullKey:
case Service::HID::NpadStyleIndex::GameCube:
return QStringLiteral("image: url(:/controller/applet_pro_controller%0); ");
case Service::HID::NpadStyleIndex::JoyconDual: