bevyengine / bevy

A refreshingly simple data-driven game engine built in Rust
https://bevyengine.org
Apache License 2.0
35.95k stars 3.55k forks source link

Switch Joy-Con (Left / Right) support on macOS #6269

Open terhechte opened 2 years ago

terhechte commented 2 years ago

Bevy version

6b75589e2c91429eb6c35574840d47d39b2379b9

[Optional] Relevant system information

macOS 12.6

What you did

When I connect a single Switch Joy-Con (either left or right) to my Mac via bluetooth the D-Pad (left right up down) is not being registered. E.g. moving it doesn't generate any events in Bevy. The buttons (a, b, x, y) work fine.

What went wrong

I tracked the issue down to two places:

When I use my gilrs fork and when I change the bevy_gilrs/converter.rs locally to:

        gilrs::Axis::DPadX => Some(GamepadAxisType::LeftStickX),
        gilrs::Axis::DPadY => Some(GamepadAxisType::LeftStickY),
        // The `axis_dpad_to_button` gilrs filter should filter out all DPadX and DPadY events. If
        // it doesn't then we probably need an entry added to the following repo and an update to
        // GilRs to use the updated database: https://github.com/gabomdq/SDL_GameControllerDB
        gilrs::Axis::Unknown => None,

Then I get the correct events and I can use my Joy-Con's for controlling a Bevy game. However I don't have enough knowledge about this code to know why the filter for D-Pad events existed in the first place. I'll happily create a PR with these changes if somebody who understands this can confirm that this is indeed a useful solution.

mockersf commented 2 years ago

DPadX and DPadY were removed in https://github.com/bevyengine/bevy/pull/5220

You should receive events for DPadUp / DPad... instead

rparrett commented 1 year ago

Just checking on the current state of this. I tested JoyCon on macOS with bevy main and gamepad_input_events.

If I connect one JoyCon at a time, I get some events, but the mapping doesn't seem to make sense with any controller orientation.

If I connect the matching JoyCon, I see a connection event for that particular JoyCon, but afterwards I get no events at all when pressing buttons. (This behavior is the same in gilrs master branch)

Testing with L JoyCon button event
up GamepadButtonChangedEvent { gamepad: Gamepad { id: 0 }, button_type: North, value: 1.0 }
left GamepadButtonChangedEvent { gamepad: Gamepad { id: 0 }, button_type: South, value: 1.0 }
down GamepadButtonChangedEvent { gamepad: Gamepad { id: 0 }, button_type: East, value: 1.0 }
right GamepadButtonChangedEvent { gamepad: Gamepad { id: 0 }, button_type: West, value: 1.0 }
L1 GamepadButtonChangedEvent { gamepad: Gamepad { id: 0 }, button_type: DPadRight, value: 1.0 }
L2 GamepadButtonChangedEvent { gamepad: Gamepad { id: 0 }, button_type: C, value: 1.0 }
stick (press) GamepadButtonChangedEvent { gamepad: Gamepad { id: 0 }, button_type: Mode, value: 1.0 }
stick Nothing
- GamepadButtonChangedEvent { gamepad: Gamepad { id: 0 }, button_type: Start, value: 1.0 }
Home GamepadButtonChangedEvent { gamepad: Gamepad { id: 0 }, button_type: DPadLeft, value: 1.0 }
SL GamepadButtonChangedEvent { gamepad: Gamepad { id: 0 }, button_type: LeftTrigger, value: 1.0 }
SR GamepadButtonChangedEvent { gamepad: Gamepad { id: 0 }, button_type: RightTrigger, value: 1.0 }
Testing with R JoyCon button event
X GamepadButtonChangedEvent { gamepad: Gamepad { id: 3 }, button_type: East, value: 1.0 }
Y GamepadButtonChangedEvent { gamepad: Gamepad { id: 3 }, button_type: West, value: 1.0 }
B GamepadButtonChangedEvent { gamepad: Gamepad { id: 3 }, button_type: North, value: 1.0 }
A GamepadButtonChangedEvent { gamepad: Gamepad { id: 3 }, button_type: South, value: 1.0 }
R1 GamepadButtonChangedEvent { gamepad: Gamepad { id: 3 }, button_type: DPadRight, value: 1.0 }
R2 GamepadButtonChangedEvent { gamepad: Gamepad { id: 3 }, button_type: C, value: 1.0 }
stick(press) GamepadButtonChangedEvent { gamepad: Gamepad { id: 3 }, button_type: DPadUp, value: 1.0 }
stick Nothing
+ GamepadButtonChangedEvent { gamepad: Gamepad { id: 3 }, button_type: Select, value: 1.0 }
Home GamepadButtonChangedEvent { gamepad: Gamepad { id: 3 }, button_type: DPadDown, value: 1.0 }
SL GamepadButtonChangedEvent { gamepad: Gamepad { id: 3 }, button_type: LeftTrigger, value: 1.0 }
SR GamepadButtonChangedEvent { gamepad: Gamepad { id: 3 }, button_type: RightTrigger, value: 1.0 }

I didn't test as thoroughly on the gilrs master branch, but moving sticks there results in dpad events like:

Event { id: GamepadId(0), event: AxisChanged(DPadX, 1.0, Code(EvCode(EvCode { page: 1, usage: 57 }))), time: SystemTime { tv_sec: 1674092067, tv_nsec: 727176000 } }

and the mapping for directional buttons seems similar.

rparrett commented 1 year ago

I don't know if I am going to keep working on this, so to summarize my findings: