10 changed files with 526 additions and 13 deletions
-
2src/core/CMakeLists.txt
-
199src/core/hle/service/hid/controllers/applet_resource.cpp
-
87src/core/hle/service/hid/controllers/applet_resource.h
-
5src/core/hle/service/hid/errors.h
-
8src/core/hle/service/hid/hid.cpp
-
7src/core/hle/service/hid/hid_server.cpp
-
136src/core/hle/service/hid/hid_system_server.cpp
-
6src/core/hle/service/hid/hid_system_server.h
-
62src/core/hle/service/hid/resource_manager.cpp
-
27src/core/hle/service/hid/resource_manager.h
@ -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
|
||||
@ -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 |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue