X-Git-Url: https://scm.cri.minesparis.psl.eu/git/minwii.git/blobdiff_plain/866367171f81ef26d50bed69a749d3f90a1304e9..f7094076a9f447c33341612d1a530141d35d1a3a:/src/pywiiuse/pygame_wiimouse.py diff --git a/src/pywiiuse/pygame_wiimouse.py b/src/pywiiuse/pygame_wiimouse.py new file mode 100755 index 0000000..3f31800 --- /dev/null +++ b/src/pywiiuse/pygame_wiimouse.py @@ -0,0 +1,262 @@ +# -*- coding: utf-8 -*- +''' +wiimote -> mouse interface +$Id$ +$URL$ +''' + +import pygame +from threading import Thread +from Queue import Queue, Empty +import time + +# events to use. Is there a way to get ones known to be unused? + + +wiiuse = None # import within the thread, why do I have to do this? + +class wiimote_thread(Thread): + '''Manage the wiiuse interface''' + def __init__(self, nmotes=1, timeout=5): + Thread.__init__(self, name='wiimote') + self.queue = Queue() + self.startup = Queue() + self.nmotes = nmotes + self.timeout = timeout + self.setDaemon(1) + self._paused = False + self.start() + self.startup.get(True) # wait for the thread to get started and acquire the motes + + def run(self): + '''This runs in a separate thread''' + global wiiuse + import PyWiiUse as wiiuse # import here to avoid thread problems on windows + self.wiimotes = wiiuse.init(self.nmotes) + found = wiiuse.find(self.wiimotes, self.nmotes, self.timeout) + self.actual_nmotes = wiiuse.connect(self.wiimotes, self.nmotes) + + self.previousPositions = {} + + for i in range(self.nmotes): + wiiuse.set_leds(self.wiimotes[i], wiiuse.LED[i]) + self.previousPositions[self.wiimotes[i][0].unid] = (0, 0) + + self.go = self.actual_nmotes != 0 + + self.startup.put(self.go) + + while self.go: + if self._paused : continue + try : + if wiiuse.poll(self.wiimotes, self.nmotes) : + for i in range(self.nmotes): + m = self.wiimotes[i] + if m[0].event == wiiuse.EVENT: + self.event_cb(m) + except : + pass + + #try: + # wiiuse.poll(self.wiimotes, self.nmotes) + #except: + # pass + + # allow executing functions in this thread + while True: + try: + func, args = self.queue.get_nowait() + except Empty: + break + print 'do:', func.__name__, args + func(*args) + + def pause(self) : + self._paused = True + + def resume(self) : + self._paused = False + + def do(self, func, *args): + '''Run the function in the thread handling the wiimote''' + self.queue.put((func, args)) + + def event_cb(self, wmp): + '''Called when the library has some data for the user.''' + wm = wmp[0] +# if wm.btns: +# for name,b in wiiuse.button.items(): +# if wiiuse.is_just_pressed(wm, b): +# pygame.event.post(pygame.event.Event(WIIMOTE_BUTTON_PRESS, button=name, +# time=time.time(), +# id=wm.unid)) +# +# if wm.btns_released: +# for name,b in wiiuse.button.items(): +# if wiiuse.is_released(wm, b): +# pygame.event.post(pygame.event.Event(WIIMOTE_BUTTON_RELEASE, button=name, +# time=time.time(), +# id=wm.unid)) +# +# if True: +# pygame.event.post(pygame.event.Event(WIIMOTE_ACCEL, +# orient=(wm.orient.roll, wm.orient.pitch, +# wm.orient.yaw), +# accel=(wm.gforce.x, wm.gforce.y, wm.gforce.z), +# time=time.time(), +# id=wm.unid)) + if True: + #dots = [ (wm.ir.dot[i].visible, wm.ir.dot[i].x, wm.ir.dot[i].y) for i in range(4) ] + #pygame.event.post(pygame.event.Event(WIIMOTE_IR, + # dots=dots, + # cursor=(wm.ir.x, wm.ir.y, wm.ir.z), + # time=time.time(), + # id=wm.unid)) + + dots = [ (wm.ir.dot[i].visible, wm.ir.dot[i].x, wm.ir.dot[i].y) for i in range(4) ] + cursor=(wm.ir.x, wm.ir.y, wm.ir.z) + pos = cursor[:2] + previousPos = self.previousPositions[wm.unid] + rel = (pos[0] - previousPos[0], pos[1] - previousPos[1]) + self.previousPositions[wm.unid] = pos + + evt = pygame.event.Event(pygame.MOUSEMOTION, + pos = pos, + rel = rel, + buttons = [], + dots=dots, + cursor=(wm.ir.x, wm.ir.y, wm.ir.z), + time=time.time(), + wiimoteid=wm.unid) + pygame.event.post(evt) + + +# if wm.exp.type == wiiuse.EXP_NUNCHUK: +# nc = wm.exp.u.nunchuk +# +# for name,b in wiiuse.nunchuk_button.items(): +# if wiiuse.is_just_pressed(nc, b): +# pygame.event.post(pygame.event.Event(NUNCHUK_BUTTON_PRESS, button=name, +# time=time.time(), +# id=wm.unid)) +# elif wiiuse.is_released(nc, b): +# pygame.event.post(pygame.event.Event(NUNCHUK_BUTTON_RELEASE, button=name, +# time=time.time(), +# id=wm.unid)) +# +# pygame.event.post(pygame.event.Event(NUNCHUK_ACCEL, +# orient=(nc.orient.roll, nc.orient.pitch, +# nc.orient.yaw), +# accel=(nc.gforce.x, nc.gforce.y, nc.gforce.z), +# time=time.time(), +# id=wm.unid)) +# pygame.event.post(pygame.event.Event(NUNCHUK_JOY, +# angle=nc.js.ang, +# mag=nc.js.mag, +# time=time.time(), +# id=wm.unid)) + + def control_cb(self, wmp, attachment, speaker, ir, led, battery): + '''Could check the battery level and such here''' + pygame.event.post(pygame.event.Event(WIIMOTE_STATUS, + attachment=attachment, + speaker=speaker, + ir=ir, + led=[led[i] for i in range(4)], + battery=battery, + id=wmp[0].unid)) + + def disconnect_cb(self, wmp): + '''What should we do here?''' + pygame.event.post(pygame.event.Event(WIIMOTE_DISCONNECT, + id=wmp[0].unid)) + + def quit(self): + '''Go away.''' + for i in range(self.nmotes): + wiiuse.set_leds(self.wiimotes[i], 0) + wiiuse.disconnect(self.wiimotes[i]) + self.go = False + +WT = None + +def init(nmotes, timeout): + '''Initialize the module.''' + global WT + if WT: + return + WT = wiimote_thread(nmotes, timeout) + +def get_count(): + '''How many Wiimotes were found?''' + return WT.actual_nmotes + +def quit(): + '''Gracefully shutdown the connection and turn off the wiimote leds''' + WT.quit() + WT.join() + +class wiimote(object): + '''Object representing a Wiimote''' + def __init__(self, n): + self.wm = WT.wiimotes[n] + + def enable_leds(self, m): + '''Control leds. The lower 4 bits map to the 4 leds''' + WT.do(wiiuse.set_leds, self.wm, sum([wiiuse.LED[i] for i in range(4) if m & (1<