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
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 vec3f(_Structure
):
42 _fields_
= [('x', c_float
),
47 class orient(_Structure
):
48 _fields_
= [('roll', c_float
),
56 return 'orient(roll=%f pitch=%f yaw=%f a_roll=%f a_pitch=%f)' % (
57 self
.roll
, self
.pitch
, self
.yaw
, self
.a_roll
, self
.a_pitch
)
59 class accel(_Structure
):
60 _fields_
= [('cal_zero', vec3b
),
63 ('st_pitch', c_float
),
64 ('st_alpha', c_float
),
67 class ir_dot(_Structure
):
68 _fields_
= [('visible', c_byte
),
78 _fields_
= [('dot', ir_dot
*4),
89 ('distance', c_float
),
96 for name
, typ
in self
._fields
_ :
98 pr('(%s, %s)' % (name
, getattr(self
, name
)))
103 class joystick(_Structure
):
104 _fields_
= [('max', vec2b
),
111 class nunchuk(_Structure
):
112 _fields_
= [('accel_calib', accel
),
114 ('flags', POINTER(c_int
)),
116 ('btns_held', c_byte
),
117 ('btns_released', c_byte
),
118 ('orient_threshold', c_float
),
119 ('accel_threshold', c_int
),
125 class classic_ctrl(_Structure
):
126 _fields_
= [('btns', c_short
),
127 ('btns_held', c_short
),
128 ('btns_released', c_short
),
129 ('r_shoulder', c_float
),
130 ('l_shoulder', c_float
),
135 class guitar_hero_3(_Structure
):
136 _fields_
= [('btns', c_short
),
137 ('btns_held', c_short
),
138 ('btns_released', c_short
),
139 ('whammy_bar', c_float
),
143 class expansion_union(Union
):
144 _fields_
= [('nunchuk', nunchuk
),
145 ('classic', classic_ctrl
),
146 ('gh3', guitar_hero_3
),
149 class expansion(_Structure
):
150 _fields_
= [('type', c_int
),
151 ('u', expansion_union
),
154 class wiimote_state(_Structure
):
155 _fields_
= [('exp_ljs_ang', c_float
),
156 ('exp_rjs_ang', c_float
),
157 ('exp_ljs_mag', c_float
),
158 ('exp_rjs_mag', c_float
),
159 ('exp_btns', c_uint16
),
160 ('exp_orient', orient
),
161 ('exp_accel', vec3b
),
162 ('exp_r_shoulder', c_float
),
163 ('exp_l_shoulder', c_float
),
166 ('ir_distance', c_float
),
173 JunkSkip
= [('dev_handle', c_void_p
),
174 ('hid_overlap', c_void_p
*5), # skipping over this data structure
177 ('normal_timeout', c_byte
),
178 ('exp_timeout', c_byte
),
181 JunkSkip
= [('bdaddr', c_void_p
),
182 ('bdaddr_str', c_char
*18),
191 UNEXPECTED_DISCONNECT
= 5
195 CLASSIC_CTRL_INSERTED
= 9
196 CLASSIC_CTRL_REMOVED
= 10
197 GUITAR_HERO_3_CTRL_INSERTED
= 11
198 GUITAR_HERO_3_CTRL_REMOVED
= 12
200 class wiimote(_Structure
):
201 _fields_
= [('unid', c_int
),
205 ('battery_level', c_float
),
207 ('handshake_state', c_byte
),
208 ('read_req', c_void_p
),
209 ('accel_calib', accel
),
216 ('btns_held', c_uint16
),
217 ('btns_released', c_uint16
),
218 ('orient_threshold', c_float
),
219 ('accel_threshold', c_int
),
220 ('lstate', wiimote_state
),
222 ('event_buf', c_byte
*32),
225 wiimote_p
= POINTER(wiimote
)
226 wiimote_pp
= POINTER(wiimote_p
)
228 # make function prototypes a bit easier to declare
229 def cfunc(name
, dll
, result
, *args
):
230 '''build and apply a ctypes prototype complete with parameter flags
232 cvMinMaxLoc = cfunc('cvMinMaxLoc', _cxDLL, None,
233 ('image', POINTER(IplImage), 1),
234 ('min_val', POINTER(double), 2),
235 ('max_val', POINTER(double), 2),
236 ('min_loc', POINTER(CvPoint), 2),
237 ('max_loc', POINTER(CvPoint), 2),
238 ('mask', POINTER(IplImage), 1, None))
239 means locate cvMinMaxLoc in dll _cxDLL, it returns nothing.
240 The first argument is an input image. The next 4 arguments are output, and the last argument is
241 input with an optional value. A typical call might look like:
243 min_val,max_val,min_loc,max_loc = cvMinMaxLoc(img)
248 atypes
.append(arg
[1])
249 aflags
.append((arg
[2], arg
[0]) + arg
[3:])
250 return CFUNCTYPE(result
, *atypes
)((name
, dll
), tuple(aflags
))
252 # get the shared library
253 lib
= find_library('wiiuse') or find_library('libwiiuse')
254 dll
= cdll
.LoadLibrary(lib
)
257 # dll = cdll.LoadLibrary('wiiuse.dll')
259 # dll = cdll.LoadLibrary('libwiiuse.so')
261 # access the functions
262 init
= cfunc('wiiuse_init', dll
, wiimote_pp
,
263 ('wiimotes', c_int
, 1))
264 # find = cfunc('wiiuse_find', dll, c_int,
265 # ('wm', wiimote_pp, 1),
266 # ('max_wiimotes', c_int, 1),
267 # ('timeout', c_int, 1))
268 # connect = cfunc('wiiuse_connect', dll, c_int,
269 # ('wm', wiimote_pp, 1),
270 # ('wiimotes', c_int, 1))
271 # poll = cfunc('wiiuse_poll', dll, c_int,
272 # ('wm', wiimote_pp, 1),
273 # ('wiimotes', c_int, 1))
274 find
= dll
.wiiuse_find
275 connect
= dll
.wiiuse_connect
276 poll
= dll
.wiiuse_poll
277 set_leds
= dll
.wiiuse_set_leds
278 motion_sensing
= dll
.wiiuse_motion_sensing
279 set_accel_threshold
= dll
.wiiuse_set_accel_threshold
280 set_orient_threshold
= dll
.wiiuse_set_orient_threshold
281 set_orient_threshold
.argtypes
= [wiimote_p
, c_float
]
282 set_timeout
= dll
.wiiuse_set_timeout
283 set_ir
= dll
.wiiuse_set_ir
285 def is_pressed(dev
, button
):
286 return dev
.btns
& button
288 def is_held(dev
, button
):
289 return dev
.btns_held
& button
291 def is_released(dev
, button
):
292 return dev
.btns_released
& button
294 def is_just_pressed(dev
, button
):
295 return is_pressed(dev
, button
) and not is_held(dev
, button
)
298 return wm
.state
& 0x10
301 return wm
.state
& 0x20
304 return wm
.state
& 0x40
312 LED
= [LED_1
, LED_2
, LED_3
, LED_4
]
321 INIT_FLAGS
= SMOOTHING | ORIENT_THRESH
329 button
= { '2':0x0001,
342 nunchuk_button
= { 'Z':0x01,
347 if __name__
== '__main__':
348 def handle_event(wm
):
349 print 'EVENT', wm
.unid
, wm
.btns
350 #print wm.gforce.x, wm.gforce.y, wm.gforce.z
354 wiimotes
= init(nmotes
)
356 found
= find(wiimotes
, nmotes
, 2)
358 print 'no wiimotes found'
361 connected
= connect(wiimotes
, nmotes
)
363 print 'connected to %d wiimotes (of %d found)' % (connected
, found
)
365 print 'failed to connect to any wiimote.'
368 set_leds(wiimotes
[0], 0x20)
369 motion_sensing(wiimotes
[0], 1)
370 set_ir(wiimotes
[0], 1)
374 if poll(wiimotes
, nmotes
):
376 for i
in range(nmotes
):
378 if wiimotes
[i
][0].event
== EVENT
:
379 handle_event(wiimotes
[i
][0])
380 except KeyboardInterrupt :