mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-07-21 05:09:34 -06:00
InputCommon/WiimoteController: Add inputs that report the raw IR objects seen by the Wiimote.
This commit is contained in:
@ -201,6 +201,17 @@ Device::Device(std::unique_ptr<WiimoteReal::Wiimote> wiimote) : m_wiimote(std::m
|
|||||||
|
|
||||||
AddInput(new UndetectableAnalogInput<float>(&m_ir_state.distance, "IR Distance", 1));
|
AddInput(new UndetectableAnalogInput<float>(&m_ir_state.distance, "IR Distance", 1));
|
||||||
|
|
||||||
|
// Raw IR Objects.
|
||||||
|
for (std::size_t i = 0; i < 4; ++i)
|
||||||
|
{
|
||||||
|
AddInput(new UndetectableAnalogInput<float>(&m_ir_state.raw_ir_object_position[i].x,
|
||||||
|
fmt::format("IR Object {} X", i + 1), 1));
|
||||||
|
AddInput(new UndetectableAnalogInput<float>(&m_ir_state.raw_ir_object_position[i].y,
|
||||||
|
fmt::format("IR Object {} Y", i + 1), 1));
|
||||||
|
AddInput(new UndetectableAnalogInput<float>(&m_ir_state.raw_ir_object_size[i],
|
||||||
|
fmt::format("IR Object {} Size", i + 1), 1));
|
||||||
|
}
|
||||||
|
|
||||||
// Raw gyroscope.
|
// Raw gyroscope.
|
||||||
static constexpr std::array<std::array<const char*, 2>, 3> gyro_names = {{
|
static constexpr std::array<std::array<const char*, 2>, 3> gyro_names = {{
|
||||||
{"Gyro Pitch Down", "Gyro Pitch Up"},
|
{"Gyro Pitch Down", "Gyro Pitch Up"},
|
||||||
@ -1178,8 +1189,7 @@ void Device::ProcessInputReport(WiimoteReal::Report& report)
|
|||||||
// Process IR data.
|
// Process IR data.
|
||||||
if (manipulator->HasIR() && m_ir_state.IsFullyConfigured())
|
if (manipulator->HasIR() && m_ir_state.IsFullyConfigured())
|
||||||
{
|
{
|
||||||
m_ir_state.ProcessData(
|
m_ir_state.ProcessData(*manipulator);
|
||||||
Common::BitCastPtr<std::array<WiimoteEmu::IRBasic, 2>>(manipulator->GetIRDataPtr()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process extension data.
|
// Process extension data.
|
||||||
@ -1251,7 +1261,7 @@ void Device::UpdateOrientation()
|
|||||||
float(MathUtil::PI);
|
float(MathUtil::PI);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::IRState::ProcessData(const std::array<WiimoteEmu::IRBasic, 2>& data)
|
void Device::IRState::ProcessData(const DataReportManipulator& manipulator)
|
||||||
{
|
{
|
||||||
// A better implementation might extrapolate points when they fall out of camera view.
|
// A better implementation might extrapolate points when they fall out of camera view.
|
||||||
// But just averaging visible points actually seems to work very well.
|
// But just averaging visible points actually seems to work very well.
|
||||||
@ -1263,18 +1273,54 @@ void Device::IRState::ProcessData(const std::array<WiimoteEmu::IRBasic, 2>& data
|
|||||||
const auto camera_max = IRObject(WiimoteEmu::CameraLogic::CAMERA_RES_X - 1,
|
const auto camera_max = IRObject(WiimoteEmu::CameraLogic::CAMERA_RES_X - 1,
|
||||||
WiimoteEmu::CameraLogic::CAMERA_RES_Y - 1);
|
WiimoteEmu::CameraLogic::CAMERA_RES_Y - 1);
|
||||||
|
|
||||||
const auto add_point = [&](IRObject point) {
|
const auto add_point = [&](IRObject point, u8 size, size_t idx) {
|
||||||
// Non-visible points are 0xFF-filled.
|
// Non-visible points are 0xFF-filled.
|
||||||
if (point.y > camera_max.y)
|
if (point.y > camera_max.y)
|
||||||
|
{
|
||||||
|
raw_ir_object_position[idx].x = 0.0f;
|
||||||
|
raw_ir_object_position[idx].y = 0.0f;
|
||||||
|
raw_ir_object_size[idx] = 0.0f;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
raw_ir_object_position[idx].x = static_cast<float>(point.x) / camera_max.x;
|
||||||
|
raw_ir_object_position[idx].y = static_cast<float>(point.y) / camera_max.y;
|
||||||
|
raw_ir_object_size[idx] = static_cast<float>(size) / 15.0f;
|
||||||
|
|
||||||
points.Push(Common::Vec2(point));
|
points.Push(Common::Vec2(point));
|
||||||
};
|
};
|
||||||
|
|
||||||
for (auto& block : data)
|
size_t object_index = 0;
|
||||||
|
switch (manipulator.GetIRReportFormat())
|
||||||
{
|
{
|
||||||
add_point(block.GetObject1());
|
case IRReportFormat::Basic:
|
||||||
add_point(block.GetObject2());
|
{
|
||||||
|
const std::array<WiimoteEmu::IRBasic, 2> data =
|
||||||
|
Common::BitCastPtr<std::array<WiimoteEmu::IRBasic, 2>>(manipulator.GetIRDataPtr());
|
||||||
|
for (const auto& block : data)
|
||||||
|
{
|
||||||
|
// size is not reported by IRBasic, just assume a typical size
|
||||||
|
add_point(block.GetObject1(), 2, object_index);
|
||||||
|
++object_index;
|
||||||
|
add_point(block.GetObject2(), 2, object_index);
|
||||||
|
++object_index;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IRReportFormat::Extended:
|
||||||
|
{
|
||||||
|
const std::array<WiimoteEmu::IRExtended, 4> data =
|
||||||
|
Common::BitCastPtr<std::array<WiimoteEmu::IRExtended, 4>>(manipulator.GetIRDataPtr());
|
||||||
|
for (const auto& object : data)
|
||||||
|
{
|
||||||
|
add_point(object.GetPosition(), object.size, object_index);
|
||||||
|
++object_index;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
// unsupported format
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
is_hidden = !points.Count();
|
is_hidden = !points.Count();
|
||||||
|
@ -126,7 +126,7 @@ private:
|
|||||||
{
|
{
|
||||||
static u32 GetDesiredIRSensitivity();
|
static u32 GetDesiredIRSensitivity();
|
||||||
|
|
||||||
void ProcessData(const std::array<WiimoteEmu::IRBasic, 2>&);
|
void ProcessData(const DataReportManipulator& manipulator);
|
||||||
bool IsFullyConfigured() const;
|
bool IsFullyConfigured() const;
|
||||||
|
|
||||||
u32 current_sensitivity = u32(-1);
|
u32 current_sensitivity = u32(-1);
|
||||||
@ -139,6 +139,9 @@ private:
|
|||||||
float distance = 0;
|
float distance = 0;
|
||||||
|
|
||||||
bool is_hidden = true;
|
bool is_hidden = true;
|
||||||
|
|
||||||
|
std::array<Common::Vec2, 4> raw_ir_object_position;
|
||||||
|
std::array<float, 4> raw_ir_object_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ReportHandler
|
class ReportHandler
|
||||||
|
Reference in New Issue
Block a user