| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- // 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 "hid_core/hid_result.h"
- #include "hid_core/resources/applet_resource.h"
- #include "hid_core/resources/shared_memory_format.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;
- }
- auto& shared_memory = shared_memory_holder[index];
- if (!shared_memory.IsMapped()) {
- const Result result = shared_memory.Initialize(system);
- if (result.IsError()) {
- return result;
- }
- if (shared_memory.GetAddress() == nullptr) {
- shared_memory.Finalize();
- return ResultSharedMemoryNotInitialized;
- }
- }
- auto* shared_memory_format = shared_memory.GetAddress();
- if (shared_memory_format != nullptr) {
- shared_memory_format->Initialize();
- }
- data[index].shared_memory_format = shared_memory_format;
- 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;
- }
- // TODO: Don't Handle pending delete here
- if (registration_list.flag[i] == RegistrationStatus::None ||
- registration_list.flag[i] == RegistrationStatus::PendingDelete) {
- 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) {
- const u64 index = GetIndexFromAruid(aruid);
- if (index >= AruidIndexMax) {
- return;
- }
- FreeAppletResourceId(aruid);
- DestroySevenSixAxisTransferMemory();
- data[index].flag.raw = 0;
- data[index].aruid = 0;
- registration_list.flag[index] = RegistrationStatus::PendingDelete;
- }
- void AppletResource::FreeAppletResourceId(u64 aruid) {
- const u64 index = GetIndexFromAruid(aruid);
- if (index >= AruidIndexMax) {
- return;
- }
- auto& aruid_data = data[index];
- if (aruid_data.flag.is_assigned) {
- aruid_data.shared_memory_format = nullptr;
- aruid_data.flag.is_assigned.Assign(false);
- shared_memory_holder[index].Finalize();
- }
- }
- u64 AppletResource::GetActiveAruid() {
- return active_aruid;
- }
- Result AppletResource::GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid) {
- const u64 index = GetIndexFromAruid(aruid);
- if (index >= AruidIndexMax) {
- return ResultAruidNotRegistered;
- }
- *out_handle = shared_memory_holder[index].GetHandle();
- return ResultSuccess;
- }
- Result AppletResource::GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format,
- u64 aruid) {
- const u64 index = GetIndexFromAruid(aruid);
- if (index >= AruidIndexMax) {
- return ResultAruidNotRegistered;
- }
- *out_shared_memory_format = data[index].shared_memory_format;
- return ResultSuccess;
- }
- AruidData* AppletResource::GetAruidData(u64 aruid) {
- const u64 aruid_index = GetIndexFromAruid(aruid);
- if (aruid_index == AruidIndexMax) {
- return nullptr;
- }
- return &data[aruid_index];
- }
- AruidData* AppletResource::GetAruidDataByIndex(std::size_t aruid_index) {
- return &data[aruid_index];
- }
- bool AppletResource::IsVibrationAruidActive(u64 aruid) const {
- return aruid == 0 || aruid == active_vibration_aruid;
- }
- 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);
- }
- Result AppletResource::RegisterCoreAppletResource() {
- if (ref_counter == std::numeric_limits<s32>::max() - 1) {
- return ResultAppletResourceOverflow;
- }
- if (ref_counter == 0) {
- const u64 index = GetIndexFromAruid(0);
- 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 = 0;
- aruid_data.flag.is_initialized.Assign(true);
- 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] != 0) {
- continue;
- }
- data_index = i;
- break;
- }
- if (registration_list.flag[i] == RegistrationStatus::None) {
- data_index = i;
- break;
- }
- }
- Result result = ResultSuccess;
- if (data_index == AruidIndexMax) {
- result = CreateAppletResource(0);
- } else {
- registration_list.flag[data_index] = RegistrationStatus::Initialized;
- registration_list.aruid[data_index] = 0;
- }
- if (result.IsError()) {
- UnregisterAppletResourceUserId(0);
- return result;
- }
- }
- ref_counter++;
- return ResultSuccess;
- }
- Result AppletResource::UnregisterCoreAppletResource() {
- if (ref_counter == 0) {
- return ResultAppletResourceNotInitialized;
- }
- if (--ref_counter == 0) {
- UnregisterAppletResourceUserId(0);
- }
- return ResultSuccess;
- }
- } // namespace Service::HID
|