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
33 '''This runs in a separate thread'''
35 import PyWiiUse
as wiiuse
# import here to avoid thread problems on windows
36 self
.wiimotes
= wiiuse
.init(self
.nmotes
)
37 found
= wiiuse
.find(self
.wiimotes
, self
.nmotes
, self
.timeout
)
38 self
.actual_nmotes
= wiiuse
.connect(self
.wiimotes
, self
.nmotes
)
41 for i
in range(self
.nmotes
):
42 wiiuse
.set_leds(self
.wiimotes
[i
], wiiuse
.LED
[i
])
44 self
.go
= self
.actual_nmotes
!= 0
46 self
.startup
.put(self
.go
)
49 if self
._paused
: continue
51 if wiiuse
.poll(self
.wiimotes
, self
.nmotes
) :
52 m
= self
.wiimotes
[self
.selectedWiimoteIndex
]
53 if m
[0].event
== wiiuse
.EVENT
:
60 func
, args
= self
.queue
.get_nowait()
63 print 'do:', func
.__name
__, args
72 def selectWiimote(self
, wiimoteIndex
) :
73 self
.selectedWiimoteIndex
= wiimoteIndex
75 def do(self
, func
, *args
):
76 '''Run the function in the thread handling the wiimote'''
77 self
.queue
.put((func
, args
))
79 def event_cb(self
, wmp
):
80 '''Called when the library has some data for the user.'''
82 pos
= (wm
.ir
.x
, wm
.ir
.y
)
83 pygame
.mouse
.set_pos(pos
)
88 wiiuse
.is_just_pressed(wm
, wiiuse
.button
['B']) :
89 event
= pygame
.event
.Event(pygame
.MOUSEBUTTONDOWN
,
92 pygame
.event
.post(event
)
94 if wm
.btns_released
and \
95 wiiuse
.is_released(wm
, wiiuse
.button
['B']):
96 event
= pygame
.event
.Event(pygame
.MOUSEBUTTONUP
,
99 pygame
.event
.post(event
)
103 def control_cb(self
, wmp
, attachment
, speaker
, ir
, led
, battery
):
104 '''Could check the battery level and such here'''
105 pygame
.event
.post(pygame
.event
.Event(WIIMOTE_STATUS
,
106 attachment
=attachment
,
109 led
=[led
[i
] for i
in range(4)],
113 def disconnect_cb(self
, wmp
):
114 '''What should we do here?'''
115 pygame
.event
.post(pygame
.event
.Event(WIIMOTE_DISCONNECT
,
120 for i
in range(self
.nmotes
):
121 wiiuse
.set_leds(self
.wiimotes
[i
], 0)
122 wiiuse
.disconnect(self
.wiimotes
[i
])
127 def init(nmotes
, timeout
, screenResolution
=(660, 370)):
128 '''Initialize the module.'''
132 WT
= wiimote_thread(nmotes
, timeout
)
135 for i
in range(nmotes
) :
136 wm
= Wiimote(i
) # access the wiimote object
137 wm
.enable_accels(0) # turn off acceleration reporting
138 wm
.enable_ir(1, vres
= screenResolution
, position
=wiiuse
.IR_BELOW
)
142 '''How many Wiimotes were found?'''
143 return WT
.actual_nmotes
146 '''Gracefully shutdown the connection and turn off the wiimote leds'''
150 class wiimote(object):
151 '''Object representing a Wiimote'''
152 def __init__(self
, n
):
153 self
.wm
= WT
.wiimotes
[n
]
155 def enable_leds(self
, m
):
156 '''Control leds. The lower 4 bits map to the 4 leds'''
157 WT
.do(wiiuse
.set_leds
, self
.wm
, sum([wiiuse
.LED
[i
] for i
in range(4) if m
& (1<<i
)]))
159 def enable_rumble(self
, on
):
161 WT
.do(wiiuse
.rumble
, self
.wm
, on
)
163 def enable_accels(self
, on
):
164 '''Control reporting of accelerometer data.'''
165 WT
.do(wiiuse
.motion_sensing
, self
.wm
, on
)
167 def enable_ir(self
, on
, vres
=None, position
=None, aspect
=None):
168 '''Control reporting IR data.'''
169 WT
.do(wiiuse
.set_ir
, self
.wm
, on
)
171 WT
.do(wiiuse
.set_ir_vres
, self
.wm
, *vres
)
172 if position
is not None:
173 WT
.do(wiiuse
.set_ir_position
, self
.wm
, position
)
174 if aspect
is not None:
175 WT
.do(wiiuse
.set_aspect_ratio
, self
.wm
, aspect
)
177 def set_flags(self
, smoothing
=None, continuous
=None, threshold
=None):
178 '''Set flags SMOOTHING, CONTINUOUS, ORIENT_THRESH'''
180 if smoothing
is not None:
182 enable |
= wiiuse
.SMOOTHING
184 disable |
= wiiuse
.SMOOTHING
185 if continuous
is not None:
187 enable |
= wiiuse
.CONTINUOUS
189 disable |
= wiiuse
.CONTINUOUS
190 if threshold
is not None:
192 enable |
= wiiuse
.ORIENT_THRESH
194 disable |
= wiiuse
.ORIENT_THRESH
195 print enable
, disable
196 WT
.do(wiiuse
.set_flags
, self
.wm
, enable
, disable
)
198 def set_orient_thresh(self
, thresh
):
199 '''Set orientation threshold'''
200 WT
.do(wiiuse
.set_orient_threshold
, self
.wm
, thresh
)
203 '''Trigger a status callback.'''
204 WT
.do(wiiuse
.status
, self
.wm
)
206 def disconnect(self
):
207 '''Disconnect this Wiimote'''
208 WT
.do(wiiuse
.disconnect(self
.wm
))
211 '''Get the object for the nth Wiimote'''