Skip to content

Legion Go: DS4 Options/Share mapping fix #2

Description

@nirys91

Hi,

I’m not very experienced with GitHub or programming, so I hope this report is still useful. ChatGPT helped me inspect and understand the code, but I tested the behavior and the fix myself on my Lenovo Legion Go.

My use case was very specific:
I wanted compatctl to make the Legion Go controller behave like a DualShock 4 mainly so that games could show PlayStation button prompts correctly.

The issue I found was with the DS4 menu/special button mapping on Legion Go.

compatctl_fix(.exe).zip

What I experienced:

  • the physical Select/View-side button was effectively behaving like DS4 Options
  • with --enable-share-button, the Start/Menu-side button was being used for Share
  • because of this, the PlayStation-style button behavior felt wrong in games
  • in my case, I noticed it while trying to get proper PlayStation prompts in games like Mina the Hollower

What I did:

  • downloaded the source code
  • built it with cargo build --release
  • inspected src/main.rs
  • changed the button mapping
  • rebuilt and tested the new executable on Legion Go

The mapping that worked correctly for me was:

  • physical Start/Menu -> DS4 Options
  • physical Select/View -> DS4 Share
  • touchpad click disabled for now, to avoid overlap/conflicts

This is the code that worked for me in src/main.rs:

let buttons = DS4Buttons::new()
    .triangle(xstate.north_button())
    .cross(xstate.south_button())
    .circle(xstate.east_button())
    .square(xstate.west_button())
    .dpad(map_dpad_directions(xstate.arrow_up(), xstate.arrow_down(), xstate.arrow_left(), xstate.arrow_right()))
    .options(xstate.start_button())
    .shoulder_left(xstate.left_shoulder())
    .shoulder_right(xstate.right_shoulder())
    .thumb_left(xstate.left_thumb_button())
    .thumb_right(xstate.right_thumb_button())
    .trigger_left(xstate.left_trigger_bool())
    .trigger_right(xstate.right_trigger_bool());

let buttons = if *ENABLE_DS4_SHARE_BUTTON.get().unwrap_or(&false) {
    buttons.share(xstate.select_button())
} else {
    buttons
};

let special_buttons = DS4SpecialButtons::new()
    .touchpad(false)
    .ps_home(xstate.guide_button());

Before this change, the logic around Options / Share / touchpad did not feel correct on Legion Go.

After rebuilding, the modified version worked correctly for my use case.

I am not claiming this is necessarily the perfect universal solution for every game or setup, but I wanted to share it because it may help improve Legion Go support or help other users with the same goal.

Thanks for the project.

If useful, I can also provide the already compiled executable I tested on my Legion Go.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions