Skip to content

Commit 41ce890

Browse files
authored
Merge pull request #471 from XenuIsWatching/feature/ir-passthrough-cher
libretro: add Wiimote IR passthrough
2 parents e0fd6eb + b0cfde9 commit 41ce890

5 files changed

Lines changed: 68 additions & 6 deletions

File tree

Source/Core/DolphinLibretro/Common/Options.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1729,6 +1729,20 @@ static struct retro_core_option_v2_definition option_defs[] = {
17291729
},
17301730
"disabled"
17311731
},
1732+
{
1733+
Libretro::Options::wiimote::IR_PASSTHROUGH,
1734+
"Wiimote IR > Wiimote IR Passthrough",
1735+
"Wiimote IR Passthrough",
1736+
"Take the Wiimote camera's view of the sensor bar straight from the frontend, instead of deriving it from a cursor position. The frontend supplies up to four IR objects on pointer indices 1-4; Wiimote IR Mode, Total Yaw, Total Pitch and Vertical Offset are all bypassed. For frontends that know the real geometry (a VR room, a tracked light gun) this is exact, and it carries roll and distance, which a cursor cannot. Leave off for a mouse or a gamepad.",
1737+
nullptr,
1738+
CATEGORY_WIIMOTE,
1739+
{
1740+
{ "disabled", nullptr },
1741+
{ "enabled", nullptr },
1742+
{ nullptr, nullptr }
1743+
},
1744+
"disabled"
1745+
},
17321746

17331747
#if defined(HAS_OPENGL) && defined(__WEBOS__)
17341748
{

Source/Core/DolphinLibretro/Common/Options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ namespace wiimote {
303303
constexpr const char IR_MODIFIER[] = "dolphin_ir_modifier";
304304
constexpr const char SWING_MODIFIER[] = "dolphin_swing_modifier";
305305
constexpr const char SWING_ANGLE[] = "dolphin_swing_angle";
306+
constexpr const char IR_PASSTHROUGH[] = "dolphin_ir_passthrough";
306307
} // namespace wiimote
307308

308309
// ======================================================

Source/Core/DolphinLibretro/Input.cpp

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "InputCommon/ControlReference/ExpressionParser.h"
3939
#include "InputCommon/ControllerEmu/Control/Control.h"
4040
#include "InputCommon/ControllerEmu/ControlGroup/Attachments.h"
41+
#include "InputCommon/ControllerEmu/ControlGroup/IRPassthrough.h"
4142
#include "InputCommon/ControllerEmu/Setting/NumericSetting.h"
4243
#include "InputCommon/ControllerInterface/ControllerInterface.h"
4344
#include "InputCommon/GCAdapter.h"
@@ -407,11 +408,22 @@ Device::Device(unsigned device, unsigned p) : m_device(device), m_port(p)
407408
AddButton(RETRO_DEVICE_ID_MOUSE_BUTTON_5, "Button5");
408409
return;
409410
case RETRO_DEVICE_POINTER:
410-
AddButton(RETRO_DEVICE_ID_POINTER_PRESSED, "Pressed0", 0);
411-
AddAxis(RETRO_DEVICE_ID_POINTER_X, -0x8000, "X0-", 0);
412-
AddAxis(RETRO_DEVICE_ID_POINTER_X, 0x7FFF, "X0+", 0);
413-
AddAxis(RETRO_DEVICE_ID_POINTER_Y, -0x8000, "Y0-", 0);
414-
AddAxis(RETRO_DEVICE_ID_POINTER_Y, 0x7FFF, "Y0+", 0);
411+
// Four touch indices, one per IR object. Index 0 keeps its old names.
412+
{
413+
static const char* const kPressed[] = { "Pressed0", "Pressed1", "Pressed2", "Pressed3" };
414+
static const char* const kXNeg[] = { "X0-", "X1-", "X2-", "X3-" };
415+
static const char* const kXPos[] = { "X0+", "X1+", "X2+", "X3+" };
416+
static const char* const kYNeg[] = { "Y0-", "Y1-", "Y2-", "Y3-" };
417+
static const char* const kYPos[] = { "Y0+", "Y1+", "Y2+", "Y3+" };
418+
for (unsigned i = 0; i < 4; ++i)
419+
{
420+
AddButton(RETRO_DEVICE_ID_POINTER_PRESSED, kPressed[i], i);
421+
AddAxis(RETRO_DEVICE_ID_POINTER_X, -0x8000, kXNeg[i], i);
422+
AddAxis(RETRO_DEVICE_ID_POINTER_X, 0x7FFF, kXPos[i], i);
423+
AddAxis(RETRO_DEVICE_ID_POINTER_Y, -0x8000, kYNeg[i], i);
424+
AddAxis(RETRO_DEVICE_ID_POINTER_Y, 0x7FFF, kYPos[i], i);
425+
}
426+
}
415427
return;
416428
case RETRO_DEVICE_KEYBOARD:
417429
return;
@@ -946,6 +958,37 @@ void UpdateWiimoteMappings(const WiimoteUpdateFlags& f, unsigned port, unsigned
946958
}
947959
}
948960

961+
// Raw IR: the frontend supplies the camera's view directly, bypassing the
962+
// Point group and Total Yaw/Pitch. Objects arrive on pointer indices 0-3,
963+
// X/Y over the camera's 0..1 field, PRESSED marking the object visible.
964+
// Size is a constant; games only read it to reject noise.
965+
if (f.irPassthrough)
966+
{
967+
auto* wmIRPass = static_cast<ControllerEmu::IRPassthrough*>(
968+
wm->GetWiimoteGroup(WiimoteEmu::WiimoteGroup::IRPassthrough));
969+
const bool passthrough =
970+
Libretro::Options::GetCached<bool>(Libretro::Options::wiimote::IR_PASSTHROUGH);
971+
972+
if (wmIRPass)
973+
{
974+
const std::string devPointer =
975+
Libretro::Input::GetQualifiedName(port, RETRO_DEVICE_POINTER);
976+
wmIRPass->enabled.SetValue(passthrough);
977+
static const char* const kObj[] = { "0", "1", "2", "3" };
978+
for (int i = 0; i < 4; ++i)
979+
{
980+
// Cleared when off; AreInputsBound() is half of what selects this path.
981+
const std::string idx = kObj[i];
982+
wmIRPass->SetControlExpression(i * 3 + 0,
983+
passthrough ? "`" + devPointer + ":X" + idx + "+`" : "");
984+
wmIRPass->SetControlExpression(i * 3 + 1,
985+
passthrough ? "`" + devPointer + ":Y" + idx + "+`" : "");
986+
wmIRPass->SetControlExpression(i * 3 + 2,
987+
passthrough ? "`" + devPointer + ":Pressed" + idx + "` * 0.2" : "");
988+
}
989+
}
990+
}
991+
949992
if (f.swingAngle)
950993
{
951994
ControllerEmu::ControlGroup* wmSwing = wm->GetWiimoteGroup(WiimoteEmu::WiimoteGroup::Swing);
@@ -1516,6 +1559,8 @@ void retro_set_controller_port_device_wii(unsigned port, unsigned device)
15161559
f.irModifier = true;
15171560
f.swingModifier = true;
15181561
f.sideways = true;
1562+
// Raised at setup so the option applies on a cold boot.
1563+
f.irPassthrough = true;
15191564
Libretro::Input::UpdateWiimoteMappings(f, port, device);
15201565

15211566
wmShake->SetControlExpression(0, bindMouse("L2", devMouse + ":Middle")); // Wiimote shake X

Source/Core/DolphinLibretro/Input.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,12 @@ struct WiimoteUpdateFlags
1919
bool sideways = false;
2020
bool rumble = false;
2121
bool gcMicBtn = false;
22+
bool irPassthrough = false;
2223

2324
bool any() const {
2425
return irMode || irOffset || irYaw || irPitch ||
2526
irDeadzone || irModifier || swingModifier ||
26-
swingAngle || sideways || rumble || gcMicBtn;
27+
swingAngle || sideways || rumble || gcMicBtn || irPassthrough;
2728
}
2829
};
2930

Source/Core/DolphinLibretro/Main.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ void retro_run(void)
389389
flags.swingModifier = Libretro::Options::IsUpdated(Libretro::Options::wiimote::SWING_MODIFIER);
390390
flags.swingAngle = Libretro::Options::IsUpdated(Libretro::Options::wiimote::SWING_ANGLE);
391391
flags.sideways = Libretro::Options::IsUpdated(Libretro::Options::wiimote::HOTKEY_SIDEWAYS_TOGGLE);
392+
flags.irPassthrough = Libretro::Options::IsUpdated(Libretro::Options::wiimote::IR_PASSTHROUGH);
392393
}
393394

394395
flags.rumble = Libretro::Options::IsUpdated(Libretro::Options::sysconf::ENABLE_RUMBLE);

0 commit comments

Comments
 (0)