From f7094076a9f447c33341612d1a530141d35d1a3a Mon Sep 17 00:00:00 2001 From: pin Date: Thu, 8 Apr 2010 13:56:58 +0000 Subject: [PATCH] =?utf8?q?=C3=87a=20commence=20=C3=A0=20le=20faire.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit git-svn-id: https://svn.cri.ensmp.fr/svn/minwii/trunk@129 fe552daf-6dbe-4428-90eb-1537e0879342 --- src/app/eventutils.py | 12 +- src/app/minwii.py | 15 ++ src/pywiiuse/PyWiiUse.py | 2 + src/pywiiuse/pygame_wiimouse.py | 262 ++++++++++++++++++++++++++++++++ 4 files changed, 288 insertions(+), 3 deletions(-) create mode 100755 src/pywiiuse/pygame_wiimouse.py diff --git a/src/app/eventutils.py b/src/app/eventutils.py index efa1f7e..969ad81 100755 --- a/src/app/eventutils.py +++ b/src/app/eventutils.py @@ -53,6 +53,11 @@ class _EventDispatcher : def dispatchEvents(self) : events = pygame.event.get() for event in events : + #if event.type == pygame.MOUSEMOTION : + # if hasattr(event, 'wiimoteid') : + # console.info(event) + # #return + listeners = self.registry.get(event.type, {}) for listener in listeners.keys() : listener(event) @@ -73,10 +78,10 @@ class _EventDispatcher : EventDispatcher = _EventDispatcher() -def event_handler(eventType) : +def event_handler(*eventTypes) : def markFunctionAsListener(m) : m.__islistener__ = True - m.__eventtype__ = eventType + m.__eventtypes__ = eventTypes return m return markFunctionAsListener @@ -88,7 +93,8 @@ class EventInitializer(type): for k, v in dict.items() : if isinstance(v, types.FunctionType) and hasattr(v, '__islistener__') : listener = getattr(self, k) - EventDispatcher.addEventListener(v.__eventtype__, listener) + for eventType in v.__eventtypes__ : + EventDispatcher.addEventListener(eventType, listener) def ctor(self, *args, **kw) : default_ctor = dict.get('__init__') diff --git a/src/app/minwii.py b/src/app/minwii.py index b279000..fc45bdf 100755 --- a/src/app/minwii.py +++ b/src/app/minwii.py @@ -18,6 +18,9 @@ from eventutils import EventDispatcher from musicxml import musicXml2Song from config import SONG_FILE_PATH from globals import PLAYING_MODES_DICT +from pywiiuse import pygame_wiimouse +from pywiiuse.PyWiiUse import IR_BELOW + class MinWii(object): @@ -27,6 +30,16 @@ class MinWii(object): synth = Synth() modeResolution = (1024,768) + + pygame_wiimouse.init(1, 5) # look for 1, wait 5 seconds + n = pygame_wiimouse.get_count() + print '%d wiimotes' % n + WT = pygame_wiimouse.WT + WT.pause() + wm = pygame_wiimouse.Wiimote(0) # access the wiimote object + wm.enable_accels(0) # turn on acceleration reporting + wm.enable_ir(1, vres = modeResolution, position=IR_BELOW) + pygame.display.set_mode(modeResolution) pygame.display.set_caption('MinWii') @@ -41,6 +54,7 @@ class MinWii(object): break # sélection de l'instrument + WT.resume() selector = InstrumentSelector() selector.run() selector.stop() @@ -61,3 +75,4 @@ class MinWii(object): playingScreen.run() pygame.event.clear() EventDispatcher.reset() + WT.pause() diff --git a/src/pywiiuse/PyWiiUse.py b/src/pywiiuse/PyWiiUse.py index baeeb9f..248055c 100755 --- a/src/pywiiuse/PyWiiUse.py +++ b/src/pywiiuse/PyWiiUse.py @@ -281,6 +281,8 @@ set_orient_threshold = dll.wiiuse_set_orient_threshold set_orient_threshold.argtypes = [wiimote_p, c_float] set_timeout = dll.wiiuse_set_timeout set_ir = dll.wiiuse_set_ir +set_ir_position = dll.wiiuse_set_ir_position +set_ir_vres = dll.wiiuse_set_ir_vres def is_pressed(dev, button): return dev.btns & button 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<