Browse Source
Merge pull request #8934 from german77/palma_release
Merge pull request #8934 from german77/palma_release
service: hid: Partially implement palma controllernce_cpp
committed by
GitHub
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