From 862e66202c1e612f56dad9bb0d9403b4af502178 Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Thu, 16 Nov 2023 17:58:05 -0600 Subject: service: hid: Introduce firmware settings and update activate controller calls --- src/core/CMakeLists.txt | 2 + .../service/hid/controllers/controller_base.cpp | 9 +- .../hle/service/hid/controllers/controller_base.h | 4 +- src/core/hle/service/hid/controllers/npad.h | 7 + src/core/hle/service/hid/controllers/palma.cpp | 2 +- src/core/hle/service/hid/hid.cpp | 7 +- src/core/hle/service/hid/hid_firmware_settings.cpp | 99 ++++++++++++++ src/core/hle/service/hid/hid_firmware_settings.h | 54 ++++++++ src/core/hle/service/hid/hid_server.cpp | 146 ++++++++++++++++----- src/core/hle/service/hid/hid_server.h | 5 +- src/core/hle/service/hid/resource_manager.cpp | 12 +- src/core/hle/service/hid/resource_manager.h | 2 - 12 files changed, 295 insertions(+), 54 deletions(-) create mode 100644 src/core/hle/service/hid/hid_firmware_settings.cpp create mode 100644 src/core/hle/service/hid/hid_firmware_settings.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 3aa2e4340..555807e19 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -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 diff --git a/src/core/hle/service/hid/controllers/controller_base.cpp b/src/core/hle/service/hid/controllers/controller_base.cpp index c58d67d7d..0bcd87062 100644 --- a/src/core/hle/service/hid/controllers/controller_base.cpp +++ b/src/core/hle/service/hid/controllers/controller_base.cpp @@ -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() { diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h index d6f7a5073..9a44ee41e 100644 --- a/src/core/hle/service/hid/controllers/controller_base.h +++ b/src/core/hle/service/hid/controllers/controller_base.h @@ -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(); diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 949e58a4c..e23b4986c 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -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; diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp index 73a2a2b91..51a18335f 100644 --- a/src/core/hle/service/hid/controllers/palma.cpp +++ b/src/core/hle/service/hid/controllers/palma.cpp @@ -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; } diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 801a4d08f..1b7381d8d 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -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(system); std::shared_ptr resouce_manager = std::make_shared(system); + std::shared_ptr firmware_settings = + std::make_shared(); - server_manager->RegisterNamedService("hid", - std::make_shared(system, resouce_manager)); + server_manager->RegisterNamedService( + "hid", std::make_shared(system, resouce_manager, firmware_settings)); server_manager->RegisterNamedService( "hid:dbg", std::make_shared(system, resouce_manager)); server_manager->RegisterNamedService( diff --git a/src/core/hle/service/hid/hid_firmware_settings.cpp b/src/core/hle/service/hid/hid_firmware_settings.cpp new file mode 100644 index 000000000..59bd6825c --- /dev/null +++ b/src/core/hle/service/hid/hid_firmware_settings.cpp @@ -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 diff --git a/src/core/hle/service/hid/hid_firmware_settings.h b/src/core/hle/service/hid/hid_firmware_settings.h new file mode 100644 index 000000000..6c10c440b --- /dev/null +++ b/src/core/hle/service/hid/hid_firmware_settings.h @@ -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; + using FeaturesPerId = std::array; + + 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 diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp index 2fb31cf47..0be6a7186 100644 --- a/src/core/hle/service/hid/hid_server.cpp +++ b/src/core/hle/service/hid/hid_server.cpp @@ -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 resource_manager; }; -IHidServer::IHidServer(Core::System& system_, std::shared_ptr resource) - : ServiceFramework{system_, "hid"}, resource_manager{resource} { +IHidServer::IHidServer(Core::System& system_, std::shared_ptr resource, + std::shared_ptr 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()}; - 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(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()}; - 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(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()}; - GetResourceManager()->ActivateController(HidController::Mouse); - LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); + Result result = ResultSuccess; + auto& mouse = GetResourceManager()->GetController(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()}; - GetResourceManager()->ActivateController(HidController::Keyboard); - LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); + Result result = ResultSuccess; + auto& keyboard = + GetResourceManager()->GetController(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()}; - 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(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()}; - GetResourceManager()->ActivateController(HidController::NPad); - LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); + auto& npad = GetResourceManager()->GetController(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()}; - 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()}; - 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(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()}; - 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( + 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()}; - 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( + 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(HidController::ConsoleSixAxisSensor) - .ActivateController(); + .Activate(); GetResourceManager() ->GetController(HidController::ConsoleSixAxisSensor) diff --git a/src/core/hle/service/hid/hid_server.h b/src/core/hle/service/hid/hid_server.h index 98353b0db..eb2e8e7f4 100644 --- a/src/core/hle/service/hid/hid_server.h +++ b/src/core/hle/service/hid/hid_server.h @@ -11,10 +11,12 @@ class System; namespace Service::HID { class ResourceManager; +class HidFirmwareSettings; class IHidServer final : public ServiceFramework { public: - explicit IHidServer(Core::System& system_, std::shared_ptr resource); + explicit IHidServer(Core::System& system_, std::shared_ptr resource, + std::shared_ptr settings); ~IHidServer() override; std::shared_ptr GetResourceManager(); @@ -141,6 +143,7 @@ private: void IsFirmwareUpdateNeededForNotification(HLERequestContext& ctx); std::shared_ptr resource_manager; + std::shared_ptr firmware_settings; }; } // namespace Service::HID diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/core/hle/service/hid/resource_manager.cpp index 4e462f3b3..d6f42c646 100644 --- a/src/core/hle/service/hid/resource_manager.cpp +++ b/src/core/hle/service/hid/resource_manager.cpp @@ -59,8 +59,8 @@ void ResourceManager::Initialize() { MakeControllerWithServiceContext(HidController::Palma, shared_memory); // Homebrew doesn't try to activate some controllers, so we activate them by default - GetController(HidController::NPad).ActivateController(); - GetController(HidController::Touchscreen).ActivateController(); + GetController(HidController::NPad).Activate(); + GetController(HidController::Touchscreen).Activate(); GetController(HidController::HomeButton).SetCommonHeaderOffset(0x4C00); GetController(HidController::SleepButton).SetCommonHeaderOffset(0x4E00); @@ -73,14 +73,6 @@ void ResourceManager::Initialize() { is_initialized = true; } -void ResourceManager::ActivateController(HidController controller) { - controllers[static_cast(controller)]->ActivateController(); -} - -void ResourceManager::DeactivateController(HidController controller) { - controllers[static_cast(controller)]->DeactivateController(); -} - void ResourceManager::UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { auto& core_timing = system.CoreTiming(); diff --git a/src/core/hle/service/hid/resource_manager.h b/src/core/hle/service/hid/resource_manager.h index 81b17f9a9..34dbf36bc 100644 --- a/src/core/hle/service/hid/resource_manager.h +++ b/src/core/hle/service/hid/resource_manager.h @@ -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); -- cgit v1.2.3