I had a question about a C extension I once have written, for wrapping up joystick input under Windows
(https://discourse.panda3d.org/viewtopic.php?t=2270).
I still can provide a compiled version for Python 2.5 if anybody is interested, but there is another way to get joystick input: using the ctypes module. Advantage: no need to compile any C/C++ code.
enn0x
test.py
import joystick
import time
print 'num joysticks:', joystick.Joystick.getNumJosticks( )
j = joystick.Joystick( 0 )
print 'j num axes:', j.numAxes( )
print 'j num buttons:', j.numButtons( )
print 'j name:', ( j.name( ), )
while 1:
time.sleep( 0.2 )
j.update( )
x = j.getX( )
y = j.getY( )
z = j.getZ( )
r = j.getR( )
pov = j.getPOV( )
b0 = j.getButton( 0 )
b1 = j.getButton( 1 )
b2 = j.getButton( 2 )
b3 = j.getButton( 3 )
print x, y, z, r, pov, b0, b1, b2, b3
#print [ j.getButton( i ) for i in range( j.numButtons( ) ) ]
joystick.py
from ctypes import *
winmm = windll.winmm
class JOYINFOEX( Structure ):
_pack_ = 1
_fields_ = [ ( 'dwSize', c_long ),
( 'dwFlags', c_long ),
( 'dwXpos', c_long ),
( 'dwYpos', c_long ),
( 'dwZpos', c_long ),
( 'dwRpos', c_long ),
( 'dwUpos', c_long ),
( 'dwVpos', c_long ),
( 'dwButtons', c_long ),
( 'dwButtonNumber', c_long ),
( 'dwPOV', c_long ),
( 'dwReserved1', c_long ),
( 'dwReserved2', c_long ),
]
class JOYCAPSA( Structure ):
_pack_ = 1
_fields_ = [ ( 'wMid', c_short ),
( 'wPid', c_short ),
( 'szPname', c_char * 32 ),
( 'wXmin', c_uint ),
( 'wXmax', c_uint ),
( 'wYmin', c_uint ),
( 'wYmax', c_uint ),
( 'wZmin', c_uint ),
( 'wZmax', c_uint ),
( 'wNumButtons', c_uint ),
( 'wPeriodMin', c_uint ),
( 'wPeriodMax', c_uint ),
( 'wRmin', c_uint ),
( 'wRmax', c_uint ),
( 'wUmin', c_uint ),
( 'wUmax', c_uint ),
( 'wVmin', c_uint ),
( 'wVmax', c_uint ),
( 'wCaps', c_uint ),
( 'wMaxAxes', c_uint ),
( 'wNumAxes', c_uint ),
( 'wMaxButtons', c_uint ),
( 'szRegKey', c_char * 32 ),
( 'szOEMVxD', c_char * 260 ),
]
class Joystick:
def __init__( self, id ):
self.jid = c_uint( id )
self.info = JOYINFOEX( )
self.info.dwFlags = c_long( 255 )
self.info.dwSize = sizeof( self.info ) * 8
@staticmethod
def getNumJosticks( ):
nmax = winmm.joyGetNumDevs( );
n = 0
for i in range( nmax ):
result = winmm.joyGetPos( c_uint( i ), byref( JOYINFOEX( ) ) )
if result == 0:
n += 1
return n
@staticmethod
def parametric( x ):
if x < 32767: x -= 32768
else: x -= 32767
return float( x ) / 32768.0
def update( self ):
winmm.joyGetPosEx( self.jid, byref( self.info ) )
def getX( self ):
return self.parametric( self.info.dwXpos )
def getY( self ):
return self.parametric( self.info.dwYpos )
def getZ( self ):
return self.parametric( self.info.dwZpos )
def getR( self ):
return self.parametric( self.info.dwRpos )
def getU( self ):
return self.parametric( self.info.dwUpos )
def getV( self ):
return self.parametric( self.info.dwVpos )
def getPOV( self ):
return self.info.dwPOV / 100
def getButton( self, btn ):
state = self.info.dwButtons & ( 1 << btn )
return state and True or False
def caps( self ):
caps = JOYCAPSA( )
capssize = c_uint( sizeof( caps ) * 8 )
capssize = c_uint( 404 )
result = winmm.joyGetDevCapsA( self.jid, byref( caps ), capssize )
return caps
def numAxes( self ):
return self.caps( ).wNumAxes
def numButtons( self ):
return self.caps( ).wNumButtons
def name( self ):
return self.caps( ).szPname