From c19ad21ae855c9143a871e378e8d8c59abcaebfa Mon Sep 17 00:00:00 2001 From: german77 Date: Thu, 22 Apr 2021 13:15:59 -0500 Subject: hid: Implement SevenSixAxis and ConsoleSixAxisSensor --- .../service/hid/controllers/console_sixaxis.cpp | 90 ++++++++++++++++++++++ .../hle/service/hid/controllers/console_sixaxis.h | 80 +++++++++++++++++++ src/core/hle/service/hid/controllers/npad.cpp | 4 +- src/core/hle/service/hid/controllers/npad.h | 2 + 4 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 src/core/hle/service/hid/controllers/console_sixaxis.cpp create mode 100644 src/core/hle/service/hid/controllers/console_sixaxis.h (limited to 'src/core/hle/service/hid/controllers') diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/console_sixaxis.cpp new file mode 100644 index 000000000..801e14b79 --- /dev/null +++ b/src/core/hle/service/hid/controllers/console_sixaxis.cpp @@ -0,0 +1,90 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/settings.h" +#include "core/core_timing.h" +#include "core/hle/service/hid/controllers/console_sixaxis.h" + +namespace Service::HID { +constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3C200; + +Controller_ConsoleSixAxis::Controller_ConsoleSixAxis(Core::System& system) + : ControllerBase(system) {} +Controller_ConsoleSixAxis::~Controller_ConsoleSixAxis() = default; + +void Controller_ConsoleSixAxis::OnInit() {} + +void Controller_ConsoleSixAxis::OnRelease() {} + +void Controller_ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* data, + std::size_t size) { + seven_six_axis.header.timestamp = core_timing.GetCPUTicks(); + seven_six_axis.header.total_entry_count = 17; + + if (!IsControllerActivated() || !is_transfer_memory_set) { + seven_six_axis.header.entry_count = 0; + seven_six_axis.header.last_entry_index = 0; + return; + } + seven_six_axis.header.entry_count = 16; + + const auto& last_entry = + seven_six_axis.sevensixaxis_states[seven_six_axis.header.last_entry_index]; + seven_six_axis.header.last_entry_index = (seven_six_axis.header.last_entry_index + 1) % 17; + auto& cur_entry = seven_six_axis.sevensixaxis_states[seven_six_axis.header.last_entry_index]; + + cur_entry.sampling_number = last_entry.sampling_number + 1; + cur_entry.sampling_number2 = cur_entry.sampling_number; + + // Try to read sixaxis sensor states + MotionDevice motion_device{}; + const auto& device = motions[0]; + if (device) { + std::tie(motion_device.accel, motion_device.gyro, motion_device.rotation, + motion_device.orientation, motion_device.quaternion) = device->GetStatus(); + console_six_axis.is_seven_six_axis_sensor_at_rest = motion_device.gyro.Length2() < 0.0001f; + } + + cur_entry.accel = motion_device.accel; + // Zero gyro values as they just mess up with the camera + // Note: Probably a correct sensivity setting must be set + cur_entry.gyro = {}; + cur_entry.quaternion = { + { + motion_device.quaternion.xyz.y, + motion_device.quaternion.xyz.x, + -motion_device.quaternion.w, + }, + -motion_device.quaternion.xyz.z, + }; + + console_six_axis.sampling_number++; + // TODO(German77): Find the purpose of those values + console_six_axis.verticalization_error = 0.0f; + console_six_axis.gyro_bias = {0.0f, 0.0f, 0.0f}; + + // Update console six axis shared memory + std::memcpy(data + SHARED_MEMORY_OFFSET, &console_six_axis, sizeof(console_six_axis)); + // Update seven six axis transfer memory + std::memcpy(transfer_memory, &seven_six_axis, sizeof(seven_six_axis)); +} + +void Controller_ConsoleSixAxis::OnLoadInputDevices() { + const auto player = Settings::values.players.GetValue()[0]; + std::transform(player.motions.begin() + Settings::NativeMotion::MOTION_HID_BEGIN, + player.motions.begin() + Settings::NativeMotion::MOTION_HID_END, motions.begin(), + Input::CreateDevice); +} + +void Controller_ConsoleSixAxis::SetTransferMemoryPointer(u8* t_mem_1) { + is_transfer_memory_set = true; + transfer_memory = t_mem_1; +}; + +void Controller_ConsoleSixAxis::ResetTimestamp() { + auto& cur_entry = seven_six_axis.sevensixaxis_states[seven_six_axis.header.last_entry_index]; + cur_entry.sampling_number = 0; + cur_entry.sampling_number2 = 0; +} +} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.h b/src/core/hle/service/hid/controllers/console_sixaxis.h new file mode 100644 index 000000000..ac0501683 --- /dev/null +++ b/src/core/hle/service/hid/controllers/console_sixaxis.h @@ -0,0 +1,80 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include "common/bit_field.h" +#include "common/common_types.h" +#include "common/quaternion.h" +#include "core/frontend/input.h" +#include "core/hle/service/hid/controllers/controller_base.h" + +namespace Service::HID { +class Controller_ConsoleSixAxis final : public ControllerBase { +public: + explicit Controller_ConsoleSixAxis(Core::System& system); + ~Controller_ConsoleSixAxis() 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, u8* data, size_t size) override; + + // Called when input devices should be loaded + void OnLoadInputDevices() override; + + // Called on InitializeSevenSixAxisSensor + void SetTransferMemoryPointer(u8* t_mem_1); + + // Called on ResetSevenSixAxisSensorTimestamp + void ResetTimestamp(); + +private: + struct SevenSixAxisState { + INSERT_PADDING_WORDS(4); // unused + s64_le sampling_number{}; + s64_le sampling_number2{}; + u64 unknown{}; + Common::Vec3f accel{}; + Common::Vec3f gyro{}; + Common::Quaternion quaternion{}; + }; + static_assert(sizeof(SevenSixAxisState) == 0x50, "SevenSixAxisState is an invalid size"); + + struct SevenSixAxisMemory { + CommonHeader header{}; + std::array sevensixaxis_states{}; + }; + static_assert(sizeof(SevenSixAxisMemory) == 0xA70, "SevenSixAxisMemory is an invalid size"); + + struct ConsoleSharedMemory { + u64_le sampling_number{}; + bool is_seven_six_axis_sensor_at_rest{}; + f32 verticalization_error{}; + Common::Vec3f gyro_bias{}; + }; + static_assert(sizeof(ConsoleSharedMemory) == 0x20, "ConsoleSharedMemory is an invalid size"); + + struct MotionDevice { + Common::Vec3f accel; + Common::Vec3f gyro; + Common::Vec3f rotation; + std::array orientation; + Common::Quaternion quaternion; + }; + + using MotionArray = + std::array, Settings::NativeMotion::NUM_MOTIONS_HID>; + u8* transfer_memory; + MotionArray motions; + bool is_transfer_memory_set = false; + ConsoleSharedMemory console_six_axis{}; + SevenSixAxisMemory seven_six_axis{}; +}; +} // namespace Service::HID diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 113a41254..249c300f6 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -654,8 +654,8 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing const auto& device = motions[i][e]; if (device) { std::tie(motion_devices[e].accel, motion_devices[e].gyro, - motion_devices[e].rotation, motion_devices[e].orientation) = - device->GetStatus(); + motion_devices[e].rotation, motion_devices[e].orientation, + motion_devices[e].quaternion) = device->GetStatus(); sixaxis_at_rest = sixaxis_at_rest && motion_devices[e].gyro.Length2() < 0.0001f; } } diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index c3b07bd41..085f42c48 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -8,6 +8,7 @@ #include #include "common/bit_field.h" #include "common/common_types.h" +#include "common/quaternion.h" #include "common/settings.h" #include "core/frontend/input.h" #include "core/hle/kernel/object.h" @@ -467,6 +468,7 @@ private: Common::Vec3f gyro; Common::Vec3f rotation; std::array orientation; + Common::Quaternion quaternion; }; struct NfcXcdHandle { -- cgit v1.2.3 From cfdec68d5a8001453fbd49e9677f00ea3dfa9bcb Mon Sep 17 00:00:00 2001 From: german77 Date: Mon, 26 Apr 2021 22:07:16 -0500 Subject: address comments --- src/core/hle/service/hid/controllers/console_sixaxis.cpp | 6 +++--- src/core/hle/service/hid/controllers/console_sixaxis.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/core/hle/service/hid/controllers') diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.cpp b/src/core/hle/service/hid/controllers/console_sixaxis.cpp index 801e14b79..913768fab 100644 --- a/src/core/hle/service/hid/controllers/console_sixaxis.cpp +++ b/src/core/hle/service/hid/controllers/console_sixaxis.cpp @@ -77,10 +77,10 @@ void Controller_ConsoleSixAxis::OnLoadInputDevices() { Input::CreateDevice); } -void Controller_ConsoleSixAxis::SetTransferMemoryPointer(u8* t_mem_1) { +void Controller_ConsoleSixAxis::SetTransferMemoryPointer(u8* t_mem) { is_transfer_memory_set = true; - transfer_memory = t_mem_1; -}; + transfer_memory = t_mem; +} void Controller_ConsoleSixAxis::ResetTimestamp() { auto& cur_entry = seven_six_axis.sevensixaxis_states[seven_six_axis.header.last_entry_index]; diff --git a/src/core/hle/service/hid/controllers/console_sixaxis.h b/src/core/hle/service/hid/controllers/console_sixaxis.h index ac0501683..1fae98e94 100644 --- a/src/core/hle/service/hid/controllers/console_sixaxis.h +++ b/src/core/hle/service/hid/controllers/console_sixaxis.h @@ -30,7 +30,7 @@ public: void OnLoadInputDevices() override; // Called on InitializeSevenSixAxisSensor - void SetTransferMemoryPointer(u8* t_mem_1); + void SetTransferMemoryPointer(u8* t_mem); // Called on ResetSevenSixAxisSensorTimestamp void ResetTimestamp(); @@ -71,8 +71,8 @@ private: using MotionArray = std::array, Settings::NativeMotion::NUM_MOTIONS_HID>; - u8* transfer_memory; MotionArray motions; + u8* transfer_memory = nullptr; bool is_transfer_memory_set = false; ConsoleSharedMemory console_six_axis{}; SevenSixAxisMemory seven_six_axis{}; -- cgit v1.2.3