diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp index b3aab5b486..4c72126f57 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.cpp @@ -49,6 +49,7 @@ #include "InputCommon/ControllerEmu/ControlGroup/IMUAccelerometer.h" #include "InputCommon/ControllerEmu/ControlGroup/IMUCursor.h" #include "InputCommon/ControllerEmu/ControlGroup/IMUGyroscope.h" +#include "InputCommon/ControllerEmu/ControlGroup/IRPassthrough.h" #include "InputCommon/ControllerEmu/ControlGroup/ModifySettingsButton.h" #include "InputCommon/ControllerEmu/ControlGroup/Tilt.h" @@ -250,6 +251,8 @@ Wiimote::Wiimote(const unsigned int index) : m_index(index), m_bt_device_index(i _trans("Camera field of view (affects sensitivity of pointing).")}, fov_default.y, 0.01, 180); + groups.emplace_back(m_ir_passthrough = new ControllerEmu::IRPassthrough( + IR_PASSTHROUGH_GROUP, _trans("Point (Passthrough)"))); groups.emplace_back(m_imu_accelerometer = new ControllerEmu::IMUAccelerometer( ACCELEROMETER_GROUP, _trans("Accelerometer"))); groups.emplace_back(m_imu_gyroscope = @@ -360,6 +363,8 @@ ControllerEmu::ControlGroup* Wiimote::GetWiimoteGroup(WiimoteGroup group) const return m_imu_gyroscope; case WiimoteGroup::IMUPoint: return m_imu_ir; + case WiimoteGroup::IRPassthrough: + return m_ir_passthrough; default: ASSERT(false); return nullptr; @@ -447,6 +452,33 @@ void Wiimote::UpdateButtonsStatus(const DesiredWiimoteState& target_state) m_status.buttons.hex = target_state.buttons.hex & ButtonData::BUTTON_MASK; } +static std::array +GetPassthroughCameraPoints(ControllerEmu::IRPassthrough* ir_passthrough) +{ + std::array camera_points; + for (size_t i = 0; i < camera_points.size(); ++i) + { + const ControlState size = ir_passthrough->GetObjectSize(i); + if (size <= 0.0f) + continue; + + const ControlState x = ir_passthrough->GetObjectPositionX(i); + const ControlState y = ir_passthrough->GetObjectPositionY(i); + + camera_points[i].position.x = + std::clamp(std::lround(x * ControlState(CameraLogic::CAMERA_RES_X - 1)), long(0), + long(CameraLogic::CAMERA_RES_X - 1)); + camera_points[i].position.y = + std::clamp(std::lround(y * ControlState(CameraLogic::CAMERA_RES_Y - 1)), long(0), + long(CameraLogic::CAMERA_RES_Y - 1)); + camera_points[i].size = + std::clamp(std::lround(size * ControlState(CameraLogic::MAX_POINT_SIZE)), long(0), + long(CameraLogic::MAX_POINT_SIZE)); + } + + return camera_points; +} + void Wiimote::BuildDesiredWiimoteState(DesiredWiimoteState* target_state, SensorBarState sensor_bar_state) { @@ -470,7 +502,11 @@ void Wiimote::BuildDesiredWiimoteState(DesiredWiimoteState* target_state, ConvertAccelData(GetTotalAcceleration(), ACCEL_ZERO_G << 2, ACCEL_ONE_G << 2); // Calculate IR camera state. - if (sensor_bar_state == SensorBarState::Enabled) + if (m_ir_passthrough->enabled) + { + target_state->camera_points = GetPassthroughCameraPoints(m_ir_passthrough); + } + else if (sensor_bar_state == SensorBarState::Enabled) { target_state->camera_points = CameraLogic::GetCameraPoints( GetTotalTransformation(), diff --git a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h index f6cfab90d7..e364ccdb6c 100644 --- a/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h +++ b/Source/Core/Core/HW/WiimoteEmu/WiimoteEmu.h @@ -34,6 +34,7 @@ class Force; class IMUAccelerometer; class IMUGyroscope; class IMUCursor; +class IRPassthrough; class ModifySettingsButton; class Output; class Tilt; @@ -59,6 +60,7 @@ enum class WiimoteGroup IMUAccelerometer, IMUGyroscope, IMUPoint, + IRPassthrough, }; enum class NunchukGroup; @@ -121,6 +123,7 @@ public: static constexpr const char* ACCELEROMETER_GROUP = "IMUAccelerometer"; static constexpr const char* GYROSCOPE_GROUP = "IMUGyroscope"; static constexpr const char* IR_GROUP = "IR"; + static constexpr const char* IR_PASSTHROUGH_GROUP = "IRPassthrough"; static constexpr const char* A_BUTTON = "A"; static constexpr const char* B_BUTTON = "B"; @@ -300,6 +303,7 @@ private: ControllerEmu::IMUAccelerometer* m_imu_accelerometer; ControllerEmu::IMUGyroscope* m_imu_gyroscope; ControllerEmu::IMUCursor* m_imu_ir; + ControllerEmu::IRPassthrough* m_ir_passthrough; ControllerEmu::SettingValue m_sideways_setting; ControllerEmu::SettingValue m_upright_setting; diff --git a/Source/Core/DolphinLib.props b/Source/Core/DolphinLib.props index a5039859f9..50a6eb5494 100644 --- a/Source/Core/DolphinLib.props +++ b/Source/Core/DolphinLib.props @@ -504,6 +504,7 @@ + @@ -1162,6 +1163,7 @@ + diff --git a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuMotionControlIMU.cpp b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuMotionControlIMU.cpp index 8d07e9201e..9536b2ef9d 100644 --- a/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuMotionControlIMU.cpp +++ b/Source/Core/DolphinQt/Config/Mapping/WiimoteEmuMotionControlIMU.cpp @@ -48,6 +48,8 @@ void WiimoteEmuMotionControlIMU::CreateMainLayout() auto* groups_layout = new QHBoxLayout(); groups_layout->addWidget( CreateGroupBox(Wiimote::GetWiimoteGroup(GetPort(), WiimoteEmu::WiimoteGroup::IMUPoint))); + groups_layout->addWidget( + CreateGroupBox(Wiimote::GetWiimoteGroup(GetPort(), WiimoteEmu::WiimoteGroup::IRPassthrough))); groups_layout->addWidget(CreateGroupBox( Wiimote::GetWiimoteGroup(GetPort(), WiimoteEmu::WiimoteGroup::IMUAccelerometer))); groups_layout->addWidget( diff --git a/Source/Core/InputCommon/CMakeLists.txt b/Source/Core/InputCommon/CMakeLists.txt index ed19e12b74..dc4da808a1 100644 --- a/Source/Core/InputCommon/CMakeLists.txt +++ b/Source/Core/InputCommon/CMakeLists.txt @@ -37,6 +37,8 @@ add_library(inputcommon ControllerEmu/ControlGroup/IMUCursor.h ControllerEmu/ControlGroup/IMUGyroscope.cpp ControllerEmu/ControlGroup/IMUGyroscope.h + ControllerEmu/ControlGroup/IRPassthrough.cpp + ControllerEmu/ControlGroup/IRPassthrough.h ControllerEmu/ControlGroup/MixedTriggers.cpp ControllerEmu/ControlGroup/MixedTriggers.h ControllerEmu/ControlGroup/ModifySettingsButton.cpp diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.h b/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.h index f51fff6015..bb426e9297 100644 --- a/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.h +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/ControlGroup.h @@ -49,7 +49,8 @@ enum class GroupType Shake, IMUAccelerometer, IMUGyroscope, - IMUCursor + IMUCursor, + IRPassthrough, }; class ControlGroup diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/IRPassthrough.cpp b/Source/Core/InputCommon/ControllerEmu/ControlGroup/IRPassthrough.cpp new file mode 100644 index 0000000000..119f9bcb0e --- /dev/null +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/IRPassthrough.cpp @@ -0,0 +1,51 @@ +// Copyright 2024 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "InputCommon/ControllerEmu/ControlGroup/IRPassthrough.h" + +#include +#include + +#include "Common/Common.h" +#include "Common/MathUtil.h" + +#include "InputCommon/ControlReference/ControlReference.h" +#include "InputCommon/ControllerEmu/Control/Control.h" +#include "InputCommon/ControllerEmu/Control/Input.h" + +namespace ControllerEmu +{ +IRPassthrough::IRPassthrough(std::string name_, std::string ui_name_) + : ControlGroup(std::move(name_), std::move(ui_name_), GroupType::IRPassthrough, + ControlGroup::DefaultValue::Disabled) +{ + AddInput(Translatability::Translate, _trans("Object 1 X")); + AddInput(Translatability::Translate, _trans("Object 1 Y")); + AddInput(Translatability::Translate, _trans("Object 1 Size")); + AddInput(Translatability::Translate, _trans("Object 2 X")); + AddInput(Translatability::Translate, _trans("Object 2 Y")); + AddInput(Translatability::Translate, _trans("Object 2 Size")); + AddInput(Translatability::Translate, _trans("Object 3 X")); + AddInput(Translatability::Translate, _trans("Object 3 Y")); + AddInput(Translatability::Translate, _trans("Object 3 Size")); + AddInput(Translatability::Translate, _trans("Object 4 X")); + AddInput(Translatability::Translate, _trans("Object 4 Y")); + AddInput(Translatability::Translate, _trans("Object 4 Size")); +} + +ControlState IRPassthrough::GetObjectPositionX(size_t object_index) const +{ + return controls[object_index * 3 + 0]->GetState(); +} + +ControlState IRPassthrough::GetObjectPositionY(size_t object_index) const +{ + return controls[object_index * 3 + 1]->GetState(); +} + +ControlState IRPassthrough::GetObjectSize(size_t object_index) const +{ + return controls[object_index * 3 + 2]->GetState(); +} + +} // namespace ControllerEmu diff --git a/Source/Core/InputCommon/ControllerEmu/ControlGroup/IRPassthrough.h b/Source/Core/InputCommon/ControllerEmu/ControlGroup/IRPassthrough.h new file mode 100644 index 0000000000..9e6bf9b5bb --- /dev/null +++ b/Source/Core/InputCommon/ControllerEmu/ControlGroup/IRPassthrough.h @@ -0,0 +1,23 @@ +// Copyright 2024 Dolphin Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "InputCommon/ControllerEmu/ControlGroup/ControlGroup.h" +#include "InputCommon/ControllerEmu/Setting/NumericSetting.h" +#include "InputCommon/ControllerInterface/CoreDevice.h" + +namespace ControllerEmu +{ +class IRPassthrough : public ControlGroup +{ +public: + IRPassthrough(std::string name, std::string ui_name); + + ControlState GetObjectPositionX(size_t object_index) const; + ControlState GetObjectPositionY(size_t object_index) const; + ControlState GetObjectSize(size_t object_index) const; +}; +} // namespace ControllerEmu