Encore un coup pour préparer la personalisation du comportement des wiimotes.
[minwii.git] / src / minwii / app.py
1 # -*- coding: utf-8 -*-
2 """
3 l'application winwii
4
5 $Id$
6 $URL$
7 """
8
9 import pygame
10 from pgu.gui import Theme
11 from pgu.gui import Desktop
12 from pgu.gui import QUIT
13 from minwii.widgets.launch import LaunchScreen
14 from minwii.widgets.home import Home
15 from minwii.widgets.playingscreen import SongPlayingScreen, PlayingScreen
16 from minwii.widgets.instrumentselector import InstrumentSelector
17 from minwii.synth import Synth
18 from minwii.eventutils import EventDispatcher
19 from minwii.musicxml import musicXml2Song
20 from minwii.config import SONG_FILE_PATH
21 from minwii.config import SCREEN_RESOLUTION
22 from minwii.globals import PLAYING_MODES_DICT
23 from minwii.log import console, LOG_FORMAT_VERSION, envLogger
24 import os.path
25
26
27
28 class MinWii(object):
29
30 def __init__(self, wiimoteSupport=True, fullscreen=False) :
31 envLogger.info('winwii log format version : %s', LOG_FORMAT_VERSION)
32 self.wiimoteSupport = wiimoteSupport
33 self.fullscreen = fullscreen
34 LaunchScreen()
35 themedir = __file__.split(os.path.sep)[:-1] + ['widgets', 'data', 'minwii_theme']
36 themedir = os.path.sep.join(themedir)
37 theme = Theme(themedir)
38 self.app = Desktop(theme=theme)
39 self.synth = Synth()
40 self.screenResolution = SCREEN_RESOLUTION
41 envLogger.info('résolution écran : %s', self.screenResolution)
42 self.nwiimotes = 0
43 self.initWiimotes()
44 self.firstSong = True
45
46 def initWiimotes(self) :
47 if self.wiimoteSupport :
48 from pywiiuse import pygame_wiimouse
49 from minwii.config import IR_POSITION
50 pygame_wiimouse.init(4, 5, self.screenResolution, IR_POSITION) # look for 4, wait 5 seconds
51 self.nwiimotes = nwiimotes = pygame_wiimouse.get_count()
52 console.debug('wiimotes found : %d', nwiimotes)
53 self.WT = WT = pygame_wiimouse.WT
54 WT.setEventCallBack(pygame_wiimouse._default_event_cb)
55 WT.pause()
56 else :
57 self.WT = _WTFacade()
58
59 def run(self) :
60 "séquençage de l'affichage des écrans"
61 displayFlags = 0
62 if self.fullscreen :
63 displayFlags = displayFlags | pygame.FULLSCREEN
64 pygame.display.set_mode(self.screenResolution, displayFlags)
65 pygame.display.set_caption('MINWii')
66 WT = self.WT
67
68 songFile, playMode, wiimoteIndex = '', 'NORMAL', 0
69
70 while True :
71 WT.resume()
72
73 exit, songFile, playMode, wiimoteIndex = \
74 self.selectSongAndOptions(songFile, playMode, wiimoteIndex)
75 if exit : break
76
77 WT.selectWiimote(wiimoteIndex)
78
79 instrumentDescription = self.selectInstrument()
80 if not instrumentDescription :
81 continue
82
83 self.runPlayingScreen(songFile, playMode, instrumentDescription)
84 WT.pause()
85
86
87 def selectSongAndOptions(self, songFile, playMode, wiimoteIndex) :
88 """ lance l'écran de paramétrage et retourne un tuple comportant :
89 - drapeau de sortie de l'application (booléen)
90 - chemin du fichier de la chanson
91 - mode (entier)
92 - wiimote sélectionnée (entier)
93 """
94 home = Home(songPath=SONG_FILE_PATH,
95 songFile=songFile,
96 playMode=playMode,
97 wiimoteIndex=wiimoteIndex,
98 nwiimotes=self.nwiimotes)
99 app = self.app
100 home.connect(QUIT, app.quit)
101 app.run(home)
102 app.close(home)
103
104 #logging
105 if home.exitApp :
106 console.debug("sortie de l'application")
107 else :
108 actual_wiimotes = self.WT.get_count()
109 if self.firstSong :
110 self.firstSong = False
111 else :
112 envLogger.info('NEW_LOG_FILE')
113 console.info('chanson : %s', home.songFile)
114 console.info('mode : %s', home.modeSelect.value)
115 if actual_wiimotes is None :
116 console.info('HID : souris')
117 elif actual_wiimotes == 0 :
118 console.info('HID : souris (pas de wiimote trouvée)')
119 else :
120 console.info('HID : wiimote %d', home.selectedWiimote.value + 1)
121 #---
122
123 return (home.exitApp,
124 home.songFile,
125 home.selectedPlayMode,
126 home.selectedWiimoteIndex)
127
128 def selectInstrument(self) :
129 """ lance l'écran de sélection de l'instrument et retourne
130 un dictionnaire comportant la description de l'instrument
131 """
132 selector = InstrumentSelector()
133 selector.run()
134 selector.stop()
135 pygame.event.clear()
136 EventDispatcher.reset()
137 instru = selector.selectedInstrument
138 if instru :
139 console.info('instrument : %s', instru['name'])
140 console.info('preset : %d', instru['preset'])
141 console.info('bank : %d', instru['bank'])
142 console.info('ajustement octave : %d', instru['octave'])
143 return instru
144
145 def runPlayingScreen(self, songFile, playMode, instrumentDescription) :
146 """ Lance l'écran de jeu principal avec la chanson 'songFile' dans le mode 'playMode'
147 avec l'instrument midi 'instrumentDescription'.
148 """
149 playMode = PLAYING_MODES_DICT[playMode]
150 bank, preset = instrumentDescription['bank'], instrumentDescription['preset']
151 octave = instrumentDescription['octave']
152 self.synth.adjust_octave(0, octave)
153 self.synth.program_select(0, bank, preset)
154 if playMode == PLAYING_MODES_DICT['IMPRO'] :
155 playingScreen = PlayingScreen(self.synth)
156 else :
157 song = musicXml2Song(songFile)
158 playingScreen = SongPlayingScreen(self.synth, song, mode=playMode)
159 playingScreen.run()
160 pygame.event.clear()
161 EventDispatcher.reset()
162
163
164 class _WTFacade :
165 """ Classe utilitaire pour singer l'api
166 de pygame_wiimouse en cas d'abscence de wiimote.
167 """
168 selectWimoteIndex = 0
169 def pause(self):
170 pass
171 def resume(self):
172 pass
173 def selectWiimote(self, i):
174 pass
175 def get_count(self) :
176 return None