1 '''Python interface to the wiiuse library for the wii remote
3 Just a simple wrapper, no attempt to make the api pythonic. I tried to hide ctypes where
6 This software is free for any use. If you or your lawyer are stupid enough to believe I have any
7 liability for it, then don't use it; otherwise, be my guest.
9 Gary Bishop, January 2008
10 hacked for new API and data June 2009
15 from ctypes
import c_char_p
, c_int
, c_byte
, c_uint
, c_uint16
, c_float
, c_short
, c_void_p
, c_char
, c_ubyte
, c_ushort
16 from ctypes
import CFUNCTYPE
, Structure
, POINTER
, Union
, byref
, cdll
17 from ctypes
.util
import find_library
20 # duplicate the wiiuse data structures
22 class _Structure(Structure
):
24 '''Print the fields'''
26 for field
in self
._fields
_:
27 res
.append('%s=%s' % (field
[0], repr(getattr(self
, field
[0]))))
28 return self
.__class
__.__name
__ + '(' + ','.join(res
) + ')'
30 class vec2b(_Structure
):
31 _fields_
= [('x', c_byte
),
35 class vec3b(_Structure
):
36 _fields_
= [('x', c_byte
),
41 class vec3w(_Structure
):
42 _fields_
= [('x', c_ushort
),
47 class vec3f(_Structure
):
48 _fields_
= [('x', c_float
),
53 class orient(_Structure
):
54 _fields_
= [('roll', c_float
),
62 return 'orient(roll=%f pitch=%f yaw=%f a_roll=%f a_pitch=%f)' % (
63 self
.roll
, self
.pitch
, self
.yaw
, self
.a_roll
, self
.a_pitch
)
65 class accel(_Structure
):
66 _fields_
= [('cal_zero', vec3w
),
69 ('st_pitch', c_float
),
70 ('st_alpha', c_float
),
73 class ir_dot(_Structure
):
74 _fields_
= [('visible', c_byte
),
84 _fields_
= [('dot', ir_dot
*4),
95 ('distance', c_float
),
102 for name
, typ
in self
._fields
_ :
104 pr('(%s, %s)' % (name
, getattr(self
, name
)))
109 class joystick(_Structure
):
110 _fields_
= [('max', vec2b
),
117 class nunchuk(_Structure
):
118 _fields_
= [('accel_calib', accel
),
120 ('flags', POINTER(c_int
)),
122 ('btns_last', c_byte
),
123 ('btns_held', c_byte
),
124 ('btns_released', c_byte
),
125 ('orient_threshold', c_float
),
126 ('accel_threshold', c_float
),
132 class classic_ctrl(_Structure
):
133 _fields_
= [('btns', c_short
),
134 ('btns_last', c_short
),
135 ('btns_held', c_short
),
136 ('btns_released', c_short
),
137 ('r_shoulder', c_float
),
138 ('l_shoulder', c_float
),
143 class guitar_hero_3(_Structure
):
144 _fields_
= [('btns', c_short
),
145 ('btns_last', c_short
),
146 ('btns_held', c_short
),
147 ('btns_released', c_short
),
148 ('whammy_bar', c_float
),
152 class motion_plus(_Structure
):
153 _fields_
= [('rx', c_short
),
160 class expansion_union(Union
):
161 _fields_
= [('nunchuk', nunchuk
),
162 ('classic', classic_ctrl
),
163 ('gh3', guitar_hero_3
),
167 class expansion(_Structure
):
168 _fields_
= [('type', c_int
),
169 ('u', expansion_union
),
172 class wiimote_state(_Structure
):
173 _fields_
= [('exp_ljs_ang', c_float
),
174 ('exp_rjs_ang', c_float
),
175 ('exp_ljs_mag', c_float
),
176 ('exp_rjs_mag', c_float
),
177 ('exp_btns', c_ushort
),
178 ('exp_orient', orient
),
179 ('exp_accel', vec3w
),
180 ('exp_r_shoulder', c_float
),
181 ('exp_l_shoulder', c_float
),
187 ('ir_distance', c_float
),
195 JunkSkip
= [('dev_handle', c_void_p
),
196 ('hid_overlap', c_void_p
*5), # skipping over this data structure
199 ('normal_timeout', c_byte
),
200 ('exp_timeout', c_byte
),
203 elif sys
.platform
== 'darwin' :
204 JunkSkip
= [('device', c_void_p
),
205 ('bdaddr_str', c_char
*18)
209 JunkSkip
= [('bdaddr', c_void_p
),
210 ('bdaddr_str', c_char
*18),
219 UNEXPECTED_DISCONNECT
= 5
223 CLASSIC_CTRL_INSERTED
= 9
224 CLASSIC_CTRL_REMOVED
= 10
225 GUITAR_HERO_3_CTRL_INSERTED
= 11
226 GUITAR_HERO_3_CTRL_REMOVED
= 12
228 class wiimote(_Structure
):
229 _fields_
= [('unid', c_int
),
233 ('battery_level', c_float
),
237 ('handshake_state', c_byte
),
238 ('expansion_state', c_ubyte
),
239 ('read_req', c_void_p
),
240 ('data_req', c_void_p
),
242 ('cmd_head', c_void_p
),
243 ('cmd_tail', c_void_p
),
244 ('accel_calib', accel
),
254 ('btns_last', c_ushort
),
255 ('btns_held', c_ushort
),
256 ('btns_released', c_ushort
),
257 ('orient_threshold', c_float
),
258 ('accel_threshold', c_int
),
260 ('lstate', wiimote_state
),
263 ('event_buf', c_byte
*32),
264 ('motion_plus_id', c_ubyte
*6)
267 wiimote_p
= POINTER(wiimote
)
268 wiimote_pp
= POINTER(wiimote_p
)
270 # make function prototypes a bit easier to declare
271 def cfunc(name
, dll
, result
, *args
):
272 '''build and apply a ctypes prototype complete with parameter flags
274 cvMinMaxLoc = cfunc('cvMinMaxLoc', _cxDLL, None,
275 ('image', POINTER(IplImage), 1),
276 ('min_val', POINTER(double), 2),
277 ('max_val', POINTER(double), 2),
278 ('min_loc', POINTER(CvPoint), 2),
279 ('max_loc', POINTER(CvPoint), 2),
280 ('mask', POINTER(IplImage), 1, None))
281 means locate cvMinMaxLoc in dll _cxDLL, it returns nothing.
282 The first argument is an input image. The next 4 arguments are output, and the last argument is
283 input with an optional value. A typical call might look like:
285 min_val,max_val,min_loc,max_loc = cvMinMaxLoc(img)
290 atypes
.append(arg
[1])
291 aflags
.append((arg
[2], arg
[0]) + arg
[3:])
292 return CFUNCTYPE(result
, *atypes
)((name
, dll
), tuple(aflags
))
294 # get the shared library
295 lib
= find_library('wiiuse') or find_library('libwiiuse')
296 dll
= cdll
.LoadLibrary(lib
)
299 # dll = cdll.LoadLibrary('wiiuse.dll')
301 # dll = cdll.LoadLibrary('libwiiuse.so')
303 # access the functions
304 init
= cfunc('wiiuse_init', dll
, wiimote_pp
,
305 ('wiimotes', c_int
, 1))
306 # find = cfunc('wiiuse_find', dll, c_int,
307 # ('wm', wiimote_pp, 1),
308 # ('max_wiimotes', c_int, 1),
309 # ('timeout', c_int, 1))
310 # connect = cfunc('wiiuse_connect', dll, c_int,
311 # ('wm', wiimote_pp, 1),
312 # ('wiimotes', c_int, 1))
313 # poll = cfunc('wiiuse_poll', dll, c_int,
314 # ('wm', wiimote_pp, 1),
315 # ('wiimotes', c_int, 1))
316 find
= dll
.wiiuse_find
317 connect
= dll
.wiiuse_connect
318 poll
= dll
.wiiuse_poll
319 set_leds
= dll
.wiiuse_set_leds
320 motion_sensing
= dll
.wiiuse_motion_sensing
321 set_accel_threshold
= dll
.wiiuse_set_accel_threshold
322 set_orient_threshold
= dll
.wiiuse_set_orient_threshold
323 set_orient_threshold
.argtypes
= [wiimote_p
, c_float
]
324 set_timeout
= dll
.wiiuse_set_timeout
325 set_ir
= dll
.wiiuse_set_ir
326 set_ir_position
= dll
.wiiuse_set_ir_position
327 set_ir_vres
= dll
.wiiuse_set_ir_vres
329 def is_pressed(dev
, button
):
330 return dev
.btns
& button
332 def is_held(dev
, button
):
333 return dev
.btns_held
& button
335 def is_released(dev
, button
):
336 return dev
.btns_released
& button
338 def is_just_pressed(dev
, button
):
339 return is_pressed(dev
, button
) and not is_held(dev
, button
)
342 return wm
.state
& 0x10
345 return wm
.state
& 0x20
348 return wm
.state
& 0x40
356 LED
= [LED_1
, LED_2
, LED_3
, LED_4
]
365 INIT_FLAGS
= SMOOTHING | ORIENT_THRESH
373 button
= { '2':0x0001,
386 nunchuk_button
= { 'Z':0x01,
391 if __name__
== '__main__':
392 def handle_event(wm
):
393 print 'EVENT', wm
.unid
, wm
.btns
394 #print wm.gforce.x, wm.gforce.y, wm.gforce.z
398 wiimotes
= init(nmotes
)
400 found
= find(wiimotes
, nmotes
, 2)
402 print 'no wiimotes found'
405 connected
= connect(wiimotes
, nmotes
)
407 print 'connected to %d wiimotes (of %d found)' % (connected
, found
)
409 print 'failed to connect to any wiimote.'
412 set_leds(wiimotes
[0], 0x20)
413 motion_sensing(wiimotes
[0], 1)
414 set_ir(wiimotes
[0], 1)
418 if poll(wiimotes
, nmotes
):
420 for i
in range(nmotes
):
422 if wiimotes
[i
][0].event
== EVENT
:
423 handle_event(wiimotes
[i
][0])
424 except KeyboardInterrupt :