def open_device(device): """Device should either be the index of a valid SDL device or its joystick name. The list of attached devices and names can be retrieved with enumerate_devices().""" if not SDL_INITED: raise RuntimeError('SDL not initialized. Call init_sdl() from the the thread that will run the event loop.') input_device_count = sdl2.SDL_NumJoysticks() if input_device_count == 0: raise RuntimeError('No joysticks/game controllers attached.') if isinstance(device, int): if not 0 <= device < input_device_count: raise ValueError('Invalid device index {}; there are only {} available devices.'.format(device, input_device_count)) index = device name = sdl2.SDL_JoystickNameForIndex(index).decode('utf-8') else: name = device namebytes = device.encode('utf-8') for index in range(sdl2.SDL_NumJoysticks()): if sdl2.SDL_JoystickNameForIndex(index) == namebytes: break else: raise ValueError('No device recognized by SDL has the name "{}".'.format(name)) is_game_controller = bool(sdl2.SDL_IsGameController(index)) device = (sdl2.SDL_GameControllerOpen if is_game_controller else sdl2.SDL_JoystickOpen)(index) if not device: raise RuntimeError('Failed to open {} at device index {} with name "{}".'.format( 'game controller' if is_game_controller else 'joystick', index, name)) return device, name, index, is_game_controller
def __init__(self, controller_id, axis_deadzone=10000, trigger_deadzone=0): # Make sure we get joystick events even if in window mode and not focused. sdl2.SDL_SetHint(sdl2.SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, b"1") sdl2.SDL_Init(sdl2.SDL_INIT_GAMECONTROLLER) # Mapping for X-box S Controller sdl2.SDL_GameControllerAddMapping( b"030000005e0400008902000021010000,Classic XBOX Controller," b"a:b0,b:b1,y:b4,x:b3,start:b7,guide:,back:b6,leftstick:b8," b"rightstick:b9,dpup:h0.1,dpleft:h0.8,dpdown:h0.4,dpright:h0.2," b"leftx:a0,lefty:a1,rightx:a3,righty:a4,lefttrigger:a2," b"righttrigger:a5,leftshoulder:b5,rightshoulder:b2,") # Mapping for 8bitdo sdl2.SDL_GameControllerAddMapping( b"05000000c82d00002038000000010000,8Bitdo NES30 Pro," b"a:b1,b:b0,back:b10,dpdown:h0.4,dpleft:h0.8," b"dpright:h0.2,dpup:h0.1,guide:b2,leftshoulder:b6," b"leftstick:b13,lefttrigger:a5,leftx:a0,lefty:a1," b"rightshoulder:b7,rightstick:b14,righttrigger:a4," b"rightx:a2,righty:a3,start:b11,x:b4,y:b3,platform:Linux,") self.controller = None self.name = 'controller {:s}'.format(controller_id) self.which = None try: n = int(controller_id, 10) if n < sdl2.SDL_NumJoysticks(): self.controller = sdl2.SDL_GameControllerOpen(n) self.which = n except ValueError: for n in range(sdl2.SDL_NumJoysticks()): name = sdl2.SDL_JoystickNameForIndex(n) if name is not None: name = name.decode('utf8') if name == controller_id: self.controller = sdl2.SDL_GameControllerOpen(n) self.which = n if self.controller is None: raise Exception('Controller not found: {:s}'.format(controller_id)) try: self.name = sdl2.SDL_JoystickName( sdl2.SDL_GameControllerGetJoystick( self.controller)).decode('utf8') except AttributeError: pass logger.info('Using {:s} for input.'.format(self.name)) self.axis_deadzone = axis_deadzone self.trigger_deadzone = trigger_deadzone self.previous_state = State()
def open_device(input_device_index=0, input_device_name=None, _used_idx_and_name=None): if input_device_name is None and int( input_device_index) != input_device_index: raise ValueError( 'If input_device_name is not specified, the value supplied for input_device_index must be an integer.' ) input_device_count = sdl2.SDL_NumJoysticks() if input_device_count == 0: raise RuntimeError( 'According to SDL, there are no joysticks/game controllers attached.' ) if input_device_name is None: if not 0 <= input_device_index < input_device_count: isare, ssuffix = ('is', '') if input_device_count == 1 else ('are', 's') e = ( 'According to SDL, there {0} {1} joystick{2}/game controller{2} attached. Therefore, input_device_index must be ' 'an integer in the closed interval [0, {3}], which the supplied value, {4}, is not.' ) raise ValueError( e.format(isare, input_device_count, ssuffix, input_device_count - 1, input_device_index)) input_device_name = sdl2.SDL_JoystickNameForIndex(input_device_index) else: if isinstance(input_device_name, str): input_device_name = input_device_name.encode('utf-8') else: input_device_name = bytes(input_device_name) for sdl_dev_idx in range(sdl2.SDL_NumJoysticks()): if sdl2.SDL_JoystickNameForIndex(sdl_dev_idx) == input_device_name: input_device_index = sdl_dev_idx break else: raise ValueError( 'No connected joystick or game controller device recognized by SDL has the name "{}".' .format(input_device_name.decode('utf-8'))) device_is_game_controller = bool( sdl2.SDL_IsGameController(input_device_index)) device = (sdl2.SDL_GameControllerOpen if device_is_game_controller else sdl2.SDL_JoystickOpen)(input_device_index) if not device: raise RuntimeError( 'Failed to open {} at device index {} with name "{}".'.format( 'game controller' if device_is_game_controller else 'joystick', input_device_index, input_device_name.decode('utf-8'))) if _used_idx_and_name is not None: _used_idx_and_name[0] = input_device_index _used_idx_and_name[1] = input_device_name return device, device_is_game_controller
def enumerate_devices(): with contextlib.ExitStack() as estack: # We may be called from a different thread than the one that will run the SDL event loop. In case that # will happen, if SDL is not already initialized, we do not leave it initialized (if we did, it would be # bound to our current thread, which may not be desired). if not SDL_INITED: if sdl2.SDL_Init(sdl2.SDL_INIT_JOYSTICK | sdl2.SDL_INIT_GAMECONTROLLER) < 0: sdl_e = sdl2.SDL_GetError() sdl_e = sdl_e.decode('utf-8') if sdl_e else 'UNKNOWN ERROR' sdl2.SDL_Quit() raise RuntimeError( 'Failed to initialize SDL ("{}").'.format(sdl_e)) estack.callback(lambda: sdl2.SDL_QuitSubSystem( sdl2.SDL_INIT_JOYSTICK | sdl2.SDL_INIT_GAMECONTROLLER)) estack.callback(sdl2.SDL_Quit) rows = [] for sdl_dev_idx in range(sdl2.SDL_NumJoysticks()): device_is_game_controller = bool( sdl2.SDL_IsGameController(sdl_dev_idx)) device_type = 'game controller' if device_is_game_controller else 'joystick' cols = [ sdl_dev_idx, device_type, sdl2.SDL_JoystickNameForIndex(sdl_dev_idx).decode('utf-8') ] if device_is_game_controller: cols.append( sdl2.SDL_GameControllerNameForIndex(sdl_dev_idx).decode( 'utf-8')) rows.append(cols) return rows
def get_joysticks(cls): # Check init if not get_init(): init() return Stash(cls(i) for i in range( sdl2.SDL_NumJoysticks())) # Use identifier not instance id.
def __init__(self, joyName=b'FrSky Taranis Joystick'): # Set up the joystick sdl2.SDL_Init(sdl2.SDL_INIT_JOYSTICK) # Enumerate joysticks joyList = [] for i in range(0, sdl2.SDL_NumJoysticks()): joyList.append(sdl2.SDL_JoystickNameForIndex(i)) print(joyList) # By default, load the first available joystick or joyName. if (len(joyList) > 0): indxJoy = 0 try: indxJoy = joyList.index(joyName) except: pass self.joy = sdl2.SDL_JoystickOpen(indxJoy) else: print("Joystick Fail!") print("Joystick Name:", sdl2.SDL_JoystickName(self.joy)) print("Joystick NumAxes", sdl2.SDL_JoystickNumAxes(self.joy)) # print( "Joystick NumTrackballs:", sdl2.SDL_JoystickNumBalls(self.joy)) print("Joystick Buttons:", sdl2.SDL_JoystickNumButtons(self.joy)) # print( "Joystick NumHats:", sdl2.SDL_JoystickNumHats(self.joy)) self.axis = [] self.button = [] self.msg = [0.0] * 16
def enumerate_controllers(): print('Controllers connected to this system:') for n in range(sdl2.SDL_NumJoysticks()): name = sdl2.SDL_JoystickNameForIndex(n) if name is not None: name = name.decode('utf8') print(n, ':', name) print('Note: These are numbered by connection order. Numbers will change if you unplug a controller.')
def _init_thread(self): """ Complete SDL2 interface initialisation. """ # initialise SDL sdl2.SDL_Init(sdl2.SDL_INIT_EVERYTHING) # set clipboard handler to SDL2 backend.clipboard_handler = SDL2Clipboard() # display palettes for blink states 0, 1 self.show_palette = [ sdl2.SDL_AllocPalette(256), sdl2.SDL_AllocPalette(256) ] # get physical screen dimensions (needs to be called before set_mode) display_mode = sdl2.SDL_DisplayMode() sdl2.SDL_GetCurrentDisplayMode(0, ctypes.byref(display_mode)) self.physical_size = display_mode.w, display_mode.h # create the window initially, size will be corrected later self.display = None # create window in same thread that manipulates it # "NOTE: You should not expect to be able to create a window, render, or receive events on any thread other than the main one" # https://wiki.libsdl.org/CategoryThread # http://stackoverflow.com/questions/27751533/sdl2-threading-seg-fault self._do_create_window(640, 400) # load an all-black 16-colour game palette to get started self.set_palette([(0, 0, 0)] * 16, None) self.move_cursor(1, 1) self.set_page(0, 0) self.set_mode(self.kwargs['initial_mode']) # support for CGA composite self.composite_palette = sdl2.SDL_AllocPalette(256) composite_colors = video_graphical.composite_640.get( self.composite_card, video_graphical.composite_640['cga']) colors = (sdl2.SDL_Color * 256)( *[sdl2.SDL_Color(r, g, b, 255) for (r, g, b) in composite_colors]) sdl2.SDL_SetPaletteColors(self.composite_palette, colors, 0, 256) # check if we can honour scaling=smooth if self.smooth: # pointer to the zoomed surface self.zoomed = None pixelformat = self.display_surface.contents.format if pixelformat.contents.BitsPerPixel != 32: logging.warning( 'Smooth scaling not available on this display of %d-bit colour depth: needs 32-bit', self.display_surface.format.contents.BitsPerPixel) self.smooth = False if not hasattr(sdl2, 'sdlgfx'): logging.warning( 'Smooth scaling not available: SDL_GFX extension not found.' ) self.smooth = False # available joysticks num_joysticks = sdl2.SDL_NumJoysticks() for j in range(num_joysticks): sdl2.SDL_JoystickOpen(j) # if a joystick is present, its axes report 128 for mid, not 0 for axis in (0, 1): backend.input_queue.put( backend.Event(backend.STICK_MOVED, (j, axis, 128)))
def list_joysticks(self): # Read Number of joysticks and # print the name and index to console number_of_sticks = sdl2.SDL_NumJoysticks() if number_of_sticks > 0: for i in range(number_of_sticks): print("Joystick %d : %s" % (i + 1, sdl2.SDL_JoystickNameForIndex(i))) else: print("No Joysticks connected")
def get_controller(c): try: n = int(c, 10) return sdl2.SDL_GameControllerOpen(n) except ValueError: for n in range(sdl2.SDL_NumJoysticks()): name = sdl2.SDL_JoystickNameForIndex(n) if name is not None: name = name.decode('utf8') if name == c: return sdl2.SDL_GameControllerOpen(n) raise Exception('Controller not found: %s'.format(c))
def open(self, client): super(SDLInputHandler, self).open(client) # Enumerate already plugged controllers for i in range(sdl2.SDL_NumJoysticks()): if sdl2.SDL_IsGameController(i): if sdl2.SDL_GameControllerOpen(i): log.info("Opened controller: %i", i) self.client.controller_added(i) else: log.error("Unable to open controller: %i", i) else: log.error("Not a gamecontroller: %i", i)
def __init__(self, game): if sdl2.SDL_Init(sdl2.SDL_INIT_JOYSTICK) != 0: raise ("Coudldn't initialise joysticks") self.quit = False self.game_pads = [GamePad(game), GamePad(game)] self.key_map = {} self.key_map[eActions.up] = [sdl2.SDLK_UP] self.key_map[eActions.right] = [sdl2.SDLK_RIGHT] self.key_map[eActions.down] = [sdl2.SDLK_DOWN] self.key_map[eActions.left] = [sdl2.SDLK_LEFT] self.key_map[eActions.up1] = [sdl2.SDLK_w] self.key_map[eActions.right1] = [sdl2.SDLK_d] self.key_map[eActions.down1] = [sdl2.SDLK_s] self.key_map[eActions.left1] = [sdl2.SDLK_a] self.key_map[eActions.jump] = [sdl2.SDLK_SPACE] self.key_map[eActions.attack_small] = [sdl2.SDLK_g] self.key_map[eActions.attack_big] = [sdl2.SDLK_b] self.key_map[eActions.block] = [sdl2.SDLK_f] self.key_map[eActions.pause] = [sdl2.SDLK_p, sdl2.SDLK_ESCAPE] self.key_map[eActions.quit] = [sdl2.SDLK_q, sdl2.SDLK_ESCAPE] self.key_map[eActions.fullscreen] = [sdl2.SDLK_f] self.key_map[eActions.select] = [sdl2.SDLK_TAB, sdl2.SDLK_o] self.controllers = {} if sdl2.SDL_NumJoysticks() > 0: for joy in range(sdl2.SDL_NumJoysticks()): if sdl2.SDL_IsGameController(joy): self.controllers[joy] = (GameController( handler=sdl2.SDL_GameControllerOpen(joy), joy_number=joy)) if len(self.controllers) > 2: self.game_pads.append(GamePad(game))
def main(): parser = argparse.ArgumentParser(description=SHORT_DESCRIPTION) parser.add_argument('server', help='Server address') parser.add_argument('port', help='Server port', type=int, default=2010, nargs='?') parser.add_argument('ship', help='Selected ship', type=int, default=0, nargs='?') parser.add_argument('--enable-pitch', help='Turn on pitch control', action='store_true') parser.add_argument('--enable-warp', help='Turn on warp lever', action='store_true') args = parser.parse_args() SDL.SDL_Init(SDL.SDL_INIT_JOYSTICK) for joy in range(SDL.SDL_NumJoysticks()): name = SDL.SDL_JoystickNameForIndex(joy) if name == b'CH FLIGHT SIM YOKE USB': joystick = Joystick(SDL.SDL_JoystickOpen(joy)) break else: print('Could not find yoke.') exit(1) tx, rx = connect(args.server, args.port) track = Tracker() def handle_input(): for packet in rx: if isinstance(packet, diana.packet.WelcomePacket): print("Connected.") tx(diana.packet.SetShipPacket(args.ship)) tx( diana.packet.SetConsolePacket(diana.packet.Console.data, True)) tx(diana.packet.ReadyPacket()) track.rx(packet) launch_thread(handle_input) while True: process_frame(joystick, tx, lambda: track.player_ship, args)
def _init_joystick(): """ Initialize joystick using SDL library. Note that it is automatically chosen the first enumerated joystick. Returns ------- The SDL Joystick object. """ sdl2.SDL_Init(sdl2.SDL_INIT_JOYSTICK) if sdl2.SDL_NumJoysticks() < 1: raise RuntimeError(f'No joysticks connected!') return sdl2.SDL_JoystickOpen(0)
def __enter__(self): """Complete SDL2 interface initialisation.""" # set clipboard handler to SDL2 self.clipboard_handler = get_clipboard_handler() # display palettes for blink states 0, 1 self.show_palette = [ sdl2.SDL_AllocPalette(256), sdl2.SDL_AllocPalette(256) ] # get physical screen dimensions (needs to be called before set_mode) # load an all-black 16-colour game palette to get started self.set_palette([(0, 0, 0)] * 16, None) self.move_cursor(1, 1) self.set_page(0, 0) # set_mode should be first event on queue # support for CGA composite self.composite_palette = sdl2.SDL_AllocPalette(256) composite_colors = video_graphical.composite_640.get( self.composite_card, video_graphical.composite_640['cga']) colors = (sdl2.SDL_Color * 256)( *[sdl2.SDL_Color(r, g, b, 255) for (r, g, b) in composite_colors]) sdl2.SDL_SetPaletteColors(self.composite_palette, colors, 0, 256) # check if we can honour scaling=smooth if self.smooth: # pointer to the zoomed surface self.zoomed = None pixelformat = self.display_surface.contents.format if pixelformat.contents.BitsPerPixel != 32: logging.warning( 'Smooth scaling not available on this display of %d-bit colour depth: needs 32-bit', self.display_surface.format.contents.BitsPerPixel) self.smooth = False if not hasattr(sdl2, 'sdlgfx'): logging.warning( 'Smooth scaling not available: SDL_GFX extension not found.' ) self.smooth = False # available joysticks num_joysticks = sdl2.SDL_NumJoysticks() for j in range(num_joysticks): sdl2.SDL_JoystickOpen(j) # if a joystick is present, its axes report 128 for mid, not 0 for axis in (0, 1): self.input_queue.put( signals.Event(signals.STICK_MOVED, (j, axis, 128))) # enable IME sdl2.SDL_StartTextInput() return video_graphical.VideoGraphical.__enter__(self)
def _init_joystick(): """ Initialize joystick using SDL library. Note that it is automatically chosen the first enumerated joystick. Returns ------- The SDL Joystick object. """ sdl2.SDL_Init(sdl2.SDL_INIT_JOYSTICK) njoysticks = sdl2.SDL_NumJoysticks() if njoysticks < 1: raise RuntimeError(f'No joysticks connected!') print('Joysticks available:') for i in range(njoysticks): joy = sdl2.SDL_JoystickOpen(i) print(f' - {sdl2.SDL_JoystickName(joy).decode()}') return sdl2.SDL_JoystickOpen(0)
def __init__(self, stage): '''Constructor''' self.WARM_UP = 0 self.QUALIFYING = 1 self.RACE = 2 self.UNKNOWN = 3 self.stage = stage self.parser = msgParser.MsgParser() self.state = carState.CarState() self.control = carControl.CarControl() self.steer_lock = 0.785398 self.max_speed = 100 self.prev_rpm = None # Initialize the joysticks sdl2.SDL_Init(sdl2.SDL_INIT_JOYSTICK | sdl2.SDL_INIT_HAPTIC) assert sdl2.SDL_NumJoysticks() > 0 assert sdl2.SDL_NumHaptics() > 0 self.joystick = sdl2.SDL_JoystickOpen(0) self.haptic = sdl2.SDL_HapticOpen(0) assert sdl2.SDL_JoystickNumAxes(self.joystick) == 3 assert sdl2.SDL_HapticQuery(self.haptic) & sdl2.SDL_HAPTIC_CONSTANT # Initialize force feedback efx = sdl2.SDL_HapticEffect(type=sdl2.SDL_HAPTIC_CONSTANT, constant= \ sdl2.SDL_HapticConstant(type=sdl2.SDL_HAPTIC_CONSTANT, direction= \ sdl2.SDL_HapticDirection(type=sdl2.SDL_HAPTIC_CARTESIAN, dir=(0,0,0)), \ length=sdl2.SDL_HAPTIC_INFINITY, level=0, attack_length=0, fade_length=0)) self.effect_id = sdl2.SDL_HapticNewEffect(self.haptic, efx) sdl2.SDL_HapticRunEffect(self.haptic, self.effect_id, 1) sdl2.SDL_HapticSetAutocenter(self.haptic, 0) sdl2.SDL_HapticSetGain(self.haptic, 100) self.stats = sensorstats.Stats(inevery=8)
def read(self): """Read all the sticks and switches""" # Force an update of the joystick channels sdl2.SDL_PumpEvents() # Ensure that the Tx is connected if sdl2.SDL_NumJoysticks() == 0: if self.joystick: sdl2.SDL_JoystickClose(self.joystick) self.joystick = None return False elif not self.joystick: # Open the first joystick if necessary self.joystick = sdl2.SDL_JoystickOpen(0) # Read all the channels ret = [] for channel in range(self.channels): val = sdl2.SDL_JoystickGetAxis(self.joystick, channel) ret.append(int(((val / 65536.0) + 0.5) * 800.0 + 1100.0)) # Return the list of values return ret
def ResolvedName2Dict(Name): for joystick in joysticksSorted: if joystick["Res Name"] == Name: return joystick def replaceInFile(filename, find, replace): for line in fileinput.input(filename, inplace=True): line = line.replace(find, replace) sys.stdout.write(line) fileinput.close() if sdl2.SDL_NumJoysticks() < 1: print " OOPS: Can't find any joysticks." print " - Check they are connected." print " - Check they are listed in the \"USB Game Controllers\" utility." raw_input("\n Press Enter to Quit.") sys.exit(1) for i in range(sdl2.SDL_NumJoysticks()): joy = sdl2.SDL_JoystickOpen(i) if joy is None: print("Joystick device at {} is invalid.".format(i)) else: name_object = sdl2.SDL_JoystickName(joy) if name_object is None: name = "Unknown device" print("Encountered an invalid device name")
def poll_sdl_events(self): import ctypes as c sdl.SDL_JoystickEventState(sdl.SDL_ENABLE) self.num_gamepads = sdl.SDL_NumJoysticks() self.active_gamepads = {} while self.pending: event = sdl.SDL_Event() while sdl.SDL_PollEvent(c.byref(event)): if event.type == sdl.SDL_JOYBUTTONDOWN: button = event.jbutton self.gamepad_input = button.which self.gamepad_pressed = button.button self.gamepad_type = "button" elif event.type == sdl.SDL_JOYAXISMOTION: axis = event.jaxis if event.jaxis.value < -16000: self.gamepad_input = axis.which self.gamepad_pressed = axis.axis self.gamepad_type = "Naxis" elif event.jaxis.value > 16000: self.gamepad_input = axis.which self.gamepad_pressed = axis.axis self.gamepad_type = "Paxis" elif event.type == sdl.SDL_JOYDEVICEADDED: n = event.jdevice.which device = sdl.SDL_JoystickOpen(n) joy_id = sdl.SDL_JoystickInstanceID(device) self.active_gamepads[joy_id] = device name = sdl.SDL_JoystickName(device).decode("utf-8") page = 1 while page < 5: self.pages_list[page][1].insert( n, str(n), str(n) + ": " + name) if self.gamepads_stored[page][1] == name: self.pages_list[page][1].set_active_id( str(self.gamepads_stored[page][0])) page += 1 log.info(f"Controller added: {name}") log.info( f"Current active controllers: {sdl.SDL_NumJoysticks()}" ) elif event.type == sdl.SDL_JOYDEVICEREMOVED: joy_id = event.jdevice.which device = self.active_gamepads[joy_id] if sdl.SDL_JoystickGetAttached(device): sdl.SDL_JoystickClose(device) name = sdl.SDL_JoystickName(device).decode("utf-8") page = 1 while page < 5: if self.gamepads_stored[page][1] == name: self.pages_list[page][1].set_active_id("-1") self.pages_list[page][1].remove( self.gamepads_stored[page][0]) page += 1 log.info(f"Controller removed: {name}") self.active_gamepads.pop(joy_id) log.info( f"Current active controllers: {sdl.SDL_NumJoysticks()}" )
def joystick_devices(): """Returns the list of joystick like devices. :return list containing information about all joystick like devices """ global _joystick_devices syslog = logging.getLogger("system") syslog.debug("{:d} joysticks found".format(sdl2.SDL_NumJoysticks())) # Get all connected devices devices = [] for i in range(sdl2.SDL_NumJoysticks()): joy = sdl2.SDL_JoystickOpen(i) if joy is None: syslog.error("Invalid joystick device at id {}".format(i)) else: devices.append(JoystickDeviceData(joy)) # Compare existing versus observed devices and only proceed if there # is a difference device_added = False device_removed = False for new_dev in devices: if new_dev not in _joystick_devices: device_added = True syslog.debug("Added: name={} windows_id={:d}".format( new_dev.name, new_dev.windows_id)) for old_dev in _joystick_devices: if old_dev not in devices: device_removed = True syslog.debug("Removed: name={} windows_id={:d}".format( new_dev.name, new_dev.windows_id)) if not device_added and not device_removed: return _joystick_devices # Create hashes based on number of inputs for each virtual device. As we # absolutely need to be able to assign the SDL device to the correct # vJoy device we will not proceed if this mapping cannot be made without # ambiguity. vjoy_lookup = {} for i, dev in enumerate(devices): if not dev.is_virtual: continue hash_value = (dev.axis_count, dev.buttons, dev.hats) syslog.debug("vjoy windows id {:d}: {}".format(i, hash_value)) if hash_value in vjoy_lookup: raise error.GremlinError( "Indistinguishable vJoy devices present.\n\n" "vJoy devices have to differ in the number of " "(at least one of) axis, buttons, or hats in order to work " "properly with Joystick Gremlin.") vjoy_lookup[hash_value] = i # For virtual joysticks query them id by id until we have found all active # devices vjoy_proxy = VJoyProxy() # Try each possible vJoy device and if it exists find the matching device # as detected by SDL should_terminate = False for i in range(1, 17): try: vjoy_dev = vjoy_proxy[i] hash_value = (vjoy_dev.axis_count, vjoy_dev.button_count, vjoy_dev.hat_count) if hash_value in vjoy_lookup: # Set vJoy id and correctly setup the axis id mapping devices[vjoy_lookup[hash_value]]._vjoy_id = vjoy_dev.vjoy_id axis_mapping = [] for j in range(vjoy_dev.axis_count): axis_mapping.append((j + 1, vjoy_dev.axis_id(j + 1))) devices[vjoy_lookup[hash_value]].set_axis_mapping(axis_mapping) syslog.debug("vjoy id {:d}: {} - MATCH".format(i, hash_value)) if hash_value not in vjoy_lookup: syslog.debug("vjoy id {:d}: {} - ERROR".format(i, hash_value)) should_terminate = True except error.VJoyError as e: if e.value != "Requested vJoy device is not available": raise error.GremlinError(e.value) if should_terminate: raise error.GremlinError( "Unable to match vJoy devices to windows devices.") # Reset all devices so we don't hog the ones we aren't actually using vjoy_proxy.reset() _joystick_devices = devices return _joystick_devices
def __init__(self, app): self.app = app self.ui = self.app.ui # read from binds.cfg file or create it from template # exec results in edit_binds, a dict whose keys are keys+mods # and whose values are bound functions self.edit_bind_src = None # bad probs if a command isn't in binds.cfg, so just blow it away # if the template is newer than it # TODO: better solution is find any binds in template but not binds.cfg # and add em binds_filename = self.app.config_dir + BINDS_FILENAME binds_outdated = not os.path.exists( binds_filename) or os.path.getmtime( binds_filename) < os.path.getmtime(BINDS_TEMPLATE_FILENAME) if not binds_outdated and os.path.exists(binds_filename): exec(open(binds_filename).read()) self.app.log('Loaded key binds from %s' % binds_filename) else: default_data = open(BINDS_TEMPLATE_FILENAME).readlines()[1:] new_binds = open(binds_filename, 'w') new_binds.writelines(default_data) new_binds.close() self.app.log('Created new key binds file %s' % binds_filename) exec(''.join(default_data)) if not self.edit_bind_src: self.app.log('No bind data found, Is binds.cfg.default present?') exit() # associate key + mod combos with methods self.edit_binds = {} for bind_string in self.edit_bind_src: bind = self.parse_key_bind(bind_string) if not bind: continue # bind data could be a single item (string) or a list/tuple bind_data = self.edit_bind_src[bind_string] if type(bind_data) is str: bind_fnames = ['BIND_%s' % bind_data] else: bind_fnames = ['BIND_%s' % s for s in bind_data] bind_functions = [] for bind_fname in bind_fnames: if not hasattr(self, bind_fname): continue bind_functions.append(getattr(self, bind_fname)) self.edit_binds[bind] = bind_functions # get controller(s) # TODO: use kewl SDL2 gamepad system js_init = sdl2.SDL_InitSubSystem(sdl2.SDL_INIT_JOYSTICK) if js_init != 0: self.app.log( "SDL2: Couldn't initialize joystick subsystem, code %s" % js_init) return sticks = sdl2.SDL_NumJoysticks() #self.app.log('%s gamepads found' % sticks) self.gamepad = None self.gamepad_left_x, self.gamepad_left_y = 0, 0 # for now, just grab first pad if sticks > 0: pad = sdl2.SDL_JoystickOpen(0) pad_name = sdl2.SDL_JoystickName(pad).decode('utf-8') pad_axes = sdl2.SDL_JoystickNumAxes(pad) pad_buttons = sdl2.SDL_JoystickNumButtons(pad) self.app.log('Gamepad found: %s with %s axes, %s buttons' % (pad_name, pad_axes, pad_buttons)) self.gamepad = pad # before main loop begins, set initial mouse position - # SDL_GetMouseState returns 0,0 if the mouse hasn't yet moved # in the new window! wx, wy = ctypes.c_int(0), ctypes.c_int(0) sdl2.SDL_GetWindowPosition(self.app.window, wx, wy) wx, wy = int(wx.value), int(wy.value) mx, my = ctypes.c_int(0), ctypes.c_int(0) sdl2.mouse.SDL_GetGlobalMouseState(mx, my) mx, my = int(mx.value), int(my.value) self.app.mouse_x, self.app.mouse_y = mx - wx, my - wy # set flag so we know whether handle_input's SDL_GetMouseState result # is accurate :/ self.mouse_has_moved = False
def main(): parser = argparse.ArgumentParser() parser.add_argument('-l', '--list-controllers', action='store_true', help='Display a list of controllers attached to the system.') parser.add_argument('-c', '--controller', type=str, default='0', help='Controller to use. Default: 0.') parser.add_argument('-m', '--macro-controller', metavar='CONTROLLER:RECORD_BUTTON:PLAY_BUTTON', type=str, default=None, help='Controller and buttons to use for macro control. Default: None.') parser.add_argument('-p', '--port', type=str, default='/dev/ttyUSB0', help='Serial port or "functionfs" for direct USB mode. Default: /dev/ttyUSB0.') parser.add_argument('-b', '--baud-rate', type=int, default=115200, help='Baud rate. Default: 115200.') parser.add_argument('-u', '--udc', type=str, default='dummy_udc.0', help='UDC for direct USB mode. Default: dummy_udc.0 (loopback mode).') parser.add_argument('-R', '--record', type=str, default=None, help='Record events to file.') parser.add_argument('-P', '--playback', type=str, default=None, help='Play back events from file.') parser.add_argument('-d', '--dontexit', action='store_true', help='Switch to live input when playback finishes, instead of exiting. Default: False.') parser.add_argument('-q', '--quiet', action='store_true', help='Disable speed meter. Default: False.') parser.add_argument('-M', '--macros-dir', type=str, default='.', help='Directory to save macros. Default: current directory.') parser.add_argument('-f', '--function', type=str, nargs='*', default=[], help='Map a macro function to a button.') parser.add_argument('-D', '--log-level', type=str, default='INFO', help='Debugging level. CRITICAL, ERROR, WARNING, INFO, DEBUG. Default=INFO') args = parser.parse_args() numeric_level = getattr(logging, args.log_level.upper(), None) if not isinstance(numeric_level, int): raise ValueError('Invalid log level: %s' % args.log_level) root_logger.setLevel(numeric_level) if args.list_controllers: Controller.enumerate() exit(0) states = [] if args.playback is None or args.dontexit: if args.controller == 'fake': states = fakeinput() else: states = Controller(args.controller) if args.playback is not None: states = itertools.chain(replay_states(args.playback), states) macro_controller = None macro_record = None macro_play = None if args.macro_controller is not None: try: macro_controller, macro_record, macro_play = args.macro_controller.rsplit(':', maxsplit=3) macro_record = int(macro_record, 10) macro_play = int(macro_play, 10) except ValueError: logger.critical('Macro controller must be <controller number or name>:<record button>:<play button>') exit(-1) try: n = int(macro_controller, 10) if n < sdl2.SDL_NumJoysticks(): sdl2.SDL_JoystickOpen(n) macro_controller = n except ValueError: for n in range(sdl2.SDL_NumJoysticks()): name = sdl2.SDL_JoystickNameForIndex(n) if name is not None: name = name.decode('utf8') if name == macro_controller: sdl2.SDL_JoystickOpen(n) macro_controller = n window = None try: window = Window() except sdl2.ext.common.SDLError: logger.warning('Could not create a window with SDL. Keyboard input will not be available.') pass function_macros = {} for arg in args.function: try: b,f = arg.split(':') function_macros[int(b, 10)] = macros_dict[f] except ValueError: logger.error('Invalid function macro ignored.') except KeyError: logger.error('Invalid function macro ignored.') with MacroManager(states, macros_dir=args.macros_dir, record_button=macro_record, play_button=macro_play, function_macros=function_macros) as mm: with Recorder(args.record) as record: with HAL(args.port, args.baud_rate, args.udc) as hal: with tqdm(unit=' updates', disable=args.quiet, dynamic_ncols=True) as pbar: try: while True: for event in sdl2.ext.get_events(): # we have to fetch the events from SDL in order for the controller # state to be updated. if event.type == sdl2.SDL_WINDOWEVENT: if event.window.event == sdl2.SDL_WINDOWEVENT_CLOSE: raise WindowClosed else: if event.type == sdl2.SDL_KEYDOWN and event.key.repeat == 0: logger.debug('Key down: {:s}'.format(sdl2.SDL_GetKeyName(event.key.keysym.sym).decode('utf8'))) mm.key_event(event.key.keysym.sym, True) elif event.type == sdl2.SDL_KEYUP: logger.debug('Key up: {:s}'.format(sdl2.SDL_GetKeyName(event.key.keysym.sym).decode('utf8'))) mm.key_event(event.key.keysym.sym, False) elif event.jdevice.which == macro_controller: if event.type == sdl2.SDL_JOYBUTTONDOWN: logger.debug('Macro controller button down: {:d}'.format(event.jbutton.button)) mm.button_event(event.jbutton.button, True) elif event.type == sdl2.SDL_JOYBUTTONUP: mm.button_event(event.jbutton.button, False) # wait for the arduino to request another state. if hal.poll(): state = next(mm) hal.write(state) record.write(state) pbar.set_description('Sent {:s}'.format(state.hexstr)) pbar.update() if window is not None: window.update(state) except StopIteration: logger.info('Exiting because replay finished.') except KeyboardInterrupt: logger.info('Exiting due to keyboard interrupt.') except WindowClosed: logger.info('Exiting because input window was closed.')
import shlex from helpers import scale, Throttler from settings import VIDEO_ENABLED, EV3_HOST, DATA_PORT, PC_HOST, DATA_RATE,\ SIXAXIS try: import cPickle as pickle except: import pickle # ______ Constants & configuration ______ # # initialise joysticking error = sdl2.SDL_Init(sdl2.SDL_INIT_JOYSTICK) numsticks = sdl2.SDL_NumJoysticks() print("{} Sticks found".format(numsticks+1)) for stick in range(numsticks): name = sdl2.SDL_JoystickNameForIndex(stick) print("Name of stick {} is {}".format(stick, name)) if name == b"PLAYSTATION(R)3 Controller": gamepad_obj = sdl2.SDL_JoystickOpen(stick) if sdl2.SDL_JoystickNumAxes(gamepad_obj) == 4: # Let's do a test read sdl2.SDL_PumpEvents() result = sdl2.SDL_JoystickGetAxis(gamepad_obj, 0) if result < -30000: print("Stick {} disconnected".format(stick)) else: print("Selected stick {}".format(stick)) break
def joystick_devices_initialization(): """Initializes joystick device information. This function retrieves information about various joystick devices and associates them and collates their information as required. Amongst other things this also ensures that each vJoy device has a correct windows id assigned to it. """ global _joystick_devices, _joystick_init_lock _joystick_init_lock.acquire() syslog = logging.getLogger("system") syslog.info("Initializing joystick devices") syslog.debug("{:d} joysticks detected".format(sdl2.SDL_NumJoysticks())) # Register all devices with the device registry to handle duplicate and # non duplicate devices transparently. devreg = common.DeviceRegistry() devreg.reset() # Register the fake keyboard device devreg.register(0, 0) # Process all connected devices in order to properly initialize the # device registry for i in range(sdl2.SDL_NumJoysticks()): joy = sdl2.SDL_JoystickOpen(i) if joy is None: syslog.error("Invalid joystick device at id {}".format(i)) else: devreg.register(get_device_guid(joy), sdl2.SDL_JoystickInstanceID(joy)) # Process all devices again to detect those that have been added and those # that have been removed since the last time this function ran. # Accumulate all devices devices = [] for i in range(sdl2.SDL_NumJoysticks()): joy = sdl2.SDL_JoystickOpen(i) if joy is not None: devices.append(JoystickDeviceData(joy)) # Compare existing versus observed devices and only proceed if there # is a change to avoid unnecessary work. device_added = False device_removed = False for new_dev in devices: if new_dev not in _joystick_devices: device_added = True syslog.debug( "Added: name={} windows_id={:d} hardware_id={:d}".format( new_dev.name, new_dev.windows_id, new_dev.hardware_id)) for old_dev in _joystick_devices: if old_dev not in devices: device_removed = True syslog.debug( "Removed: name={} windows_id={:d} hardware_id={:d}".format( old_dev.name, old_dev.windows_id, old_dev.hardware_id)) # Terminate if no change occurred if not device_added and not device_removed: _joystick_init_lock.release() return # In order to associate vJoy devices and their ids correctly with SDL # device ids a hash is constructed from the number of axes, buttons, and # hats. This information is used to attempt to find unambiguous mappings # between vJoy and SDL devices. If this is not possible Gremlin will # terminate as this is a non-recoverable error. vjoy_lookup = {} for dev in [dev for dev in devices if dev.is_virtual]: hash_value = (dev.axis_count, dev.buttons, dev.hats) syslog.debug("vJoy windows id {:d}: {}".format(dev.windows_id, hash_value)) # Only unique combinations of axes, buttons, and hats are allowed # for vJoy devices if hash_value in vjoy_lookup: raise error.GremlinError( "Indistinguishable vJoy devices present.\n\n" "vJoy devices have to differ in the number of " "(at least one of) axes, buttons, or hats in order to work " "properly with Joystick Gremlin.") vjoy_lookup[hash_value] = dev # Query all vJoy devices in sequence until all have been processed and # their matching SDL counterparts have been found. vjoy_proxy = VJoyProxy() should_terminate = False for i in range(1, 17): # Only process devices that actually exist if not vjoy.device_exists(i): continue # Compute a hash for the vJoy device and match it against the SDL # device hashes hash_value = (vjoy.axis_count(i), vjoy.button_count(i), vjoy.hat_count(i)) # As we are ensured that no duplicate vJoy devices exist from # the previous step we can directly link the SDL and vJoy device if hash_value in vjoy_lookup: vjoy_lookup[hash_value].set_vjoy_id(i) syslog.debug("vjoy id {:d}: {} - MATCH".format(i, hash_value)) else: should_terminate = True syslog.debug("vjoy id {:d}: {} - ERROR - vJoy device exists " "SDL is missing".format(i, hash_value)) # If the device can be acquired, configure the mapping from # vJoy axis id, which may not be sequential, to the # sequential SDL axis id if hash_value in vjoy_lookup: try: vjoy_dev = vjoy_proxy[i] axis_mapping = [] for j in range(vjoy_dev.axis_count): axis_mapping.append((j + 1, vjoy_dev.axis_id(j + 1))) vjoy_lookup[hash_value].set_axis_mapping(axis_mapping) except error.VJoyError as e: syslog.debug("vJoy id {:} can't be acquired".format(i)) if should_terminate: raise error.GremlinError( "Unable to match vJoy devices to windows devices.") # Reset all devices so we don't hog the ones we aren't actually using vjoy_proxy.reset() # Update device list which will be used when queries for joystick devices # are made _joystick_devices = devices _joystick_init_lock.release()
def __new__(cls, identifier=None, instance_id=None, *args, **kwargs): # Check init if not get_init(): init() # Create the object joy = super().__new__(cls) if instance_id is not None: # Create the underlying joystick from the instance id. # SDL_JOYDEVICEREMOVED and all other SDL_JOY#### events give the instance id joy.joystick = sdl2.SDL_JoystickFromInstanceID(instance_id) # print('Instance ID:', raw_joystick, SDL_JoystickGetAttached(raw_joystick)) else: # Create the underlying joystick from the enumerated identifier # SDL_JOYDEVICEADDED and SDL_NumJoysticks use open if identifier is None: identifier = 0 if isinstance(identifier, str): # Get the joystick from the name or None if not found! for i in range(sdl2.SDL_NumJoysticks()): raw_joystick = sdl2.SDL_JoystickOpen(i) try: if sdl2.SDL_JoystickName(raw_joystick).decode( 'utf-8') == identifier: joy.joystick = raw_joystick break except: pass else: joy.joystick = sdl2.SDL_JoystickOpen(identifier) # print('ID:', raw_joystick, SDL_JoystickGetAttached(raw_joystick)) try: joy.identifier = sdl2.SDL_JoystickID( sdl2.SDL_JoystickInstanceID(joy.joystick)).value # joy.identifier = SDL_JoystickInstanceID(raw_joystick) joy.name = sdl2.SDL_JoystickName(joy.joystick).decode('utf-8') joy.numaxes = sdl2.SDL_JoystickNumAxes(joy.joystick) joy.numbuttons = sdl2.SDL_JoystickNumButtons(joy.joystick) joy.numhats = sdl2.SDL_JoystickNumHats(joy.joystick) joy.numballs = sdl2.SDL_JoystickNumBalls(joy.joystick) joy.init_keys() except: pass # Try to get the gamepad object try: joy.gamecontroller = sdl2.SDL_GameControllerOpen(joy.identifier) # FromInstanceId does not Attach! # joy.gamecontroller = SDL_GameControllerFromInstanceID(SDL_JoystickInstanceID(joy.joystick) # print('ID:', SDL_GameControllerGetAttached(joy.gamecontroller)) except: joy.gamecontroller = None try: joy.guid = get_guid( joy.joystick ) # Using this is more reliable for the GameController stuff except: pass return joy
import sdl2 import time from math import radians from pyrr import Quaternion, Matrix44, Vector3 import numpy as np addr = 'tcp://localhost:38219' # ------------------------------- # Start SDL and find gamecontroller sdl2.SDL_Init(sdl2.SDL_INIT_TIMER | sdl2.SDL_INIT_JOYSTICK | sdl2.SDL_INIT_GAMECONTROLLER) if (sdl2.SDL_NumJoysticks() == 0): print("No Joysticks found") sdl2.SDL_Quit() exit(0) index = 0 joystick = sdl2.SDL_JoystickOpen(index) if joystick == None: print("Unable to open device") sdl2.SDL_Quit() exit(0) else: mappings = sdl2.SDL_GameControllerAddMappingsFromFile( b'gamecontrollerdb.txt') if sdl2.SDL_IsGameController(index) == 0: