7680581c2a7a975e6b3e3de71b8d5dadd0e53f06
1 # -*- coding: utf-8 -*-
3 wiimote -> mouse interface
9 from threading
import Thread
10 from Queue
import Queue
, Empty
13 # events to use. Is there a way to get ones known to be unused?
16 wiiuse
= None # import within the thread, why do I have to do this?
18 class wiimote_thread(Thread
):
19 '''Manage the wiiuse interface'''
20 def __init__(self
, nmotes
=1, timeout
=5):
21 Thread
.__init
__(self
, name
='wiimote')
23 self
.startup
= Queue()
25 self
.selectedWiimoteIndex
= 0
26 self
.timeout
= timeout
30 self
.startup
.get(True) # wait for the thread to get started and acquire the motes
31 self
.eventCallBack
= _default_event_cb
33 def setEventCallBack(self
, func
) :
34 self
.eventCallBack
= func
37 '''This runs in a separate thread'''
39 import PyWiiUse
as wiiuse
# import here to avoid thread problems on windows
40 self
.wiimotes
= wiiuse
.init(self
.nmotes
)
41 found
= wiiuse
.find(self
.wiimotes
, self
.nmotes
, self
.timeout
)
42 self
.actual_nmotes
= wiiuse
.connect(self
.wiimotes
, self
.nmotes
)
45 for i
in range(self
.nmotes
):
46 wiiuse
.set_leds(self
.wiimotes
[i
], wiiuse
.LED
[i
])
48 self
.go
= self
.actual_nmotes
!= 0
50 self
.startup
.put(self
.go
)
53 if self
._paused
: continue
55 if wiiuse
.poll(self
.wiimotes
, self
.nmotes
) :
56 for i
in range(self
.nmotes
) :
58 if m
[0].event
== wiiuse
.EVENT
:
59 self
.eventCallBack(self
, i
, m
)
65 func
, args
= self
.queue
.get_nowait()
76 def selectWiimote(self
, wiimoteIndex
) :
77 self
.selectedWiimoteIndex
= wiimoteIndex
79 def do(self
, func
, *args
):
80 '''Run the function in the thread handling the wiimote'''
81 self
.queue
.put((func
, args
))
83 def control_cb(self
, wmp
, attachment
, speaker
, ir
, led
, battery
):
84 '''Could check the battery level and such here'''
85 pygame
.event
.post(pygame
.event
.Event(WIIMOTE_STATUS
,
86 attachment
=attachment
,
89 led
=[led
[i
] for i
in range(4)],
93 def disconnect_cb(self
, wmp
):
94 '''What should we do here?'''
95 pygame
.event
.post(pygame
.event
.Event(WIIMOTE_DISCONNECT
,
100 for i
in range(self
.nmotes
):
101 wiiuse
.set_leds(self
.wiimotes
[i
], 0)
102 wiiuse
.disconnect(self
.wiimotes
[i
])
106 return self
.actual_nmotes
109 def _default_event_cb(self
, id, wmp
):
110 '''Called when the library has some data for the user.'''
111 if id != self
.selectedWiimoteIndex
: return
113 pos
= (wm
.ir
.x
, wm
.ir
.y
)
114 pygame
.mouse
.set_pos(pos
)
119 wiiuse
.is_just_pressed(wm
, wiiuse
.button
['B']) :
120 event
= pygame
.event
.Event(pygame
.MOUSEBUTTONDOWN
,
123 pygame
.event
.post(event
)
125 if wm
.btns_released
and \
126 wiiuse
.is_released(wm
, wiiuse
.button
['B']):
127 event
= pygame
.event
.Event(pygame
.MOUSEBUTTONUP
,
130 pygame
.event
.post(event
)
136 def init(nmotes
, timeout
, screenResolution
=(660, 370), position
='ABOVE'):
137 '''Initialize the module.'''
141 WT
= wiimote_thread(nmotes
, timeout
)
143 if position
== 'ABOVE' :
144 position
= wiiuse
.IR_ABOVE
145 elif position
== 'BELOW' :
146 position
= wiiuse
.IR_BELOW
148 position
= wiiuse
.IR_ABOVE
152 for i
in range(nmotes
) :
153 wm
= Wiimote(i
) # access the wiimote object
154 wm
.enable_accels(0) # turn off acceleration reporting
155 wm
.enable_ir(1, vres
= screenResolution
, position
=position
)
159 '''How many Wiimotes were found?'''
160 return WT
.get_count()
163 '''Gracefully shutdown the connection and turn off the wiimote leds'''
167 class wiimote(object):
168 '''Object representing a Wiimote'''
169 def __init__(self
, n
):
170 self
.wm
= WT
.wiimotes
[n
]
172 def enable_leds(self
, m
):
173 '''Control leds. The lower 4 bits map to the 4 leds'''
174 WT
.do(wiiuse
.set_leds
, self
.wm
, sum([wiiuse
.LED
[i
] for i
in range(4) if m
& (1<<i
)]))
176 def enable_rumble(self
, on
):
178 WT
.do(wiiuse
.rumble
, self
.wm
, on
)
180 def enable_accels(self
, on
):
181 '''Control reporting of accelerometer data.'''
182 WT
.do(wiiuse
.motion_sensing
, self
.wm
, on
)
184 def enable_ir(self
, on
, vres
=None, position
=None, aspect
=None):
185 '''Control reporting IR data.'''
186 WT
.do(wiiuse
.set_ir
, self
.wm
, on
)
188 WT
.do(wiiuse
.set_ir_vres
, self
.wm
, *vres
)
189 if position
is not None:
190 WT
.do(wiiuse
.set_ir_position
, self
.wm
, position
)
191 if aspect
is not None:
192 WT
.do(wiiuse
.set_aspect_ratio
, self
.wm
, aspect
)
194 def set_flags(self
, smoothing
=None, continuous
=None, threshold
=None):
195 '''Set flags SMOOTHING, CONTINUOUS, ORIENT_THRESH'''
197 if smoothing
is not None:
199 enable |
= wiiuse
.SMOOTHING
201 disable |
= wiiuse
.SMOOTHING
202 if continuous
is not None:
204 enable |
= wiiuse
.CONTINUOUS
206 disable |
= wiiuse
.CONTINUOUS
207 if threshold
is not None:
209 enable |
= wiiuse
.ORIENT_THRESH
211 disable |
= wiiuse
.ORIENT_THRESH
212 WT
.do(wiiuse
.set_flags
, self
.wm
, enable
, disable
)
214 def set_orient_thresh(self
, thresh
):
215 '''Set orientation threshold'''
216 WT
.do(wiiuse
.set_orient_threshold
, self
.wm
, thresh
)
219 '''Trigger a status callback.'''
220 WT
.do(wiiuse
.status
, self
.wm
)
222 def disconnect(self
):
223 '''Disconnect this Wiimote'''
224 WT
.do(wiiuse
.disconnect(self
.wm
))
227 '''Get the object for the nth Wiimote'''