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

Time out controller mapping read events #3241

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

MarkMendell
Copy link

@MarkMendell MarkMendell commented Jun 30, 2017

(#1773) Gamecube controller (via mayflash adapter) shoulder buttons have axis sensitivity such that halfway pressed = 0, towards fully pressed = positive, and towards unpressed = negative. When mapping controller inputs, on an input event, readingEvent is set so that duplicate axis events are ignored. This is reset when the corresponding 'Off' axis event happens (null direction). However, the resting state of the gamecube shoulder button is not null. Thus, readingEvent will be stuck as the shoulder release event, and all future events are ignored.

This change ignores read events that happened more than 100 milliseconds ago (arbitrary number) on a different event (e.g. different axis or button press). It does this by recording the time of the last read event.

@MarkMendell MarkMendell changed the title Fix #1773: Time out controller mapping read events Time out controller mapping read events Jun 30, 2017
@clobber
Copy link
Member

clobber commented Jun 30, 2017

Okay, so does it also fix the shoulder buttons in-game? You said that the "axis null direction" event is never received in Preferences, which leads me to think the shoulders can be mapped with your solution but still won't work in-game, e.g., with an SNES game shoulders as the events received here are the same a game receives. That would mean this is incomplete and needs a solution at the device handler level. Possibly needing to expose a way to adjust deadzones from the UI, if that solves it at all.

Can you verify your solution also allows the shoulders to work in-game?

One other thing, instead of CFAbsoluteTime/CFAbsoluteTimeGetCurrent you should be using mach_absolute_time. Like NSDate, CFAbsoluteTime is not monotonic and not a good way to measure elapsed time due to various system voodoo, even if it is just 100ms.

If you can address those two points, shoulders working in-game and the timer, then this is probably an okay workaround until we figure out a user-adjustable interface for deadzones that fits cleanly into the UI.

@MarkMendell
Copy link
Author

Okay, so does it also fix the shoulder buttons in-game?

Yes. The slight press 'axis' is registered as the button (or if you press quickly, the full press 'axis').

Can you verify your solution also allows the shoulders to work in-game?

Works for me playing EarthBound.

One other thing, instead of CFAbsoluteTime/CFAbsoluteTimeGetCurrent you should be using mach_absolute_time.

Done. Let me know if I initialized in a bad place. I also found OEMonotonicTime() in OpenEmu-SDK, let me know if it's preferable to include and call this method instead.

[...] until we figure out a user-adjustable interface for deadzones that fits cleanly into the UI.

Good idea. With this specific controller, it would help to have a way to tell OpenEmu to ignore some inputs while mapping - it's impossible to trigger the shoulder 'button' event without going through the 'axis' event. Regardless, OpenEmu is awesome and thank you for all the work you put into it!

@clobber
Copy link
Member

clobber commented Jun 30, 2017

Yes. The slight press 'axis' is registered as the button (or if you press quickly, the full press 'axis').

Just to be clear, do the gamecube controller shoulder/triggers act as both a 'button' AND 'axis' events?

@MarkMendell
Copy link
Author

Yup

@clobber
Copy link
Member

clobber commented Sep 22, 2017

So I bought the Mayflash GameCube Controller Adapter for Wii U & PC with 2 ports in order to test your pull request but am noticing that every time I relaunch the app or unplug/replug the adapter, I can never get input to work in-game again despite my mappings being recognized or after re-mapping controls. I think OE is getting confused with the multiple ports somehow. Can you replicate this with your adapter?

@MarkMendell
Copy link
Author

Yes, I have the same issue. Mapping every port to player one and then replugging the adapter + cycling the controller through the ports each time I start it gets it to work for me eventually (one player only).

From logging the kIOHIDUniqueIDKey for the initial load and button press, It looks like each port gets a player index from the order it gets loaded, and they get loaded in a random order. Unless an HID property can say which port it is, the only solution might be UI saying 'press a button on player 1, player 2 (or skip)‚ ...'. This can be remembered until they reconnect the device (a new kIOHIDUniqueIDKey gets assigned).

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.

None yet

2 participants