committed by
german77
7 changed files with 842 additions and 33 deletions
-
2src/core/CMakeLists.txt
-
6src/core/hle/service/hid/controllers/npad.cpp
-
229src/core/hle/service/hid/controllers/palma.cpp
-
163src/core/hle/service/hid/controllers/palma.h
-
2src/core/hle/service/hid/errors.h
-
444src/core/hle/service/hid/hid.cpp
-
29src/core/hle/service/hid/hid.h
@ -0,0 +1,229 @@ |
|||||
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
|
||||
|
#include "core/core_timing.h"
|
||||
|
#include "core/hid/emulated_controller.h"
|
||||
|
#include "core/hid/hid_core.h"
|
||||
|
#include "core/hid/hid_types.h"
|
||||
|
#include "core/hle/kernel/k_event.h"
|
||||
|
#include "core/hle/kernel/k_readable_event.h"
|
||||
|
#include "core/hle/service/hid/controllers/palma.h"
|
||||
|
#include "core/hle/service/kernel_helpers.h"
|
||||
|
|
||||
|
namespace Service::HID { |
||||
|
|
||||
|
Controller_Palma::Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, |
||||
|
KernelHelpers::ServiceContext& service_context_) |
||||
|
: ControllerBase{hid_core_}, service_context{service_context_} { |
||||
|
controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other); |
||||
|
operation_complete_event = service_context.CreateEvent("hid:PalmaOperationCompleteEvent"); |
||||
|
} |
||||
|
|
||||
|
Controller_Palma::~Controller_Palma() = default; |
||||
|
|
||||
|
void Controller_Palma::OnInit() {} |
||||
|
|
||||
|
void Controller_Palma::OnRelease() {} |
||||
|
|
||||
|
void Controller_Palma::OnUpdate(const Core::Timing::CoreTiming& core_timing) { |
||||
|
if (!IsControllerActivated()) { |
||||
|
return; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Result Controller_Palma::GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id, |
||||
|
PalmaConnectionHandle& handle) { |
||||
|
active_handle.npad_id = npad_id; |
||||
|
handle = active_handle; |
||||
|
return ResultSuccess; |
||||
|
} |
||||
|
|
||||
|
Result Controller_Palma::InitializePalma(const PalmaConnectionHandle& handle) { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
return InvalidPalmaHandle; |
||||
|
} |
||||
|
ActivateController(); |
||||
|
return ResultSuccess; |
||||
|
} |
||||
|
|
||||
|
Kernel::KReadableEvent& Controller_Palma::AcquirePalmaOperationCompleteEvent( |
||||
|
const PalmaConnectionHandle& handle) const { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
LOG_ERROR(Service_HID, "Invalid npad id {}", handle.npad_id); |
||||
|
} |
||||
|
return operation_complete_event->GetReadableEvent(); |
||||
|
} |
||||
|
|
||||
|
Result Controller_Palma::GetPalmaOperationInfo(const PalmaConnectionHandle& handle, |
||||
|
PalmaOperationType& operation_type, |
||||
|
PalmaOperationData& data) const { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
return InvalidPalmaHandle; |
||||
|
} |
||||
|
operation_type = operation.operation; |
||||
|
data = operation.data; |
||||
|
return ResultSuccess; |
||||
|
} |
||||
|
|
||||
|
Result Controller_Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle, |
||||
|
u64 palma_activity) { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
return InvalidPalmaHandle; |
||||
|
} |
||||
|
operation.operation = PalmaOperationType::PlayActivity; |
||||
|
operation.result = PalmaResultSuccess; |
||||
|
operation.data = {}; |
||||
|
operation_complete_event->GetWritableEvent().Signal(); |
||||
|
return ResultSuccess; |
||||
|
} |
||||
|
|
||||
|
Result Controller_Palma::SetPalmaFrModeType(const PalmaConnectionHandle& handle, |
||||
|
PalmaFrModeType fr_mode_) { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
return InvalidPalmaHandle; |
||||
|
} |
||||
|
fr_mode = fr_mode_; |
||||
|
return ResultSuccess; |
||||
|
} |
||||
|
|
||||
|
Result Controller_Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
return InvalidPalmaHandle; |
||||
|
} |
||||
|
operation.operation = PalmaOperationType::ReadStep; |
||||
|
operation.result = PalmaResultSuccess; |
||||
|
operation.data = {}; |
||||
|
operation_complete_event->GetWritableEvent().Signal(); |
||||
|
return ResultSuccess; |
||||
|
} |
||||
|
|
||||
|
Result Controller_Palma::EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled) { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
return InvalidPalmaHandle; |
||||
|
} |
||||
|
return ResultSuccess; |
||||
|
} |
||||
|
|
||||
|
Result Controller_Palma::ResetPalmaStep(const PalmaConnectionHandle& handle) { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
return InvalidPalmaHandle; |
||||
|
} |
||||
|
return ResultSuccess; |
||||
|
} |
||||
|
|
||||
|
void Controller_Palma::ReadPalmaApplicationSection() {} |
||||
|
|
||||
|
void Controller_Palma::WritePalmaApplicationSection() {} |
||||
|
|
||||
|
Result Controller_Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
return InvalidPalmaHandle; |
||||
|
} |
||||
|
operation.operation = PalmaOperationType::ReadUniqueCode; |
||||
|
operation.result = PalmaResultSuccess; |
||||
|
operation.data = {}; |
||||
|
operation_complete_event->GetWritableEvent().Signal(); |
||||
|
return ResultSuccess; |
||||
|
} |
||||
|
|
||||
|
Result Controller_Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
return InvalidPalmaHandle; |
||||
|
} |
||||
|
operation.operation = PalmaOperationType::SetUniqueCodeInvalid; |
||||
|
operation.result = PalmaResultSuccess; |
||||
|
operation.data = {}; |
||||
|
operation_complete_event->GetWritableEvent().Signal(); |
||||
|
return ResultSuccess; |
||||
|
} |
||||
|
|
||||
|
void Controller_Palma::WritePalmaActivityEntry() {} |
||||
|
|
||||
|
Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, |
||||
|
u64 unknown) { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
return InvalidPalmaHandle; |
||||
|
} |
||||
|
operation.operation = PalmaOperationType::WriteRgbLedPatternEntry; |
||||
|
operation.result = PalmaResultSuccess; |
||||
|
operation.data = {}; |
||||
|
operation_complete_event->GetWritableEvent().Signal(); |
||||
|
return ResultSuccess; |
||||
|
} |
||||
|
|
||||
|
Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, |
||||
|
u8* t_mem, u64 size) { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
return InvalidPalmaHandle; |
||||
|
} |
||||
|
operation.operation = PalmaOperationType::WriteWaveEntry; |
||||
|
operation.result = PalmaResultSuccess; |
||||
|
operation.data = {}; |
||||
|
operation_complete_event->GetWritableEvent().Signal(); |
||||
|
return ResultSuccess; |
||||
|
} |
||||
|
|
||||
|
Result Controller_Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle, |
||||
|
s32 database_id_version_) { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
return InvalidPalmaHandle; |
||||
|
} |
||||
|
database_id_version = database_id_version_; |
||||
|
operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion; |
||||
|
operation.result = PalmaResultSuccess; |
||||
|
operation.data[0] = {}; |
||||
|
operation_complete_event->GetWritableEvent().Signal(); |
||||
|
return ResultSuccess; |
||||
|
} |
||||
|
|
||||
|
Result Controller_Palma::GetPalmaDataBaseIdentificationVersion( |
||||
|
const PalmaConnectionHandle& handle) { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
return InvalidPalmaHandle; |
||||
|
} |
||||
|
operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion; |
||||
|
operation.result = PalmaResultSuccess; |
||||
|
operation.data = {}; |
||||
|
operation.data[0] = static_cast<u8>(database_id_version); |
||||
|
operation_complete_event->GetWritableEvent().Signal(); |
||||
|
return ResultSuccess; |
||||
|
} |
||||
|
|
||||
|
void Controller_Palma::SuspendPalmaFeature() {} |
||||
|
|
||||
|
Result Controller_Palma::GetPalmaOperationResult(const PalmaConnectionHandle& handle) const { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
return InvalidPalmaHandle; |
||||
|
} |
||||
|
return operation.result; |
||||
|
} |
||||
|
void Controller_Palma::ReadPalmaPlayLog() {} |
||||
|
|
||||
|
void Controller_Palma::ResetPalmaPlayLog() {} |
||||
|
|
||||
|
void Controller_Palma::SetIsPalmaAllConnectable(bool is_all_connectable) { |
||||
|
// If true controllers are able to be paired
|
||||
|
is_connectable = is_all_connectable; |
||||
|
} |
||||
|
|
||||
|
void Controller_Palma::SetIsPalmaPairedConnectable() {} |
||||
|
|
||||
|
Result Controller_Palma::PairPalma(const PalmaConnectionHandle& handle) { |
||||
|
if (handle.npad_id != active_handle.npad_id) { |
||||
|
return InvalidPalmaHandle; |
||||
|
} |
||||
|
// TODO: Do something
|
||||
|
return ResultSuccess; |
||||
|
} |
||||
|
|
||||
|
void Controller_Palma::SetPalmaBoostMode(bool boost_mode) {} |
||||
|
|
||||
|
void Controller_Palma::CancelWritePalmaWaveEntry() {} |
||||
|
|
||||
|
void Controller_Palma::EnablePalmaBoostMode() {} |
||||
|
|
||||
|
void Controller_Palma::GetPalmaBluetoothAddress() {} |
||||
|
|
||||
|
void Controller_Palma::SetDisallowedPalmaConnection() {} |
||||
|
|
||||
|
} // namespace Service::HID
|
||||
@ -0,0 +1,163 @@ |
|||||
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project |
||||
|
// SPDX-License-Identifier: GPL-2.0-or-later |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include <array> |
||||
|
#include "common/common_funcs.h" |
||||
|
#include "common/common_types.h" |
||||
|
#include "core/hle/service/hid/controllers/controller_base.h" |
||||
|
#include "core/hle/service/hid/errors.h" |
||||
|
|
||||
|
namespace Kernel { |
||||
|
class KEvent; |
||||
|
class KReadableEvent; |
||||
|
} // namespace Kernel |
||||
|
|
||||
|
namespace Service::KernelHelpers { |
||||
|
class ServiceContext; |
||||
|
} |
||||
|
|
||||
|
namespace Core::HID { |
||||
|
class EmulatedController; |
||||
|
} // namespace Core::HID |
||||
|
|
||||
|
namespace Service::HID { |
||||
|
class Controller_Palma final : public ControllerBase { |
||||
|
public: |
||||
|
using PalmaOperationData = std::array<u8, 0x140>; |
||||
|
|
||||
|
// This is nn::hid::PalmaOperationType |
||||
|
enum class PalmaOperationType { |
||||
|
PlayActivity, |
||||
|
SetFrModeType, |
||||
|
ReadStep, |
||||
|
EnableStep, |
||||
|
ResetStep, |
||||
|
ReadApplicationSection, |
||||
|
WriteApplicationSection, |
||||
|
ReadUniqueCode, |
||||
|
SetUniqueCodeInvalid, |
||||
|
WriteActivityEntry, |
||||
|
WriteRgbLedPatternEntry, |
||||
|
WriteWaveEntry, |
||||
|
ReadDataBaseIdentificationVersion, |
||||
|
WriteDataBaseIdentificationVersion, |
||||
|
SuspendFeature, |
||||
|
ReadPlayLog, |
||||
|
ResetPlayLog, |
||||
|
}; |
||||
|
|
||||
|
// This is nn::hid::PalmaWaveSet |
||||
|
enum class PalmaWaveSet : u64 { |
||||
|
Small, |
||||
|
Medium, |
||||
|
Large, |
||||
|
}; |
||||
|
|
||||
|
// This is nn::hid::PalmaFrModeType |
||||
|
enum class PalmaFrModeType : u64 { |
||||
|
Off, |
||||
|
B01, |
||||
|
B02, |
||||
|
B03, |
||||
|
Downloaded, |
||||
|
}; |
||||
|
|
||||
|
// This is nn::hid::PalmaFeature |
||||
|
enum class PalmaFeature : u64 { |
||||
|
FrMode, |
||||
|
RumbleFeedback, |
||||
|
Step, |
||||
|
MuteSwitch, |
||||
|
}; |
||||
|
|
||||
|
// This is nn::hid::PalmaOperationInfo |
||||
|
struct PalmaOperationInfo { |
||||
|
PalmaOperationType operation{}; |
||||
|
Result result{PalmaResultSuccess}; |
||||
|
PalmaOperationData data{}; |
||||
|
}; |
||||
|
static_assert(sizeof(PalmaOperationInfo) == 0x148, "PalmaOperationInfo is an invalid size"); |
||||
|
|
||||
|
// This is nn::hid::PalmaActivityEntry |
||||
|
struct PalmaActivityEntry { |
||||
|
u32 rgb_led_pattern_index; |
||||
|
INSERT_PADDING_BYTES(2); |
||||
|
PalmaWaveSet wave_set; |
||||
|
u32 wave_index; |
||||
|
INSERT_PADDING_BYTES(12); |
||||
|
}; |
||||
|
static_assert(sizeof(PalmaActivityEntry) == 0x20, "PalmaActivityEntry is an invalid size"); |
||||
|
|
||||
|
struct PalmaConnectionHandle { |
||||
|
Core::HID::NpadIdType npad_id; |
||||
|
INSERT_PADDING_BYTES(4); // Unknown |
||||
|
}; |
||||
|
static_assert(sizeof(PalmaConnectionHandle) == 0x8, |
||||
|
"PalmaConnectionHandle has incorrect size."); |
||||
|
|
||||
|
explicit Controller_Palma(Core::HID::HIDCore& hid_core_, u8* raw_shared_memory_, |
||||
|
KernelHelpers::ServiceContext& service_context_); |
||||
|
~Controller_Palma() override; |
||||
|
|
||||
|
// Called when the controller is initialized |
||||
|
void OnInit() override; |
||||
|
|
||||
|
// When the controller is released |
||||
|
void OnRelease() override; |
||||
|
|
||||
|
// When the controller is requesting an update for the shared memory |
||||
|
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override; |
||||
|
|
||||
|
Result GetPalmaConnectionHandle(Core::HID::NpadIdType npad_id, PalmaConnectionHandle& handle); |
||||
|
Result InitializePalma(const PalmaConnectionHandle& handle); |
||||
|
Kernel::KReadableEvent& AcquirePalmaOperationCompleteEvent( |
||||
|
const PalmaConnectionHandle& handle) const; |
||||
|
Result GetPalmaOperationInfo(const PalmaConnectionHandle& handle, |
||||
|
PalmaOperationType& operation_type, |
||||
|
PalmaOperationData& data) const; |
||||
|
Result PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_activity); |
||||
|
Result SetPalmaFrModeType(const PalmaConnectionHandle& handle, PalmaFrModeType fr_mode_); |
||||
|
Result ReadPalmaStep(const PalmaConnectionHandle& handle); |
||||
|
Result EnablePalmaStep(const PalmaConnectionHandle& handle, bool is_enabled); |
||||
|
Result ResetPalmaStep(const PalmaConnectionHandle& handle); |
||||
|
Result ReadPalmaUniqueCode(const PalmaConnectionHandle& handle); |
||||
|
Result SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle); |
||||
|
Result WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, u64 unknown); |
||||
|
Result WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWaveSet wave, u8* t_mem, |
||||
|
u64 size); |
||||
|
Result SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle, |
||||
|
s32 database_id_version_); |
||||
|
Result GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& handle); |
||||
|
Result GetPalmaOperationResult(const PalmaConnectionHandle& handle) const; |
||||
|
void SetIsPalmaAllConnectable(bool is_all_connectable); |
||||
|
Result PairPalma(const PalmaConnectionHandle& handle); |
||||
|
void SetPalmaBoostMode(bool boost_mode); |
||||
|
|
||||
|
private: |
||||
|
void ReadPalmaApplicationSection(); |
||||
|
void WritePalmaApplicationSection(); |
||||
|
void WritePalmaActivityEntry(); |
||||
|
void SuspendPalmaFeature(); |
||||
|
void ReadPalmaPlayLog(); |
||||
|
void ResetPalmaPlayLog(); |
||||
|
void SetIsPalmaPairedConnectable(); |
||||
|
void CancelWritePalmaWaveEntry(); |
||||
|
void EnablePalmaBoostMode(); |
||||
|
void GetPalmaBluetoothAddress(); |
||||
|
void SetDisallowedPalmaConnection(); |
||||
|
|
||||
|
bool is_connectable{}; |
||||
|
s32 database_id_version{}; |
||||
|
PalmaOperationInfo operation{}; |
||||
|
PalmaFrModeType fr_mode{}; |
||||
|
PalmaConnectionHandle active_handle{}; |
||||
|
|
||||
|
Core::HID::EmulatedController* controller; |
||||
|
|
||||
|
Kernel::KEvent* operation_complete_event; |
||||
|
KernelHelpers::ServiceContext& service_context; |
||||
|
}; |
||||
|
|
||||
|
} // namespace Service::HID |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue