Skip to content

fix(CapabilityMap): use min/max range for unsigned axis normalization#569

Open
honjow wants to merge 3 commits intoShadowBlip:mainfrom
honjow:fix/unsigned-axis-normalization
Open

fix(CapabilityMap): use min/max range for unsigned axis normalization#569
honjow wants to merge 3 commits intoShadowBlip:mainfrom
honjow:fix/unsigned-axis-normalization

Conversation

@honjow
Copy link
Copy Markdown
Contributor

@honjow honjow commented Mar 28, 2026

normalize_unsigned_value was computing value / max, which only works when min is 0. For axes where min is non-zero — such as ADC-based triggers found on some ARM handhelds (e.g. Gameforce Ace, which uses the adc-joystick driver and reports triggers as ABS_HAT2X/ABS_HAT2Y with a range of 890 to 1530) — the values are never correctly scaled to 0.0 to 1.0.

Changed to (value - min) / (max - min) with a .clamp(0.0, 1.0), and updated denormalize_unsigned_value accordingly.

Also adds an inverted field to EvdevConfig (source side). This complements the existing invert option on AxisCapability (target side): the existing one handles Vector2 joystick axes after translation, but there's no way to invert a trigger (Float value) at the source. ADC triggers on some hardware report values in reverse — high at rest, low when pressed — and without this option there's currently no way to handle it in a capability map.

- evdev:
    event_type: ABS
    event_code: ABS_HAT2X
    value_type: trigger
    inverted: true

No behavior change for devices where min is already 0.

- normalize_unsigned_value now accounts for min offset: (value - min) / (max - min)
- denormalize_unsigned_value updated accordingly
- Add `inverted` field to EvdevConfig for capability maps, allowing
  axes with reversed hardware polarity (e.g. ADC triggers) to be
  properly mapped without device tree changes
Copy link
Copy Markdown
Contributor

@pastaq pastaq left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a small bit, everything else looks good.

"maximum": 65535,
"minimum": 0
},
"inverted": {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call this invert as well to keep terms consistent

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's call this invert as well to keep terms consistent

Changes pushed

"maximum": 65535,
"minimum": 0
},
"invert": {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the inversion stuff is particularly necessary. It appears to be redundant with #534. It is also out of scope for fixing the bug with axes not starting at 0. If you think there is a valid case for it please submit that as a separate PR.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I'll remove it

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would inverting triggers in a similar manner as in #534 be acceptable?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After thinking about this, the issue in #532 seems identical to the one I had with triggers, just with stick-axes. #534 only seems to solve the issue for stick-axes, whereas I believe honjow suggestions would solve both cases iiuc. I would need need to test this with loki666 to be sure though.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In either case it's a separate issue so a separate PR is necessary

Remove the invert field added to EvdevConfig as it is out of scope for
the unsigned axis normalization fix and overlaps with existing invert
support in PR ShadowBlip#534.
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

Successfully merging this pull request may close these issues.

3 participants