From 465501b5aceb80f6014f6ab1382e80e8e4e1559a Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Fri, 8 Dec 2023 07:20:22 +0100 Subject: [PATCH] early-access version 4010 --- README.md | 2 +- dist/72-yuzu-input.rules | 19 ++ src/core/CMakeLists.txt | 2 + .../hid/controllers/applet_resource.cpp | 199 ++++++++++++++++++ .../service/hid/controllers/applet_resource.h | 87 ++++++++ src/core/hle/service/hid/errors.h | 5 + src/core/hle/service/hid/hid.cpp | 8 + src/core/hle/service/hid/hid_server.cpp | 7 +- .../hle/service/hid/hid_system_server.cpp | 136 +++++++++++- src/core/hle/service/hid/hid_system_server.h | 6 + src/core/hle/service/hid/resource_manager.cpp | 62 +++++- src/core/hle/service/hid/resource_manager.h | 27 +++ src/video_core/host1x/ffmpeg/ffmpeg.cpp | 7 +- 13 files changed, 552 insertions(+), 15 deletions(-) create mode 100755 dist/72-yuzu-input.rules create mode 100755 src/core/hle/service/hid/controllers/applet_resource.cpp create mode 100755 src/core/hle/service/hid/controllers/applet_resource.h diff --git a/README.md b/README.md index 35f181a03..3db28b3df 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 4009. +This is the source code for early-access 4010. ## Legal Notice diff --git a/dist/72-yuzu-input.rules b/dist/72-yuzu-input.rules new file mode 100755 index 000000000..d64f8b28d --- /dev/null +++ b/dist/72-yuzu-input.rules @@ -0,0 +1,19 @@ +# SPDX-FileCopyrightText: 2023 yuzu Emulator Project +# SPDX-License-Identifier: GPL-2.0-or-later + +# Allow systemd-logind to manage user access to hidraw with this file +# On most systems, this file should be installed to /etc/udev/rules.d/72-yuzu-input.rules +# Consult your distro if this is not the case + +# Switch Pro Controller (USB/Bluetooth) +KERNEL=="hidraw*", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="2009", MODE="0660", TAG+="uaccess" +KERNEL=="hidraw*", KERNELS=="*057e:2009*", MODE="0660", TAG+="uaccess" + +# Joy-Con L (Bluetooth) +KERNEL=="hidraw*", KERNELS=="*057e:2006*", MODE="0660", TAG+="uaccess" + +# Joy-Con R (Bluetooth) +KERNEL=="hidraw*", KERNELS=="*057e:2007*", MODE="0660", TAG+="uaccess" + +# Joy-Con Charging Grip (USB) +KERNEL=="hidraw*", ATTRS{idVendor}=="057e", ATTRS{idProduct}=="200e", MODE="0660", TAG+="uaccess" diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 45862463e..9907a6dc4 100755 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -543,6 +543,8 @@ add_library(core STATIC hle/service/hid/xcd.cpp hle/service/hid/xcd.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.h hle/service/hid/controllers/controller_base.cpp diff --git a/src/core/hle/service/hid/controllers/applet_resource.cpp b/src/core/hle/service/hid/controllers/applet_resource.cpp new file mode 100755 index 000000000..ee60d8b44 --- /dev/null +++ b/src/core/hle/service/hid/controllers/applet_resource.cpp @@ -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 diff --git a/src/core/hle/service/hid/controllers/applet_resource.h b/src/core/hle/service/hid/controllers/applet_resource.h new file mode 100755 index 000000000..3dcec2898 --- /dev/null +++ b/src/core/hle/service/hid/controllers/applet_resource.h @@ -0,0 +1,87 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include + +#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 flag{}; + std::array 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 data{}; + + Core::System& system; +}; +} // namespace Service::HID diff --git a/src/core/hle/service/hid/errors.h b/src/core/hle/service/hid/errors.h index 5f5fc581a..a4a23f200 100755 --- a/src/core/hle/service/hid/errors.h +++ b/src/core/hle/service/hid/errors.h @@ -19,6 +19,11 @@ 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 ResultAruidNoAvailableEntries{ErrorModule::HID, 1044}; +constexpr Result ResultAruidAlreadyRegistered{ErrorModule::HID, 1046}; +constexpr Result ResultAruidNotRegistered{ErrorModule::HID, 1047}; + constexpr Result InvalidPalmaHandle{ErrorModule::HID, 3302}; } // namespace Service::HID diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index b6cfc02b0..6b6eef841 100755 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // 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_debug_server.h" #include "core/hle/service/hid/hid_firmware_settings.h" @@ -20,6 +22,12 @@ void LoopProcess(Core::System& system) { std::shared_ptr firmware_settings = std::make_shared(); + // 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( "hid", std::make_shared(system, resouce_manager, firmware_settings)); server_manager->RegisterNamedService( diff --git a/src/core/hle/service/hid/hid_server.cpp b/src/core/hle/service/hid/hid_server.cpp index a7d1578d9..e0f4051aa 100755 --- a/src/core/hle/service/hid/hid_server.cpp +++ b/src/core/hle/service/hid/hid_server.cpp @@ -224,8 +224,13 @@ void IHidServer::CreateAppletResource(HLERequestContext& ctx) { 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}; - rb.Push(ResultSuccess); + rb.Push(result); rb.PushIpcInterface(system, resource_manager); } diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp index b56d0347a..4d33456a3 100755 --- a/src/core/hle/service/hid/hid_system_server.cpp +++ b/src/core/hle/service/hid/hid_system_server.cpp @@ -3,6 +3,7 @@ #include "core/hid/hid_core.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/errors.h" #include "core/hle/service/hid/hid_system_server.h" @@ -63,13 +64,13 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr()}; + + 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()}; + + 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()}; + + 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()}; + + 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()}; + + 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()}; + + 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) { LOG_INFO(Service_AM, "(STUBBED) called"); diff --git a/src/core/hle/service/hid/hid_system_server.h b/src/core/hle/service/hid/hid_system_server.h index 822d5e5b9..1e623dfc2 100755 --- a/src/core/hle/service/hid/hid_system_server.h +++ b/src/core/hle/service/hid/hid_system_server.h @@ -38,6 +38,12 @@ private: void HasLeftRightBattery(HLERequestContext& ctx); void GetUniquePadsFromNpad(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 AcquireDeviceRegisteredEventForControllerSupport(HLERequestContext& ctx); void GetRegisteredDevices(HLERequestContext& ctx); diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/core/hle/service/hid/resource_manager.cpp index e76d4eea9..60d4ef71f 100755 --- a/src/core/hle/service/hid/resource_manager.cpp +++ b/src/core/hle/service/hid/resource_manager.cpp @@ -9,6 +9,7 @@ #include "core/hle/service/hid/resource_manager.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/debug_pad.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) ResourceManager::ResourceManager(Core::System& system_) - : system{system_}, service_context{system_, "hid"} {} + : system{system_}, service_context{system_, "hid"} { + applet_resource = std::make_shared(system); +} ResourceManager::~ResourceManager() = default; @@ -77,6 +80,11 @@ void ResourceManager::Initialize() { system.HIDCore().ReloadInputDevices(); is_initialized = true; } + +std::shared_ptr ResourceManager::GetAppletResource() const { + return applet_resource; +} + std::shared_ptr ResourceManager::GetCaptureButton() const { return capture_button; } @@ -137,6 +145,46 @@ std::shared_ptr ResourceManager::GetUniquePad() const { 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, std::chrono::nanoseconds ns_late) { 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 resource) - : ServiceFramework{system_, "IAppletResource"} { + : ServiceFramework{system_, "IAppletResource"}, resource_manager{resource} { static const FunctionInfo functions[] = { {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"}, }; RegisterHandlers(functions); - resource->Initialize(); - // Register update callbacks npad_update_event = Core::Timing::CreateEvent( "HID::UpdatePadCallback", @@ -233,9 +279,13 @@ IAppletResource::~IAppletResource() { void IAppletResource::GetSharedMemoryHandle(HLERequestContext& ctx) { 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}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(&system.Kernel().GetHidSharedMem()); + rb.Push(result); + rb.PushCopyObjects(handle); } } // namespace Service::HID diff --git a/src/core/hle/service/hid/resource_manager.h b/src/core/hle/service/hid/resource_manager.h index 2b6a9b5e6..a78e2b729 100755 --- a/src/core/hle/service/hid/resource_manager.h +++ b/src/core/hle/service/hid/resource_manager.h @@ -6,11 +6,20 @@ #include "core/hle/service/kernel_helpers.h" #include "core/hle/service/service.h" +namespace Core { +class System; +} + namespace Core::Timing { struct EventType; } +namespace Kernel { +class KSharedMemory; +} + namespace Service::HID { +class AppletResource; class Controller_Stubbed; class ConsoleSixAxis; class DebugPad; @@ -38,6 +47,7 @@ public: void Initialize(); + std::shared_ptr GetAppletResource() const; std::shared_ptr GetCaptureButton() const; std::shared_ptr GetConsoleSixAxis() const; std::shared_ptr GetDebugMouse() const; @@ -54,6 +64,18 @@ public: std::shared_ptr GetTouchScreen() const; std::shared_ptr 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 UpdateNpad(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: bool is_initialized{false}; + mutable std::mutex shared_mutex; + std::shared_ptr applet_resource = nullptr; + std::shared_ptr capture_button = nullptr; std::shared_ptr console_six_axis = nullptr; std::shared_ptr debug_mouse = nullptr; @@ -106,6 +131,8 @@ private: std::shared_ptr default_update_event; std::shared_ptr mouse_keyboard_update_event; std::shared_ptr motion_update_event; + + std::shared_ptr resource_manager; }; } // namespace Service::HID diff --git a/src/video_core/host1x/ffmpeg/ffmpeg.cpp b/src/video_core/host1x/ffmpeg/ffmpeg.cpp index dcd07e6d2..96686da59 100755 --- a/src/video_core/host1x/ffmpeg/ffmpeg.cpp +++ b/src/video_core/host1x/ffmpeg/ffmpeg.cpp @@ -233,7 +233,12 @@ std::unique_ptr DecoderContext::ReceiveFrame(bool* out_is_interlaced) { return false; } - *out_is_interlaced = frame->interlaced_frame != 0; + *out_is_interlaced = +#if defined(FF_API_INTERLACED_FRAME) || LIBAVUTIL_VERSION_MAJOR >= 59 + (frame->flags & AV_FRAME_FLAG_INTERLACED) != 0; +#else + frame->interlaced_frame != 0; +#endif return true; };