-
-
Notifications
You must be signed in to change notification settings - Fork 158
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
Port the controller module to C. #2056
Conversation
Unit tests failing because the ubuntu 20.04 build uses SDL 2.0.10, which doesn't have SDL_strtokr. Try using strtok_r instead, our compilers probably all support it? Other fail is about the stubs of Controller |
Notes for self, review:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. The testing code works well with my aged 360 controller - including hot plugging. Possibly we could refine the final design of the module/class a little more but the main thing is to get it converted to C so that process becomes easier to tackle.
I think the current proposed changes to the cython version all make sense - but I agree we should take a pass at the documentation before the module (pygame.controller
I assume) reaches it's final form.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I don't have the hardware to test out these changes, I have gone through the code and found nothing questionable.
This change LGTM and should probably go in before the next dev release, so I'm approving. Thanks for the PR 🎉
@zoldalma999 Once the merge conflicts are fixed, I'm willing to give this a final test with several controllers I own to make sure it works properly, and then merge it when all things look good. If you'd like, I can fix the merge conflicts and push to your branch |
Sorry to come up with this so late, but I’m not sure the “port to C PR” and the “change a couple APIs” PR should be the same PR. I’d be happier with this PR if it was a drop in replacement. |
I'd appreciate that. I'll message you whenever it is ready.
The changes to the API are more like removes, apart from "Controller.get_axis returns in the range of -1 to 1 now". I can change it to be like the cython version, and add functions that will be removed in a later pr anyway, but it made sense for me to just not add those functions. |
Thanks for pointing that out. I'd like it if you changed that to be like the Cython version, then that change can be evaluated independently. |
Looking at the fails I'm guessing this needs to make some modifications to the meson build now:
|
With my nintendo switch joycons, I get a segfault on Windows 11 when I reach this line in the test script : # In pygame.CONTROLLERDEVICEADDED event check
mapping = controller.get_mapping() EDIT : Traceback coming when I'll figure out which debugger can give the traceback I want on Windows. Turned out this line (line 252) was the culprit : if (value[0] != '\0') { Here you have to check if value[0] is not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this is a really good work ! 😄 🎉
An additional step for better controller support!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approving this since it looks pretty much stable enough. Good work ! 🎉
I also have a remark about something, since pygame.CONTROLLER_BUTTON|AXIS_<AXIS/BUTTON>
is not something universal right now. This leads to unexpected behaviour and despite the fact we have set_mapping
, I feel like we should have some kind of database that loads smart default mapping when the controller is initialized.
To support my idea, buttons in my nintendo switch joycons that are supposed to have a pygame constant are not detected by the test script. Furthermore with my SNES controller, if I press X, 2 buttons are shown activated.
Let me know if you like the idea (this would require a separate PR btw).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, all looks good to me, on a retest. The example script works as I expect with rumble, hot-plugging and all the buttons on my controller working.
The tests also all pass. I think we just have to get this controller API out there and see it get wider user testing with different controller setups. I'm using an old X-box 360 controller on Windows, in cas that is useful ino.
Merging this now. |
While the port is meant to be a full replacement, there are some changes made to the module. But apart from the removed functions, there are not a lot of differences, and they are meant to make the module more like the joystick module. However they are/can be breaking changes.
Changes:
I removed the controller.get/set_eventstate functions, since there is no other place we expose something like this. If someone wants to block controller events, they can use
pygame.event.set_blocked
anyway. And controller.update is only needed if one disables events with set_eventstate, so that got removed too.controller.name_forindex is kind of an awkward function, since it uses device indicies as its parameter, which is inconsistent, and should not be used a lot. Even SDL removed it in SDL3 to replace it with a similar function, just with instance_ids.
Controller.get_axis returning -1 to 1 values is a change that should have been made a while ago honestly. Nowhere else do we use the -32768 to 32767 range. Changed the CONTROLLERAXISMOTION event as well, while I was at it.
This is done mostly so that it matches up with the joystick module's behaviour.
Questions:
Test script and testing:
Adapted from the joystick example, this should test out most of the functionality of the module. Things to check:
If something is broken, set NEW_CONTROLLER_MODULE to False to see if it is a regression or not. You can also run the controller tests, though not sure how good those are.
Test script
PS.: I wanted to (and should have) done this earlier. But late is better than never.