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

No way to detect button combinations #6

Open
tardy-ish opened this issue Jul 1, 2021 · 1 comment
Open

No way to detect button combinations #6

tardy-ish opened this issue Jul 1, 2021 · 1 comment
Assignees
Labels
question Further information is requested

Comments

@tardy-ish
Copy link

So it's probably my lack of expertise with async programming speaking here but I could not figure out as to how to detect any button combinations being made on the controller, any way to do so or to implement some the filters to do the same?

@Zuzu-Typ
Copy link
Owner

Zuzu-Typ commented Jul 1, 2021

Hi there (:

Unfortunately, XInput-Python does not offer this as a built-in feature, but it's still fairly simple to implement.

I've assembled two examples of how this can be done using the EventHandler class:

import XInput

class CustomHandler(XInput.EventHandler):
    
    A_AND_B_BUTTONS = XInput.BUTTON_A | XInput.BUTTON_B

    MASK = 0xFFFFFF
    
    def __init__(self, *controllers):
        super().__init__(*controllers, filter = CustomHandler.A_AND_B_BUTTONS)

        self.buttons_pressed = 0

    def process_button_event(self, event):
        if event.type == XInput.EVENT_BUTTON_PRESSED:
            self.buttons_pressed |= event.button_id
        else:
            self.buttons_pressed &= (CustomHandler.MASK ^ event.button_id)

        if self.buttons_pressed == CustomHandler.A_AND_B_BUTTONS:
            print("CustomHandler detected: A and B have been pressed.")
        
    def process_stick_event(self, event):
        pass
    def process_trigger_event(self, event):
        pass
    def process_connection_event(self, event):
        pass

class AlternativeCustomHandler(XInput.EventHandler):
    
    def __init__(self, *controllers):
        super().__init__(*controllers, filter = XInput.BUTTON_A | XInput.BUTTON_B)

        self.buttons_pressed = {"A" : False, "B": False}

    def process_button_event(self, event):
        if event.type == XInput.EVENT_BUTTON_PRESSED:
            self.buttons_pressed[event.button] = True
        else:
            self.buttons_pressed[event.button] = False

        if all(self.buttons_pressed.values()):
            print("AlternativeCustomHandler detected: A and B have been pressed.")
        
    def process_stick_event(self, event):
        pass
    def process_trigger_event(self, event):
        pass
    def process_connection_event(self, event):
        pass
    
main_handler = CustomHandler(0, 1, 2, 3)
alt_handler = AlternativeCustomHandler(0, 1, 2, 3)
thread = XInput.GamepadThread(main_handler)
thread.add_event_handler(alt_handler)

Each of the event handlers filter out any buttons, except for the A and B buttons, which in this example are the ones that shall be pressed together.
The event handlers then keep track of the state of both buttons in some way and print a message on the console when both buttons are currently being pressed.

Admittedly, the filter/handler system isn't very great. Maybe I'll come up with a better solution some day.

Cheers,
--Zuzu_Typ--

@Zuzu-Typ Zuzu-Typ self-assigned this Jul 1, 2021
@Zuzu-Typ Zuzu-Typ added the question Further information is requested label Jul 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants