Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Binding analog triggers as "fire" button triggers 2+ times per press #5175

Open
nyanpasu64 opened this issue Oct 5, 2024 · 0 comments
Open

Comments

@nyanpasu64
Copy link

Description

When I bind "fire" to an analog trigger of a Xbox 360 controller, the item triggers twice when I press the trigger from top to bottom once.

Steps to reproduce

  • Plug a Xbox 360 controller into a computer.
  • In STK's gamepad mapping, double-click Fire and press the left trigger. This binds firing to "Left trigger (-+)".
  • Start a time trial (which gives you 3 boosts), and try pressing the left trigger gradually to use a single boost.
    • For debugging purposes, you can get a better idea of what's happening by binding "Look Back" to left trigger.

One boost appears when the trigger is pressed around 20%, and another at around 75%. A third boost is used when the left trigger is released to 20%.

This problem does not happen if you half-press the left trigger before binding, so the screen says "Left trigger" without the (-+). But this is an unintuitive thing to do.

Semi-related: #4674

A detour to Dolphin input

Looking in the forums I've found https://forum.freegamedev.net/viewtopic.php?f=17&t=11656&p=84946&hilit=360+analog#p84946, which seems related. However it seems the option has been since renamed to --gamepad-visuals.

It appears that on Linux, STK sees the 360's analog triggers as signed/offset numbers rather than an absolute value. On Dolphin, when I bind the 360's analog trigger, it binds "Full Axis 2+/5+" and behaves as expected, whereas if I half-press the trigger before binding, it reports "Axis 2+/5+" and only starts triggering once the trigger reaches the halfway point.

Dolphin's code is located at https://github.com/dolphin-emu/dolphin/blob/2d9f789940aba806f75cd329905253c05577d837/Source/Core/InputCommon/ControllerInterface/CoreDevice.h#L92, and you can Ctrl-F for FullAnalogSurface. There's a long comment at virtual ControlState GetState() which implies that input mapping is quite janky. Dolphin apparently splits all axes (like sticks and triggers) into positive and negative parts (Axis 2+ triggers when pressing > 50%, and Axis 2- triggers when releasing < 50%), and reconstitutes these parts into an "unsigned value" (Full Axis 2+ = (max(0, Axis 2+) - max(0, Axis 2-) + 1) / 2 = 50% + signed Axis 2, Full Axis 2+ = (max(0, Axis 2-) - max(0, Axis 2+) + 1) / 2 = 50% - signed Axis 2, source code).

I'm not sure how Dolphin determines whether to use a regular or full axis when you press a stick/trigger.


How would this translate to STK?

  • Idea: The input options should highlight digital/analog items whenever the corresponding button is pressed (just like Dolphin). This would make bad configurations more obvious to the user.
  • Currently STK currently treats any amount of analog input as mapping to a digital input. If I bind "fire" to right stick movements, even the smallest movement (outside the deadzone? idk) causes the item to be used.
    • Oddly, if I bind left trigger to "look back", it triggers at every point in its movement except the resting position (full negative) and halfway (zero). This is why pressing and releasing it uses the item 3 times (it transitions 3 times from unpressed to pressed).
  • Binding "fire" to "Left trigger" (Axis 2+) works as "expected" because this analog value is ≤ 0 (IDK your internal representation) until the trigger is pressed over halfway, at which point you instantly fire as soon as the trigger is pressed above zero.
    • Binding "fire" to the upper half of the trigger's movement range shows the raw name "Axis 2-" like Dolphin.
  • Seems your gamepad code is located at
    { SDL_CONTROLLER_AXIS_TRIGGERLEFT_UP, _("Left trigger") },
    , I've found strings for "Left trigger" and " (-+)" and " (+-)", though this just prints actions and doesn't record them. If you're interested I can look further into the code behind input handling.

Configuration

STK release version: 1.4

STK Source (PPA, distribution package, official binary, etc.): Flathub

System: Arch Linux???

Graphics card: AMD Radeon RX 570 Series

CPU: AMD Ryzen 5 5600X 6-Core Processor

Gamepads/keyboards models if related to the issue: Xbox 360 wired USB

Additional information

stdout.log: stdout.log.txt

input.xml:

<input version="1">

<!--
Event 1 : Keyboard button press
    'id' indicates which button, as defined by irrlicht's EKEY_CODE enum
Event 2 : Gamepad stick motion
    'id' indicates which stick, starting from 0
    'direction' 0 means negative, 1 means positive
Event 3 : Gamepad button press
    'id' indicates which button, starting from 0
-->

<keyboard enabled="true" configName="">
     <action name="steerLeft" event="1" id="37" />
    <action name="steerRight" event="1" id="39" />
    <action name="accel" event="1" id="38" />
    <action name="brake" event="1" id="40" />
    <action name="nitro" event="1" id="70" />
    <action name="drift" event="1" id="68" />
    <action name="rescue" event="1" id="8" />
    <action name="fire" event="1" id="32" />
    <action name="lookBack" event="1" id="83" />
    <action name="pauserace" event="1" id="27" />
    <action name="menuUp" event="1" id="38" />
    <action name="menuDown" event="1" id="40" />
    <action name="menuLeft" event="1" id="37" />
    <action name="menuRight" event="1" id="39" />
    <action name="menuSelect" event="1" id="13" />
    <action name="menuCancel" event="1" id="27" />
</keyboard>

<gamepad name ="Xbox 360 Controller" deadzone="4096" desensitize="0" auto-center="20" force-feedback="1" enabled="true" configName="">
     <action name="steerLeft" event="2" id="0" direction="0" range="0" />
    <action name="steerRight" event="2" id="0" direction="1" range="0" />
    <action name="accel" event="3" id="0" />
    <action name="brake" event="3" id="2" />
    <action name="nitro" event="3" id="9" />
    <action name="drift" event="2" id="5" direction="1" range="1" />
    <action name="rescue" event="3" id="6" />
    <action name="fire" event="2" id="2" direction="1" range="1" />
    <action name="lookBack" event="3" id="1" />
    <action name="pauserace" event="3" id="7" />
    <action name="menuUp" event="2" id="1" direction="0" range="0" />
    <action name="menuDown" event="2" id="1" direction="1" range="0" />
    <action name="menuLeft" event="2" id="0" direction="0" range="0" />
    <action name="menuRight" event="2" id="0" direction="1" range="0" />
    <action name="menuSelect" event="3" id="0" />
    <action name="menuCancel" event="3" id="1" />
</gamepad>

</input>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant