From 76eaddc4a82a5a8cd24676f3fc488a1550e2d9fd Mon Sep 17 00:00:00 2001 From: arcattack Date: Thu, 23 Jul 2026 00:55:45 -0500 Subject: [PATCH] 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) --- engine/MUNGA_L4/L4PADBINDINGS.cpp | 9 ++++++++- engine/MUNGA_L4/L4PADBINDINGS.h | 4 ++++ engine/MUNGA_L4/L4PADRIO.cpp | 10 ++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/engine/MUNGA_L4/L4PADBINDINGS.cpp b/engine/MUNGA_L4/L4PADBINDINGS.cpp index a1d910f..c11602e 100644 --- a/engine/MUNGA_L4/L4PADBINDINGS.cpp +++ b/engine/MUNGA_L4/L4PADBINDINGS.cpp @@ -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 axis set jump/detent\n" "# pad button \n" "# padaxis axis [invert] [slew ]\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" diff --git a/engine/MUNGA_L4/L4PADBINDINGS.h b/engine/MUNGA_L4/L4PADBINDINGS.h index cf11b5f..2b7814a 100644 --- a/engine/MUNGA_L4/L4PADBINDINGS.h +++ b/engine/MUNGA_L4/L4PADBINDINGS.h @@ -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 }; diff --git a/engine/MUNGA_L4/L4PADRIO.cpp b/engine/MUNGA_L4/L4PADRIO.cpp index 97b619f..b3d48fd 100644 --- a/engine/MUNGA_L4/L4PADRIO.cpp +++ b/engine/MUNGA_L4/L4PADRIO.cpp @@ -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