Issue #25: composite Turn channel -- twin-stick gamepad turning

Gamepad players expect stick X = turn; the pod-faithful default maps it
to torso twist, and the pedal pair couldn't take a single signed axis.
New bindings channel "Turn": a signed composite that decomposes into
the pedal pair at the RIO publish (+ = right pedal, - = left), ADDING
to direct pedal bindings so mixed rigs compose, clamped 0..1 per pedal.
The default bindings.txt stays pod-faithful and documents the
twin-stick alternative inline:

    padaxis LX axis Turn
    padaxis RX axis JoystickX

Also covers the HOTAS ask (any signed axis can now drive turning).
Verified: regenerated defaults carry the doc lines; a twin-stick-edited
bindings.txt parses and boots clean.  Awaiting live pad verification.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-23 00:55:45 -05:00
co-authored by Claude Opus 4.8
parent 4e0fcbf328
commit 76eaddc4a8
3 changed files with 22 additions and 1 deletions
+8 -1
View File
@@ -98,6 +98,7 @@ static const NamedValue channelNames[] =
{ "JoystickY", PadBindingProfile::ChannelJoystickY },
{ "LeftPedal", PadBindingProfile::ChannelLeftPedal },
{ "RightPedal", PadBindingProfile::ChannelRightPedal },
{ "Turn", PadBindingProfile::ChannelTurn }, // issue #25 composite
};
static int
@@ -166,7 +167,9 @@ static const char *defaultProfileText =
"# key <KEYNAME> axis <channel> set <value> jump/detent\n"
"# pad <PADBTN> button <addr>\n"
"# padaxis <PADAXIS> axis <channel> [invert] [slew <rate>]\n"
"# Channels: Throttle JoystickX JoystickY LeftPedal RightPedal\n"
"# Channels: Throttle JoystickX JoystickY LeftPedal RightPedal Turn\n"
"# (Turn = signed composite: + drives the right pedal, - the left --\n"
"# made for mapping a gamepad stick to turning)\n"
"# Pad buttons: A B X Y LB RB BACK START LS RS DPAD_* Axes: LX LY RX RY LT RT\n"
"#\n"
"# LAYOUT: the keyboard hosts the core gameplay actions on the desktop\n"
@@ -231,6 +234,10 @@ static const char *defaultProfileText =
"key F9 button 0x22\n"
"\n"
"# --- XInput pad ---\n"
"# POD-FAITHFUL (default): stick X = torso twist, triggers = pedals.\n"
"# TWIN-STICK alternative: replace the LX line with the two below --\n"
"# padaxis LX axis Turn\n"
"# padaxis RX axis JoystickX\n"
"padaxis LX axis JoystickX\n"
"padaxis LY axis JoystickY invert\n"
"padaxis LT axis LeftPedal\n"
+4
View File
@@ -36,6 +36,10 @@ public:
ChannelJoystickY,
ChannelLeftPedal,
ChannelRightPedal,
// issue #25: composite -- a SIGNED axis that decomposes into the
// pedal pair (positive = right pedal, negative = left pedal) so a
// gamepad stick can drive the turn ("twin-stick" profile).
ChannelTurn,
ChannelCount
};
+10
View File
@@ -740,6 +740,16 @@ void
channelValue[PadBindingProfile::ChannelJoystickY]);
LeftPedal = (Scalar)channelValue[PadBindingProfile::ChannelLeftPedal];
RightPedal = (Scalar)channelValue[PadBindingProfile::ChannelRightPedal];
// issue #25: the composite Turn channel decomposes into the pedal pair
// (signed: + = right, - = left); it ADDS to any direct pedal bindings so
// mixed rigs (stick turn + trigger pedals) compose.
{
float turn = channelValue[PadBindingProfile::ChannelTurn];
if (turn > 0.0f) RightPedal += (Scalar)turn;
else if (turn < 0.0f) LeftPedal += (Scalar)(-turn);
if (LeftPedal > 1.0f) LeftPedal = 1.0f;
if (RightPedal > 1.0f) RightPedal = 1.0f;
}
//
// The analog heartbeat: tells the manager to run the five-scalar