"""Simple gamepad/joystick test example.""" from inputs.inputs.libi.errors import UnpluggedError from inputs.utils import devices EVENT_ABB = ( # D-PAD, aka HAT ("Absolute-ABS_HAT0X", "HX"), ("Absolute-ABS_HAT0Y", "HY"), # Face Buttons ("Key-BTN_NORTH", "N"), ("Key-BTN_EAST", "E"), ("Key-BTN_SOUTH", "S"), ("Key-BTN_WEST", "W"), # Other buttons ("Key-BTN_THUMBL", "THL"), ("Key-BTN_THUMBR", "THR"), ("Key-BTN_TL", "TL"), ("Key-BTN_TR", "TR"), ("Key-BTN_TL2", "TL2"), ("Key-BTN_TR2", "TR3"), ("Key-BTN_MODE", "M"), ("Key-BTN_START", "ST"), # PiHUT SNES style controller buttons ("Key-BTN_TRIGGER", "N"), ("Key-BTN_THUMB", "E"), ("Key-BTN_THUMB2", "S"), ("Key-BTN_TOP", "W"), ("Key-BTN_BASE3", "SL"), ("Key-BTN_BASE4", "ST"), ("Key-BTN_TOP2", "TL"), ("Key-BTN_PINKIE", "TR"), ) # This is to reduce noise from the PlayStation controllers # For the Xbox controller, you can set this to 0 MIN_ABS_DIFFERENCE = 5 class JSTest(object): """Simple joystick test class.""" def __init__(self, gamepad=None, abbrevs=EVENT_ABB): self.btn_state = {} self.old_btn_state = {} self.abs_state = {} self.old_abs_state = {} self.abbrevs = dict(abbrevs) for key, value in self.abbrevs.items(): if key.startswith("Absolute"): self.abs_state[value] = 0 self.old_abs_state[value] = 0 if key.startswith("Key"): self.btn_state[value] = 0 self.old_btn_state[value] = 0 self._other = 0 self.gamepad = gamepad if not gamepad: self._get_gamepad() def _get_gamepad(self): """Get a gamepad object.""" try: self.gamepad = devices.gamepads[0] except IndexError: raise UnpluggedError("No gamepad found.") def handle_unknown_event(self, event, key): """Deal with unknown events.""" if event.ev_type == "Key": new_abbv = "B" + str(self._other) self.btn_state[new_abbv] = 0 self.old_btn_state[new_abbv] = 0 elif event.ev_type == "Absolute": new_abbv = "A" + str(self._other) self.abs_state[new_abbv] = 0 self.old_abs_state[new_abbv] = 0 else: return None self.abbrevs[key] = new_abbv self._other += 1 return self.abbrevs[key] def process_event(self, event): """Process the event into a state.""" if event.ev_type == "Sync": return if event.ev_type == "Misc": return key = event.ev_type + "-" + event.code try: abbv = self.abbrevs[key] except KeyError: abbv = self.handle_unknown_event(event, key) if not abbv: return if event.ev_type == "Key": self.old_btn_state[abbv] = self.btn_state[abbv] self.btn_state[abbv] = event.state if event.ev_type == "Absolute": self.old_abs_state[abbv] = self.abs_state[abbv] self.abs_state[abbv] = event.state self.output_state(event.ev_type, abbv) def format_state(self): """Format the state.""" output_string = "" for key, value in self.abs_state.items(): output_string += key + ":" + "{:>4}".format(str(value) + " ") for key, value in self.btn_state.items(): output_string += key + ":" + str(value) + " " return output_string def output_state(self, ev_type, abbv): """Print out the output state.""" if ev_type == "Key": if self.btn_state[abbv] != self.old_btn_state[abbv]: print(self.format_state()) return if abbv[0] == "H": print(self.format_state()) return difference = self.abs_state[abbv] - self.old_abs_state[abbv] if (abs(difference)) > MIN_ABS_DIFFERENCE: print(self.format_state()) def process_events(self): """Process available events.""" try: events = self.gamepad.read() except EOFError: events = [] for event in events: self.process_event(event) def main(): """Process all events forever.""" jstest = JSTest() while 1: jstest.process_events() if __name__ == "__main__": main()