2
1
Fork 0
mirror of https://github.com/yuzu-emu/yuzu.git synced 2024-07-04 23:31:19 +01:00

service: hid: Introduce firmware settings and update activate controller calls

This commit is contained in:
Narr the Reg 2023-11-16 17:58:05 -06:00
parent b9c7e5c2c8
commit 862e66202c
12 changed files with 295 additions and 54 deletions

View file

@ -523,6 +523,8 @@ add_library(core STATIC
hle/service/hid/hid.h
hle/service/hid/hid_debug_server.cpp
hle/service/hid/hid_debug_server.h
hle/service/hid/hid_firmware_settings.cpp
hle/service/hid/hid_firmware_settings.h
hle/service/hid/hid_server.cpp
hle/service/hid/hid_server.h
hle/service/hid/hid_system_server.cpp

View file

@ -8,12 +8,17 @@ namespace Service::HID {
ControllerBase::ControllerBase(Core::HID::HIDCore& hid_core_) : hid_core(hid_core_) {}
ControllerBase::~ControllerBase() = default;
void ControllerBase::ActivateController() {
Result ControllerBase::Activate() {
if (is_activated) {
return;
return ResultSuccess;
}
is_activated = true;
OnInit();
return ResultSuccess;
}
Result ControllerBase::Activate(u64 aruid) {
return Activate();
}
void ControllerBase::DeactivateController() {

View file

@ -4,6 +4,7 @@
#pragma once
#include "common/common_types.h"
#include "core/hle/result.h"
namespace Core::Timing {
class CoreTiming;
@ -31,7 +32,8 @@ public:
// When the controller is requesting a motion update for the shared memory
virtual void OnMotionUpdate(const Core::Timing::CoreTiming& core_timing) {}
void ActivateController();
Result Activate();
Result Activate(u64 aruid);
void DeactivateController();

View file

@ -86,6 +86,13 @@ public:
Default = 3,
};
enum class NpadRevision : u32 {
Revision0 = 0,
Revision1 = 1,
Revision2 = 2,
Revision3 = 3,
};
void SetSupportedStyleSet(Core::HID::NpadStyleTag style_set);
Core::HID::NpadStyleTag GetSupportedStyleSet() const;

View file

@ -44,7 +44,7 @@ Result Controller_Palma::InitializePalma(const PalmaConnectionHandle& handle) {
if (handle.npad_id != active_handle.npad_id) {
return InvalidPalmaHandle;
}
ActivateController();
Activate();
return ResultSuccess;
}

View file

@ -3,6 +3,7 @@
#include "core/hle/service/hid/hid.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_server.h"
#include "core/hle/service/hid/hid_system_server.h"
#include "core/hle/service/hid/hidbus.h"
@ -16,9 +17,11 @@ namespace Service::HID {
void LoopProcess(Core::System& system) {
auto server_manager = std::make_unique<ServerManager>(system);
std::shared_ptr<ResourceManager> resouce_manager = std::make_shared<ResourceManager>(system);
std::shared_ptr<HidFirmwareSettings> firmware_settings =
std::make_shared<HidFirmwareSettings>();
server_manager->RegisterNamedService("hid",
std::make_shared<IHidServer>(system, resouce_manager));
server_manager->RegisterNamedService(
"hid", std::make_shared<IHidServer>(system, resouce_manager, firmware_settings));
server_manager->RegisterNamedService(
"hid:dbg", std::make_shared<IHidDebugServer>(system, resouce_manager));
server_manager->RegisterNamedService(

View file

@ -0,0 +1,99 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include "core/hle/service/hid/hid_firmware_settings.h"
namespace Service::HID {
HidFirmwareSettings::HidFirmwareSettings() {
LoadSettings(true);
}
void HidFirmwareSettings::Reload() {
LoadSettings(true);
}
void HidFirmwareSettings::LoadSettings(bool reload_config) {
if (is_initalized && !reload_config) {
return;
}
// TODO: Use nn::settings::fwdbg::GetSettingsItemValue to load config values
is_debug_pad_enabled = true;
is_device_managed = true;
is_touch_i2c_managed = is_device_managed;
is_future_devices_emulated = false;
is_mcu_hardware_error_emulated = false;
is_rail_enabled = true;
is_firmware_update_failure_emulated = false;
is_firmware_update_failure = {};
is_ble_disabled = false;
is_dscale_disabled = false;
is_handheld_forced = true;
features_per_id_disabled = {};
is_touch_firmware_auto_update_disabled = false;
is_initalized = true;
}
bool HidFirmwareSettings::IsDebugPadEnabled() {
LoadSettings(false);
return is_debug_pad_enabled;
}
bool HidFirmwareSettings::IsDeviceManaged() {
LoadSettings(false);
return is_device_managed;
}
bool HidFirmwareSettings::IsEmulateFutureDevice() {
LoadSettings(false);
return is_future_devices_emulated;
}
bool HidFirmwareSettings::IsTouchI2cManaged() {
LoadSettings(false);
return is_touch_i2c_managed;
}
bool HidFirmwareSettings::IsHandheldForced() {
LoadSettings(false);
return is_handheld_forced;
}
bool HidFirmwareSettings::IsRailEnabled() {
LoadSettings(false);
return is_rail_enabled;
}
bool HidFirmwareSettings::IsHardwareErrorEmulated() {
LoadSettings(false);
return is_mcu_hardware_error_emulated;
}
bool HidFirmwareSettings::IsBleDisabled() {
LoadSettings(false);
return is_ble_disabled;
}
bool HidFirmwareSettings::IsDscaleDisabled() {
LoadSettings(false);
return is_dscale_disabled;
}
bool HidFirmwareSettings::IsTouchAutoUpdateDisabled() {
LoadSettings(false);
return is_touch_firmware_auto_update_disabled;
}
HidFirmwareSettings::FirmwareSetting HidFirmwareSettings::GetFirmwareUpdateFailure() {
LoadSettings(false);
return is_firmware_update_failure;
}
HidFirmwareSettings::FeaturesPerId HidFirmwareSettings::FeaturesDisabledPerId() {
LoadSettings(false);
return features_per_id_disabled;
}
} // namespace Service::HID

View file

@ -0,0 +1,54 @@
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include "common/common_types.h"
namespace Service::HID {
/// Loads firmware config from nn::settings::fwdbg
class HidFirmwareSettings {
public:
using FirmwareSetting = std::array<u8, 4>;
using FeaturesPerId = std::array<bool, 0xA8>;
HidFirmwareSettings();
void Reload();
void LoadSettings(bool reload_config);
bool IsDebugPadEnabled();
bool IsDeviceManaged();
bool IsEmulateFutureDevice();
bool IsTouchI2cManaged();
bool IsHandheldForced();
bool IsRailEnabled();
bool IsHardwareErrorEmulated();
bool IsBleDisabled();
bool IsDscaleDisabled();
bool IsTouchAutoUpdateDisabled();
FirmwareSetting GetFirmwareUpdateFailure();
FeaturesPerId FeaturesDisabledPerId();
private:
bool is_initalized{};
// Debug settings
bool is_debug_pad_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{};
bool is_ble_disabled{};
bool is_dscale_disabled{};
bool is_handheld_forced{};
bool is_touch_firmware_auto_update_disabled{};
FirmwareSetting is_firmware_update_failure{};
FeaturesPerId features_per_id_disabled{};
};
} // namespace Service::HID

View file

@ -10,6 +10,7 @@
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/service/hid/errors.h"
#include "core/hle/service/hid/hid_firmware_settings.h"
#include "core/hle/service/hid/hid_server.h"
#include "core/hle/service/hid/resource_manager.h"
#include "core/hle/service/ipc_helpers.h"
@ -64,8 +65,9 @@ private:
std::shared_ptr<ResourceManager> resource_manager;
};
IHidServer::IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> resource)
: ServiceFramework{system_, "hid"}, resource_manager{resource} {
IHidServer::IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> resource,
std::shared_ptr<HidFirmwareSettings> settings)
: ServiceFramework{system_, "hid"}, resource_manager{resource}, firmware_settings{settings} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IHidServer::CreateAppletResource, "CreateAppletResource"},
@ -230,48 +232,87 @@ void IHidServer::ActivateDebugPad(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
GetResourceManager()->ActivateController(HidController::DebugPad);
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
Result result = ResultSuccess;
auto& debug_pad =
GetResourceManager()->GetController<Controller_DebugPad>(HidController::DebugPad);
if (!firmware_settings->IsDeviceManaged()) {
result = debug_pad.Activate();
}
if (result.IsSuccess()) {
result = debug_pad.Activate(applet_resource_user_id);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
rb.Push(result);
}
void IHidServer::ActivateTouchScreen(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
GetResourceManager()->ActivateController(HidController::Touchscreen);
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
Result result = ResultSuccess;
auto& touch_screen =
GetResourceManager()->GetController<Controller_Touchscreen>(HidController::Touchscreen);
if (!firmware_settings->IsDeviceManaged()) {
result = touch_screen.Activate();
}
if (result.IsSuccess()) {
result = touch_screen.Activate(applet_resource_user_id);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
rb.Push(result);
}
void IHidServer::ActivateMouse(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
GetResourceManager()->ActivateController(HidController::Mouse);
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
Result result = ResultSuccess;
auto& mouse = GetResourceManager()->GetController<Controller_Mouse>(HidController::Mouse);
if (!firmware_settings->IsDeviceManaged()) {
result = mouse.Activate();
}
if (result.IsSuccess()) {
result = mouse.Activate(applet_resource_user_id);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
rb.Push(result);
}
void IHidServer::ActivateKeyboard(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
GetResourceManager()->ActivateController(HidController::Keyboard);
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
Result result = ResultSuccess;
auto& keyboard =
GetResourceManager()->GetController<Controller_Keyboard>(HidController::Keyboard);
if (!firmware_settings->IsDeviceManaged()) {
result = keyboard.Activate();
}
if (result.IsSuccess()) {
result = keyboard.Activate(applet_resource_user_id);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
rb.Push(result);
}
void IHidServer::SendKeyboardLockKeyEvent(HLERequestContext& ctx) {
@ -898,7 +939,7 @@ void IHidServer::ResetIsSixAxisSensorDeviceNewlyAssigned(HLERequestContext& ctx)
void IHidServer::ActivateGesture(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
struct Parameters {
u32 unknown;
u32 basic_gesture_id;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
@ -906,13 +947,23 @@ void IHidServer::ActivateGesture(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
GetResourceManager()->ActivateController(HidController::Gesture);
LOG_INFO(Service_HID, "called, basic_gesture_id={}, applet_resource_user_id={}",
parameters.basic_gesture_id, parameters.applet_resource_user_id);
LOG_WARNING(Service_HID, "(STUBBED) called, unknown={}, applet_resource_user_id={}",
parameters.unknown, parameters.applet_resource_user_id);
Result result = ResultSuccess;
auto& gesture = GetResourceManager()->GetController<Controller_Gesture>(HidController::Gesture);
if (!firmware_settings->IsDeviceManaged()) {
result = gesture.Activate();
}
if (result.IsSuccess()) {
// TODO: Use gesture id here
result = gesture.Activate(parameters.applet_resource_user_id);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
rb.Push(result);
}
void IHidServer::SetSupportedNpadStyleSet(HLERequestContext& ctx) {
@ -969,22 +1020,25 @@ void IHidServer::ActivateNpad(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
GetResourceManager()->ActivateController(HidController::NPad);
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
auto& npad = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
// TODO: npad->SetRevision(applet_resource_user_id, NpadRevision::Revision0);
const Result result = npad.Activate(applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
rb.Push(result);
}
void IHidServer::DeactivateNpad(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
GetResourceManager()->DeactivateController(HidController::NPad);
LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
// This function does nothing since 10.0.0+
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
@ -1053,10 +1107,9 @@ void IHidServer::GetPlayerLedPattern(HLERequestContext& ctx) {
}
void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {
// Should have no effect with how our npad sets up the data
IPC::RequestParser rp{ctx};
struct Parameters {
s32 revision;
Controller_NPad::NpadRevision revision;
INSERT_PADDING_WORDS_NOINIT(1);
u64 applet_resource_user_id;
};
@ -1064,13 +1117,16 @@ void IHidServer::ActivateNpadWithRevision(HLERequestContext& ctx) {
const auto parameters{rp.PopRaw<Parameters>()};
GetResourceManager()->ActivateController(HidController::NPad);
LOG_DEBUG(Service_HID, "called, revision={}, applet_resource_user_id={}", parameters.revision,
parameters.applet_resource_user_id);
auto& npad = GetResourceManager()->GetController<Controller_NPad>(HidController::NPad);
// TODO: npad->SetRevision(applet_resource_user_id, revision);
const auto result = npad.Activate(parameters.applet_resource_user_id);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
rb.Push(result);
}
void IHidServer::SetNpadJoyHoldType(HLERequestContext& ctx) {
@ -1718,12 +1774,22 @@ void IHidServer::ActivateConsoleSixAxisSensor(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
GetResourceManager()->ActivateController(HidController::ConsoleSixAxisSensor);
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
Result result = ResultSuccess;
auto console_sixaxis = GetResourceManager()->GetController<Controller_ConsoleSixAxis>(
HidController::ConsoleSixAxisSensor);
if (!firmware_settings->IsDeviceManaged()) {
result = console_sixaxis.Activate();
}
if (result.IsSuccess()) {
result = console_sixaxis.Activate(applet_resource_user_id);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
rb.Push(result);
}
void IHidServer::StartConsoleSixAxisSensor(HLERequestContext& ctx) {
@ -1770,9 +1836,19 @@ void IHidServer::ActivateSevenSixAxisSensor(HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto applet_resource_user_id{rp.Pop<u64>()};
GetResourceManager()->ActivateController(HidController::ConsoleSixAxisSensor);
LOG_INFO(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
LOG_WARNING(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
Result result = ResultSuccess;
auto console_sixaxis = GetResourceManager()->GetController<Controller_ConsoleSixAxis>(
HidController::ConsoleSixAxisSensor);
if (!firmware_settings->IsDeviceManaged()) {
result = console_sixaxis.Activate();
}
if (result.IsSuccess()) {
console_sixaxis.Activate(applet_resource_user_id);
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
@ -1837,7 +1913,7 @@ void IHidServer::InitializeSevenSixAxisSensor(HLERequestContext& ctx) {
// Activate console six axis controller
GetResourceManager()
->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)
.ActivateController();
.Activate();
GetResourceManager()
->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)

View file

@ -11,10 +11,12 @@ class System;
namespace Service::HID {
class ResourceManager;
class HidFirmwareSettings;
class IHidServer final : public ServiceFramework<IHidServer> {
public:
explicit IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> resource);
explicit IHidServer(Core::System& system_, std::shared_ptr<ResourceManager> resource,
std::shared_ptr<HidFirmwareSettings> settings);
~IHidServer() override;
std::shared_ptr<ResourceManager> GetResourceManager();
@ -141,6 +143,7 @@ private:
void IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx);
std::shared_ptr<ResourceManager> resource_manager;
std::shared_ptr<HidFirmwareSettings> firmware_settings;
};
} // namespace Service::HID

View file

@ -59,8 +59,8 @@ void ResourceManager::Initialize() {
MakeControllerWithServiceContext<Controller_Palma>(HidController::Palma, shared_memory);
// Homebrew doesn't try to activate some controllers, so we activate them by default
GetController<Controller_NPad>(HidController::NPad).ActivateController();
GetController<Controller_Touchscreen>(HidController::Touchscreen).ActivateController();
GetController<Controller_NPad>(HidController::NPad).Activate();
GetController<Controller_Touchscreen>(HidController::Touchscreen).Activate();
GetController<Controller_Stubbed>(HidController::HomeButton).SetCommonHeaderOffset(0x4C00);
GetController<Controller_Stubbed>(HidController::SleepButton).SetCommonHeaderOffset(0x4E00);
@ -73,14 +73,6 @@ void ResourceManager::Initialize() {
is_initialized = true;
}
void ResourceManager::ActivateController(HidController controller) {
controllers[static_cast<size_t>(controller)]->ActivateController();
}
void ResourceManager::DeactivateController(HidController controller) {
controllers[static_cast<size_t>(controller)]->DeactivateController();
}
void ResourceManager::UpdateControllers(std::uintptr_t user_data,
std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();

View file

@ -55,8 +55,6 @@ public:
}
void Initialize();
void ActivateController(HidController controller);
void DeactivateController(HidController controller);
void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);