diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hid/emulated_controller.cpp | 89 |
1 files changed, 81 insertions, 8 deletions
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp index bd2384515..049602e7d 100644 --- a/src/core/hid/emulated_controller.cpp +++ b/src/core/hid/emulated_controller.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "common/thread.h" #include "core/hid/emulated_controller.h" #include "core/hid/input_converter.h" @@ -84,18 +85,19 @@ void EmulatedController::ReloadFromSettings() { motion_params[index] = Common::ParamPackage(player.motions[index]); } + controller.colors_state.fullkey = { + .body = GetNpadColor(player.body_color_left), + .button = GetNpadColor(player.button_color_left), + }; controller.colors_state.left = { - .body = player.body_color_left, - .button = player.button_color_left, + .body = GetNpadColor(player.body_color_left), + .button = GetNpadColor(player.button_color_left), }; - - controller.colors_state.right = { - .body = player.body_color_right, - .button = player.button_color_right, + controller.colors_state.left = { + .body = GetNpadColor(player.body_color_right), + .button = GetNpadColor(player.button_color_right), }; - controller.colors_state.fullkey = controller.colors_state.left; - // Other or debug controller should always be a pro controller if (npad_id_type != NpadIdType::Other) { SetNpadStyleIndex(MapSettingsTypeToNPad(player.controller_type)); @@ -126,10 +128,14 @@ void EmulatedController::LoadDevices() { battery_params[LeftIndex].Set("battery", true); battery_params[RightIndex].Set("battery", true); + camera_params = Common::ParamPackage{"engine:camera,camera:1"}; + output_params[LeftIndex] = left_joycon; output_params[RightIndex] = right_joycon; + output_params[2] = camera_params; output_params[LeftIndex].Set("output", true); output_params[RightIndex].Set("output", true); + output_params[2].Set("output", true); LoadTASParams(); @@ -146,6 +152,7 @@ void EmulatedController::LoadDevices() { Common::Input::CreateDevice<Common::Input::InputDevice>); std::transform(battery_params.begin(), battery_params.end(), battery_devices.begin(), Common::Input::CreateDevice<Common::Input::InputDevice>); + camera_devices = Common::Input::CreateDevice<Common::Input::InputDevice>(camera_params); std::transform(output_params.begin(), output_params.end(), output_devices.begin(), Common::Input::CreateDevice<Common::Input::OutputDevice>); @@ -267,6 +274,14 @@ void EmulatedController::ReloadInput() { motion_devices[index]->ForceUpdate(); } + if (camera_devices) { + camera_devices->SetCallback({ + .on_change = + [this](const Common::Input::CallbackStatus& callback) { SetCamera(callback); }, + }); + camera_devices->ForceUpdate(); + } + // Use a common UUID for TAS static constexpr Common::UUID TAS_UUID = Common::UUID{ {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7, 0xA5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}}; @@ -851,6 +866,25 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac TriggerOnChange(ControllerTriggerType::Battery, true); } +void EmulatedController::SetCamera(const Common::Input::CallbackStatus& callback) { + std::unique_lock lock{mutex}; + controller.camera_values = TransformToCamera(callback); + + if (is_configuring) { + lock.unlock(); + TriggerOnChange(ControllerTriggerType::IrSensor, false); + return; + } + + controller.camera_state.sample++; + controller.camera_state.format = + static_cast<Core::IrSensor::ImageTransferProcessorFormat>(controller.camera_values.format); + controller.camera_state.data = controller.camera_values.data; + + lock.unlock(); + TriggerOnChange(ControllerTriggerType::IrSensor, true); +} + bool EmulatedController::SetVibration(std::size_t device_index, VibrationValue vibration) { if (device_index >= output_devices.size()) { return false; @@ -917,6 +951,9 @@ bool EmulatedController::TestVibration(std::size_t device_index) { // Send a slight vibration to test for rumble support output_devices[device_index]->SetVibration(test_vibration); + // Wait for about 15ms to ensure the controller is ready for the stop command + std::this_thread::sleep_for(std::chrono::milliseconds(15)); + // Stop any vibration and return the result return output_devices[device_index]->SetVibration(zero_vibration) == Common::Input::VibrationError::None; @@ -928,6 +965,23 @@ bool EmulatedController::SetPollingMode(Common::Input::PollingMode polling_mode) return output_device->SetPollingMode(polling_mode) == Common::Input::PollingError::None; } +bool EmulatedController::SetCameraFormat( + Core::IrSensor::ImageTransferProcessorFormat camera_format) { + LOG_INFO(Service_HID, "Set camera format {}", camera_format); + + auto& right_output_device = output_devices[static_cast<std::size_t>(DeviceIndex::Right)]; + auto& camera_output_device = output_devices[2]; + + if (right_output_device->SetCameraFormat(static_cast<Common::Input::CameraFormat>( + camera_format)) == Common::Input::CameraError::None) { + return true; + } + + // Fallback to Qt camera if native device doesn't have support + return camera_output_device->SetCameraFormat(static_cast<Common::Input::CameraFormat>( + camera_format)) == Common::Input::CameraError::None; +} + void EmulatedController::SetLedPattern() { for (auto& device : output_devices) { if (!device) { @@ -1163,6 +1217,11 @@ BatteryValues EmulatedController::GetBatteryValues() const { return controller.battery_values; } +CameraValues EmulatedController::GetCameraValues() const { + std::scoped_lock lock{mutex}; + return controller.camera_values; +} + HomeButtonState EmulatedController::GetHomeButtons() const { std::scoped_lock lock{mutex}; if (is_configuring) { @@ -1251,6 +1310,20 @@ BatteryLevelState EmulatedController::GetBattery() const { return controller.battery_state; } +const CameraState& EmulatedController::GetCamera() const { + std::scoped_lock lock{mutex}; + return controller.camera_state; +} + +NpadColor EmulatedController::GetNpadColor(u32 color) { + return { + .r = static_cast<u8>((color >> 16) & 0xFF), + .g = static_cast<u8>((color >> 8) & 0xFF), + .b = static_cast<u8>(color & 0xFF), + .a = 0xff, + }; +} + void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_npad_service_update) { std::scoped_lock lock{callback_mutex}; for (const auto& poller_pair : callback_list) { |