1 '''Access to the Wiimote in pygame
3 I tried to mimic the Joystick interface already in pygame.
7 init the module telling it the maximum number of wiimotes and the timeout
8 get_count to determine how many you got
9 Wiimote(n) to get an object referencing the nth wiimote
11 Free for any use. If you or your lawyer are stupid enough to believe I have any liability for
12 this, then don't use it; otherwise be my guest.
14 Gary Bishop January 2008
19 from threading
import Thread
20 from Queue
import Queue
, Empty
23 # events to use. Is there a way to get ones known to be unused?
24 base
= pygame
.USEREVENT
25 print 'pygame_wiimote base :', pygame
.USEREVENT
26 WIIMOTE_BUTTON_PRESS
= base
+ 1
27 WIIMOTE_BUTTON_RELEASE
= base
+ 2
28 WIIMOTE_ACCEL
= base
+ 3
30 NUNCHUK_BUTTON_PRESS
= base
+ 5
31 NUNCHUK_BUTTON_RELEASE
= base
+ 6
32 NUNCHUK_ACCEL
= base
+ 7
33 NUNCHUK_JOY
= base
+ 8
34 WIIMOTE_STATUS
= base
+ 9
35 WIIMOTE_DISCONNECT
= base
+ 10
36 pygame
.USEREVENT
= WIIMOTE_DISCONNECT
37 if pygame
.USEREVENT
> pygame
.NUMEVENTS
:
38 pygame
.NUMEVENTS
= pygame
.USEREVENT
41 wiiuse
= None # import within the thread, why do I have to do this?
43 class wiimote_thread(Thread
):
44 '''Manage the wiiuse interface'''
45 def __init__(self
, nmotes
=1, timeout
=5):
46 Thread
.__init
__(self
, name
='wiimote')
48 self
.startup
= Queue()
50 self
.timeout
= timeout
53 self
.startup
.get(True) # wait for the thread to get started and acquire the motes
56 '''This runs in a separate thread'''
58 import PyWiiUse
as wiiuse
# import here to avoid thread problems on windows
59 self
.wiimotes
= wiiuse
.init(self
.nmotes
)
60 found
= wiiuse
.find(self
.wiimotes
, self
.nmotes
, self
.timeout
)
61 self
.actual_nmotes
= wiiuse
.connect(self
.wiimotes
, self
.nmotes
)
63 for i
in range(self
.nmotes
):
64 wiiuse
.set_leds(self
.wiimotes
[i
], wiiuse
.LED
[i
])
66 self
.go
= self
.actual_nmotes
!= 0
68 self
.startup
.put(self
.go
)
72 if wiiuse
.poll(self
.wiimotes
, self
.nmotes
) :
73 for i
in range(self
.nmotes
):
75 if m
[0].event
== wiiuse
.EVENT
:
81 # wiiuse.poll(self.wiimotes, self.nmotes)
85 # allow executing functions in this thread
88 func
, args
= self
.queue
.get_nowait()
91 print 'do:', func
.__name
__, args
94 def do(self
, func
, *args
):
95 '''Run the function in the thread handling the wiimote'''
96 self
.queue
.put((func
, args
))
98 def event_cb(self
, wmp
):
99 '''Called when the library has some data for the user.'''
102 for name
,b
in wiiuse
.button
.items():
103 if wiiuse
.is_just_pressed(wm
, b
):
104 pygame
.event
.post(pygame
.event
.Event(WIIMOTE_BUTTON_PRESS
, button
=name
,
109 for name
,b
in wiiuse
.button
.items():
110 if wiiuse
.is_released(wm
, b
):
111 pygame
.event
.post(pygame
.event
.Event(WIIMOTE_BUTTON_RELEASE
, button
=name
,
116 pygame
.event
.post(pygame
.event
.Event(WIIMOTE_ACCEL
,
117 orient
=(wm
.orient
.roll
, wm
.orient
.pitch
,
119 accel
=(wm
.gforce
.x
, wm
.gforce
.y
, wm
.gforce
.z
),
123 dots
= [ (wm
.ir
.dot
[i
].visible
, wm
.ir
.dot
[i
].x
, wm
.ir
.dot
[i
].y
) for i
in range(4) ]
124 pygame
.event
.post(pygame
.event
.Event(WIIMOTE_IR
,
126 cursor
=(wm
.ir
.x
, wm
.ir
.y
, wm
.ir
.z
),
130 if wm
.exp
.type == wiiuse
.EXP_NUNCHUK
:
131 nc
= wm
.exp
.u
.nunchuk
133 for name
,b
in wiiuse
.nunchuk_button
.items():
134 if wiiuse
.is_just_pressed(nc
, b
):
135 pygame
.event
.post(pygame
.event
.Event(NUNCHUK_BUTTON_PRESS
, button
=name
,
138 elif wiiuse
.is_released(nc
, b
):
139 pygame
.event
.post(pygame
.event
.Event(NUNCHUK_BUTTON_RELEASE
, button
=name
,
143 pygame
.event
.post(pygame
.event
.Event(NUNCHUK_ACCEL
,
144 orient
=(nc
.orient
.roll
, nc
.orient
.pitch
,
146 accel
=(nc
.gforce
.x
, nc
.gforce
.y
, nc
.gforce
.z
),
149 pygame
.event
.post(pygame
.event
.Event(NUNCHUK_JOY
,
155 def control_cb(self
, wmp
, attachment
, speaker
, ir
, led
, battery
):
156 '''Could check the battery level and such here'''
157 pygame
.event
.post(pygame
.event
.Event(WIIMOTE_STATUS
,
158 attachment
=attachment
,
161 led
=[led
[i
] for i
in range(4)],
165 def disconnect_cb(self
, wmp
):
166 '''What should we do here?'''
167 pygame
.event
.post(pygame
.event
.Event(WIIMOTE_DISCONNECT
,
172 for i
in range(self
.nmotes
):
173 wiiuse
.set_leds(self
.wiimotes
[i
], 0)
174 wiiuse
.disconnect(self
.wiimotes
[i
])
179 def init(nmotes
, timeout
):
180 '''Initialize the module.'''
184 WT
= wiimote_thread(nmotes
, timeout
)
187 '''How many Wiimotes were found?'''
188 return WT
.actual_nmotes
191 '''Gracefully shutdown the connection and turn off the wiimote leds'''
195 class wiimote(object):
196 '''Object representing a Wiimote'''
197 def __init__(self
, n
):
198 self
.wm
= WT
.wiimotes
[n
]
200 def enable_leds(self
, m
):
201 '''Control leds. The lower 4 bits map to the 4 leds'''
202 WT
.do(wiiuse
.set_leds
, self
.wm
, sum([wiiuse
.LED
[i
] for i
in range(4) if m
& (1<<i
)]))
204 def enable_rumble(self
, on
):
206 WT
.do(wiiuse
.rumble
, self
.wm
, on
)
208 def enable_accels(self
, on
):
209 '''Control reporting of accelerometer data.'''
210 WT
.do(wiiuse
.motion_sensing
, self
.wm
, on
)
212 def enable_ir(self
, on
, vres
=None, position
=None, aspect
=None):
213 '''Control reporting IR data.'''
214 WT
.do(wiiuse
.set_ir
, self
.wm
, on
)
216 WT
.do(wiiuse
.set_ir_vres
, self
.wm
, vres
)
217 if position
is not None:
218 WT
.do(wiiuse
.set_ir_position
, self
.wm
, position
)
219 if aspect
is not None:
220 WT
.do(wiiuse
.set_aspect_ratio
, self
.wm
, aspect
)
222 def set_flags(self
, smoothing
=None, continuous
=None, threshold
=None):
223 '''Set flags SMOOTHING, CONTINUOUS, ORIENT_THRESH'''
225 if smoothing
is not None:
227 enable |
= wiiuse
.SMOOTHING
229 disable |
= wiiuse
.SMOOTHING
230 if continuous
is not None:
232 enable |
= wiiuse
.CONTINUOUS
234 disable |
= wiiuse
.CONTINUOUS
235 if threshold
is not None:
237 enable |
= wiiuse
.ORIENT_THRESH
239 disable |
= wiiuse
.ORIENT_THRESH
240 print enable
, disable
241 WT
.do(wiiuse
.set_flags
, self
.wm
, enable
, disable
)
243 def set_orient_thresh(self
, thresh
):
244 '''Set orientation threshold'''
245 WT
.do(wiiuse
.set_orient_threshold
, self
.wm
, thresh
)
248 '''Trigger a status callback.'''
249 WT
.do(wiiuse
.status
, self
.wm
)
251 def disconnect(self
):
252 '''Disconnect this Wiimote'''
253 WT
.do(wiiuse
.disconnect(self
.wm
))
256 '''Get the object for the nth Wiimote'''