summaryrefslogtreecommitdiffstats
path: root/src/core/hle/service/hid/controllers
diff options
context:
space:
mode:
authorliamwhite <liamwhite@users.noreply.github.com>2023-12-09 19:41:06 +0100
committerGitHub <noreply@github.com>2023-12-09 19:41:06 +0100
commitc1924951ad604417a5f7900427bff4ab0c8286a7 (patch)
tree1100f74cd019eabe937e40e921a2b481ca77da69 /src/core/hle/service/hid/controllers
parentMerge pull request #12320 from liamwhite/debug-fix (diff)
parentservice: hid: Introduce proper AppletResource emulation (diff)
downloadyuzu-c1924951ad604417a5f7900427bff4ab0c8286a7.tar
yuzu-c1924951ad604417a5f7900427bff4ab0c8286a7.tar.gz
yuzu-c1924951ad604417a5f7900427bff4ab0c8286a7.tar.bz2
yuzu-c1924951ad604417a5f7900427bff4ab0c8286a7.tar.lz
yuzu-c1924951ad604417a5f7900427bff4ab0c8286a7.tar.xz
yuzu-c1924951ad604417a5f7900427bff4ab0c8286a7.tar.zst
yuzu-c1924951ad604417a5f7900427bff4ab0c8286a7.zip
Diffstat (limited to '')
-rw-r--r--src/core/hle/service/hid/controllers/applet_resource.cpp199
-rw-r--r--src/core/hle/service/hid/controllers/applet_resource.h87
2 files changed, 286 insertions, 0 deletions
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 100644
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 100644
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 <array>
+
+#include "common/bit_field.h"
+#include "common/common_types.h"
+#include "core/hle/result.h"
+
+namespace Core {
+class System;
+}
+
+namespace Kernel {
+class KSharedMemory;
+}
+
+namespace Service::HID {
+class AppletResource {
+public:
+ explicit AppletResource(Core::System& system_);
+ ~AppletResource();
+
+ Result CreateAppletResource(u64 aruid);
+
+ Result RegisterAppletResourceUserId(u64 aruid, bool enable_input);
+ void UnregisterAppletResourceUserId(u64 aruid);
+
+ u64 GetActiveAruid();
+ Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid);
+
+ u64 GetIndexFromAruid(u64 aruid);
+
+ Result DestroySevenSixAxisTransferMemory();
+
+ void EnableInput(u64 aruid, bool is_enabled);
+ void EnableSixAxisSensor(u64 aruid, bool is_enabled);
+ void EnablePadInput(u64 aruid, bool is_enabled);
+ void EnableTouchScreen(u64 aruid, bool is_enabled);
+ void SetIsPalmaConnectable(u64 aruid, bool is_connectable);
+ void EnablePalmaBoostMode(u64 aruid, bool is_enabled);
+
+private:
+ static constexpr std::size_t AruidIndexMax = 0x20;
+
+ enum RegistrationStatus : u32 {
+ None,
+ Initialized,
+ PendingDelete,
+ };
+
+ struct DataStatusFlag {
+ union {
+ u32 raw{};
+
+ BitField<0, 1, u32> is_initialized;
+ BitField<1, 1, u32> is_assigned;
+ BitField<16, 1, u32> enable_pad_input;
+ BitField<17, 1, u32> enable_six_axis_sensor;
+ BitField<18, 1, u32> bit_18;
+ BitField<19, 1, u32> is_palma_connectable;
+ BitField<20, 1, u32> enable_palma_boost_mode;
+ BitField<21, 1, u32> enable_touchscreen;
+ };
+ };
+
+ struct AruidRegisterList {
+ std::array<RegistrationStatus, AruidIndexMax> flag{};
+ std::array<u64, AruidIndexMax> aruid{};
+ };
+ static_assert(sizeof(AruidRegisterList) == 0x180, "AruidRegisterList is an invalid size");
+
+ struct AruidData {
+ DataStatusFlag flag{};
+ u64 aruid{};
+ Kernel::KSharedMemory* shared_memory_handle{nullptr};
+ };
+
+ u64 active_aruid{};
+ AruidRegisterList registration_list{};
+ std::array<AruidData, AruidIndexMax> data{};
+
+ Core::System& system;
+};
+} // namespace Service::HID