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
19 # duplicate the wiiuse data structures
21 class _Structure(Structure
):
23 '''Print the fields'''
25 for field
in self
._fields
_:
26 res
.append('%s=%s' % (field
[0], repr(getattr(self
, field
[0]))))
27 return self
.__class
__.__name
__ + '(' + ','.join(res
) + ')'
29 class vec2b(_Structure
):
30 _fields_
= [('x', c_byte
),
34 class vec3b(_Structure
):
35 _fields_
= [('x', c_byte
),
40 class vec3f(_Structure
):
41 _fields_
= [('x', c_float
),
46 class orient(_Structure
):
47 _fields_
= [('roll', c_float
),
55 return 'orient(roll=%f pitch=%f yaw=%f a_roll=%f a_pitch=%f)' % (
56 self
.roll
, self
.pitch
, self
.yaw
, self
.a_roll
, self
.a_pitch
)
58 class accel(_Structure
):
59 _fields_
= [('cal_zero', vec3b
),
62 ('st_pitch', c_float
),
63 ('st_alpha', c_float
),
66 class ir_dot(_Structure
):
67 _fields_
= [('visible', c_byte
),
77 _fields_
= [('dot', ir_dot
*4),
88 ('distance', c_float
),
92 class joystick(_Structure
):
93 _fields_
= [('max', vec2b
),
100 class nunchuk(_Structure
):
101 _fields_
= [('accel_calib', accel
),
103 ('flags', POINTER(c_int
)),
105 ('btns_held', c_byte
),
106 ('btns_released', c_byte
),
107 ('orient_threshold', c_float
),
108 ('accel_threshold', c_int
),
114 class classic_ctrl(_Structure
):
115 _fields_
= [('btns', c_short
),
116 ('btns_held', c_short
),
117 ('btns_released', c_short
),
118 ('r_shoulder', c_float
),
119 ('l_shoulder', c_float
),
124 class guitar_hero_3(_Structure
):
125 _fields_
= [('btns', c_short
),
126 ('btns_held', c_short
),
127 ('btns_released', c_short
),
128 ('whammy_bar', c_float
),
132 class expansion_union(Union
):
133 _fields_
= [('nunchuk', nunchuk
),
134 ('classic', classic_ctrl
),
135 ('gh3', guitar_hero_3
),
138 class expansion(_Structure
):
139 _fields_
= [('type', c_int
),
140 ('u', expansion_union
),
143 class wiimote_state(_Structure
):
144 _fields_
= [('exp_ljs_ang', c_float
),
145 ('exp_rjs_ang', c_float
),
146 ('exp_ljs_mag', c_float
),
147 ('exp_rjs_mag', c_float
),
148 ('exp_btns', c_uint16
),
149 ('exp_orient', orient
),
150 ('exp_accel', vec3b
),
151 ('exp_r_shoulder', c_float
),
152 ('exp_l_shoulder', c_float
),
155 ('ir_distance', c_float
),
162 JunkSkip
= [('dev_handle', c_void_p
),
163 ('hid_overlap', c_void_p
*5), # skipping over this data structure
166 ('normal_timeout', c_byte
),
167 ('exp_timeout', c_byte
),
170 JunkSkip
= [('bdaddr', c_void_p
),
171 ('bdaddr_str', c_char
*18),
180 UNEXPECTED_DISCONNECT
= 5
184 CLASSIC_CTRL_INSERTED
= 9
185 CLASSIC_CTRL_REMOVED
= 10
186 GUITAR_HERO_3_CTRL_INSERTED
= 11
187 GUITAR_HERO_3_CTRL_REMOVED
= 12
189 class wiimote(_Structure
):
190 _fields_
= [('unid', c_int
),
194 ('battery_level', c_float
),
196 ('handshake_state', c_byte
),
197 ('read_req', c_void_p
),
198 ('accel_calib', accel
),
205 ('btns_held', c_uint16
),
206 ('btns_released', c_uint16
),
207 ('orient_threshold', c_float
),
208 ('accel_threshold', c_int
),
209 ('lstate', wiimote_state
),
211 ('event_buf', c_byte
*32),
214 wiimote_p
= POINTER(wiimote
)
215 wiimote_pp
= POINTER(wiimote_p
)
217 # make function prototypes a bit easier to declare
218 def cfunc(name
, dll
, result
, *args
):
219 '''build and apply a ctypes prototype complete with parameter flags
221 cvMinMaxLoc = cfunc('cvMinMaxLoc', _cxDLL, None,
222 ('image', POINTER(IplImage), 1),
223 ('min_val', POINTER(double), 2),
224 ('max_val', POINTER(double), 2),
225 ('min_loc', POINTER(CvPoint), 2),
226 ('max_loc', POINTER(CvPoint), 2),
227 ('mask', POINTER(IplImage), 1, None))
228 means locate cvMinMaxLoc in dll _cxDLL, it returns nothing.
229 The first argument is an input image. The next 4 arguments are output, and the last argument is
230 input with an optional value. A typical call might look like:
232 min_val,max_val,min_loc,max_loc = cvMinMaxLoc(img)
237 atypes
.append(arg
[1])
238 aflags
.append((arg
[2], arg
[0]) + arg
[3:])
239 return CFUNCTYPE(result
, *atypes
)((name
, dll
), tuple(aflags
))
241 # get the shared library
243 dll
= cdll
.LoadLibrary('wiiuse.dll')
245 dll
= cdll
.LoadLibrary('libwiiuse.so')
247 # access the functions
248 init
= cfunc('wiiuse_init', dll
, wiimote_pp
,
249 ('wiimotes', c_int
, 1))
250 # find = cfunc('wiiuse_find', dll, c_int,
251 # ('wm', wiimote_pp, 1),
252 # ('max_wiimotes', c_int, 1),
253 # ('timeout', c_int, 1))
254 # connect = cfunc('wiiuse_connect', dll, c_int,
255 # ('wm', wiimote_pp, 1),
256 # ('wiimotes', c_int, 1))
257 # poll = cfunc('wiiuse_poll', dll, c_int,
258 # ('wm', wiimote_pp, 1),
259 # ('wiimotes', c_int, 1))
260 find
= dll
.wiiuse_find
261 connect
= dll
.wiiuse_connect
262 poll
= dll
.wiiuse_poll
263 set_leds
= dll
.wiiuse_set_leds
264 motion_sensing
= dll
.wiiuse_motion_sensing
265 set_accel_threshold
= dll
.wiiuse_set_accel_threshold
266 set_orient_threshold
= dll
.wiiuse_set_orient_threshold
267 set_orient_threshold
.argtypes
= [wiimote_p
, c_float
]
268 set_timeout
= dll
.wiiuse_set_timeout
270 def is_pressed(dev
, button
):
271 return dev
.btns
& button
273 def is_held(dev
, button
):
274 return dev
.btns_held
& button
276 def is_released(dev
, button
):
277 return dev
.btns_released
& button
279 def is_just_pressed(dev
, button
):
280 return is_pressed(dev
, button
) and not is_held(dev
, button
)
283 return wm
.state
& 0x10
286 return wm
.state
& 0x20
289 return wm
.state
& 0x40
297 LED
= [LED_1
, LED_2
, LED_3
, LED_4
]
306 INIT_FLAGS
= SMOOTHING | ORIENT_THRESH
314 button
= { '2':0x0001,
327 nunchuk_button
= { 'Z':0x01,
332 if __name__
== '__main__':
333 def handle_event(wm
):
334 print 'EVENT', wm
.unid
, wm
.btns
335 print wm
.gforce
.x
, wm
.gforce
.y
, wm
.gforce
.z
338 wiimotes
= init(nmotes
)
340 found
= find(wiimotes
, nmotes
, 2)
342 print 'no wiimotes found'
345 connected
= connect(wiimotes
, nmotes
)
347 print 'connected to %d wiimotes (of %d found)' % (connected
, found
)
349 print 'failed to connect to any wiimote.'
352 set_leds(wiimotes
[0], 0x50)
353 motion_sensing(wiimotes
[0], 1)
356 if poll(wiimotes
, nmotes
):
357 for i
in range(nmotes
):
359 if wiimotes
[i
][0].event
== EVENT
:
360 handle_event(wiimotes
[i
][0])