Friday, February 01, 2008

Pyglet + Joystick

I've written a pygletified Joystick class. I'm not sure I'm using dispatch_events correctly, but it seems to work. With some more work it could support OSX and Win32.
from pyglet import event
import sys

if sys.platform == 'linux2':
import struct
from select import select

class Joystick(event.EventDispatcher):
JS_EVENT_BUTTON = 0x01 #/* button pressed/released */
JS_EVENT_AXIS = 0x02 #/* joystick moved */
JS_EVENT_INIT = 0x80 #/* initial state of device */
JS_EVENT = "IhBB"
JS_EVENT_SIZE = struct.calcsize(JS_EVENT)

def __init__(self, device_number):
device = '/dev/input/js%s' % device_number
event.EventDispatcher.__init__(self)
self.dev = open('/dev/input/js0')

def dispatch_events(self):
r,w,e = select([self.dev],[],[], 0)
if self.dev not in r: return
evt = self.dev.read(self.JS_EVENT_SIZE)
time, value, type, number = struct.unpack(self.JS_EVENT, evt)
evt = type & ~self.JS_EVENT_INIT
if evt == self.JS_EVENT_AXIS:
self.dispatch_event('on_axis', number, value)
elif evt == self.JS_EVENT_BUTTON:
self.dispatch_event('on_button', number, value==1)

def on_axis(self, axis, value):
pass

def on_button(self, button, pressed):
pass

Joystick.register_event_type('on_axis')
Joystick.register_event_type('on_button')

else:
raise ImportError('Platform not supported (%s)' % sys.platform)



if __name__ == "__main__":
j = Joystick(0)
@j.event
def on_button(button, pressed):
print 'button', button, pressed

@j.event
def on_axis(axis, value):
print 'axis', axis, value

while True:
j.dispatch_events()



6 comments:

Anonymous said...

Is there a reason you throw away the device variable in Joystick's __init__?

djfroofy said...

It looks like the device is hard-coded now in init for testing - probably just forgot to change. I would suggest (or request) making the device number a keyword argument defaulting to 0.

eedok said...

Can we get rumble? SDL has been lacking it for years

Simon Wittber said...

I would need to get hold a Joystick with force feedback first. Also, I would not write any code unless there is a standard interface for working with all JS models.

Mike said...

Very cool, thanks! Oh, and if anyone ever does get rumble feedback going, I'd be very interested in getting my hands on it for my research: http://memetic.ca

Mike

John Leimgruber said...

Handy joystick routine to get me up and running quick! Worked out of the box with an old junky usb joystick I have analog and all. I know folks have mentioned it about the device number, so I just added it in with a try except block:
try:
self.dev = open(device)
except:
print "Error opening %s" % device
sys.exit(0)

Popular Posts