Skip to content

No way to detect button combinations #6

Open

Description

@tardy-ish

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?

Activity

  1. Zuzu-Typ commented on Jul 1, 2021

    @Zuzu-Typ
    Owner

    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--

  2. self-assigned this
    on Jul 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

questionFurther information is requested

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions