3

I'm playing with the new(ish) SDL2 wrapper for python, PySDL2, and I can't seem to see any joystick events popping up on the event queue. Keydown events are fine, and when I explicitly poll the joystick, I can get the axis state fine (and observe that it changes as I move the axis, as expected). Here's my code using the queue:

import sdl2
import sdl2.ext
sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)
sdl2.SDL_Init(sdl2.SDL_INIT_JOYSTICK)
joystick = sdl2.SDL_JoystickOpen(0)
sdl2.ext.Window("test", size=(800,600),position=(0,0),flags=sdl2.SDL_WINDOW_SHOWN)
window.refresh()) 
while True:
    for event in sdl2.ext.get_events():
        if event.type==sdl2.SDL_KEYDOWN:
            print sdl2.SDL_GetKeyName(event.key.keysym.sym).lower()
        elif event.type==sdl2.SDL_JOYAXISMOTION:
            print [event.jaxis.axis,event.jaxis.value]

This prints out all the keydown occurrences, but never any axis motion events. In contrast, here's my code to explicitly poll the axis state:

import sdl2
import sdl2.ext
sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)
sdl2.SDL_Init(sdl2.SDL_INIT_JOYSTICK)
joystick = sdl2.SDL_JoystickOpen(0)

while True:
    sdl2.SDL_PumpEvents()
    print sdl2.SDL_JoystickGetAxis(joystick,0)

Which works fine, but I don't want to waste time polling the state if it's not changing, so I'd prefer the event queue method if I could get it working. Any suggestions?

If it matters, I'm running python 2.7.5 on Mac OS 10.9. I've tried both a logitech usb gamepad and an xbox 360 wired gamepad (enabled via the tattiebogle.net drivers). Above I discuss the axis events because that's what I need, but I've checked and none of the joystick events post to the event queue.

Mike Lawrence
  • 1,641
  • 5
  • 20
  • 40
  • Sorry, but I cannot duplicate this. For one thing, with the code you have as it is, you won't get any output because you haven't actually opened up a window. Did you just leave this out? What happens if you actually open a window (using `SDL_CreateWindow(...)`)?I have used your code exactly (except with a window open) and things work fine. I get the axis events to print out. What type of joystick are you using? Have you tried building SDL with DEBUG_JOYSTICK and DEBUG_INPUT_EVENTS enabled? – Mark Hildreth Nov 01 '13 at 00:27
  • Interesting. The code does indeed print output without a window, and adding a window (via `window = sdl2.ext.Window("test", size=(800,600),position=(0,0),flags=sdl2.SDL_WINDOW_SHOWN); window.refresh()`) doesn't change the behaviour reported above. I didn't compile SDL2 myself, but instead simply installed the mac framework. I'll try grabbing the source and building with the debugs as you suggest. – Mike Lawrence Nov 01 '13 at 12:19
  • Actually, while I'm familiar with the `./configure; make; sudo make install`, I'm not sure how to add the debug flags... – Mike Lawrence Nov 01 '13 at 12:39
  • You should be able to define them in the environment variable `CFLAGS`. – Mark Hildreth Nov 01 '13 at 15:11
  • @MarkHildreth Turns out that everything works fine if I build SDL2 from source rather than use the pre-build mac framework. Care to post an answer to get credit for your help? – Mike Lawrence Nov 01 '13 at 17:15
  • Go ahead and post the answer yourself. Make sure to include the version numbers you were using. – Mark Hildreth Nov 01 '13 at 18:09

2 Answers2

3

It turns out that building SDL2 (2.0-1; accessed via PySDL2-0.7.0) from source yields a build for which joystick events do post to the event queue (though you do need to create a window). Seems that the trouble is with the mac framework version of SDL2 (from here) I was using.

Mike Lawrence
  • 1,641
  • 5
  • 20
  • 40
2
import ctypes
import time
from sdl2 import *


class Joystick:
    def __init__(self):
        SDL_Init(SDL_INIT_JOYSTICK)
        self.axis = {}
        self.button = {}

    def update(self):
        event = SDL_Event()
        while SDL_PollEvent(ctypes.byref(event)) != 0:
            if event.type == SDL_JOYDEVICEADDED:
                self.device = SDL_JoystickOpen(event.jdevice.which)
            elif event.type == SDL_JOYAXISMOTION:
                self.axis[event.jaxis.axis] = event.jaxis.value
            elif event.type == SDL_JOYBUTTONDOWN:
                self.button[event.jbutton.button] = True
            elif event.type == SDL_JOYBUTTONUP:
                self.button[event.jbutton.button] = False


if __name__ == "__main__":
    joystick = Joystick()
    while True:
        joystick.update()
        time.sleep(0.1)
        print(joystick.axis)
        print(joystick.button)
wedesoft
  • 2,781
  • 28
  • 25