da2bcb869c87efa80c5ab67f29e6ee5047d570d9
[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 wiiuse = None
27 pygame_wiimouse = None
28
29 SCREEN_HOME = 0
30 SCREEN_INSTRUMENTS = 1
31 SCREEN_PLAY = 2
32
33
34
35 class MinWii(object):
36
37 def __init__(self, wiimoteSupport=True, fullscreen=False) :
38 envLogger.info('winwii log format version : %s', LOG_FORMAT_VERSION)
39 self.wiimoteSupport = wiimoteSupport
40 self.fullscreen = fullscreen
41 LaunchScreen()
42 themedir = __file__.split(os.path.sep)[:-1] + ['widgets', 'data', 'minwii_theme']
43 themedir = os.path.sep.join(themedir)
44 theme = Theme(themedir)
45 self.app = Desktop(theme=theme)
46 self.synth = Synth()
47 self.screenResolution = SCREEN_RESOLUTION
48 envLogger.info('résolution écran : %s', self.screenResolution)
49 self.nwiimotes = 0
50 self.initWiimotes()
51 self.firstSong = True
52 self.screen = SCREEN_HOME
53
54 def initWiimotes(self) :
55 if self.wiimoteSupport :
56 global wiiuse
57 from pywiiuse import PyWiiUse as wiiuse
58 global pygame_wiimouse
59 from pywiiuse import pygame_wiimouse
60 from minwii.config import IR_POSITION
61 pygame_wiimouse.init(2, 5, self.screenResolution, IR_POSITION) # look for 4, wait 5 seconds
62 self.nwiimotes = nwiimotes = pygame_wiimouse.get_count()
63 console.debug('wiimotes found : %d', nwiimotes)
64 self.WT = WT = pygame_wiimouse.WT
65 WT.setEventCallBack(self._wiimotesEventCallBack)
66 WT.pause()
67 else :
68 self.WT = _WTFacade()
69
70 def _wiimotesEventCallBack(self, wt, id, wmp) :
71 if self.screen == SCREEN_PLAY :
72 pygame_wiimouse._default_event_cb(wt, id, wmp)
73 wm = wmp[0]
74 if id == self.nwiimotes - 1 and \
75 wiiuse.is_just_pressed(wm, wiiuse.button['Home']) :
76 event = pygame.event.Event(pygame.KEYDOWN,
77 key = pygame.K_q,
78 unicode = u'q')
79 pygame.event.post(event)
80
81 def run(self) :
82 "séquençage de l'affichage des écrans"
83 displayFlags = 0
84 if self.fullscreen :
85 displayFlags = displayFlags | pygame.FULLSCREEN
86 pygame.display.set_mode(self.screenResolution, displayFlags)
87 pygame.display.set_caption('MINWii')
88 WT = self.WT
89
90 songFile, playMode, wiimoteIndex = '', 'NORMAL', 0
91
92 while True :
93 WT.resume()
94 self.screen = SCREEN_HOME
95 exit, songFile, playMode, wiimoteIndex = \
96 self.selectSongAndOptions(songFile, playMode, wiimoteIndex)
97 if exit : break
98
99 WT.selectWiimote(wiimoteIndex)
100
101 self.screen = SCREEN_INSTRUMENTS
102 instrumentDescription = self.selectInstrument()
103 if not instrumentDescription :
104 continue
105
106 self.screen = SCREEN_PLAY
107 self.runPlayingScreen(songFile, playMode, instrumentDescription)
108 WT.pause()
109
110
111 def selectSongAndOptions(self, songFile, playMode, wiimoteIndex) :
112 """ lance l'écran de paramétrage et retourne un tuple comportant :
113 - drapeau de sortie de l'application (booléen)
114 - chemin du fichier de la chanson
115 - mode (entier)
116 - wiimote sélectionnée (entier)
117 """
118 home = Home(songPath=SONG_FILE_PATH,
119 songFile=songFile,
120 playMode=playMode,
121 wiimoteIndex=wiimoteIndex,
122 nwiimotes=self.nwiimotes)
123 app = self.app
124 home.connect(QUIT, app.quit)
125 app.run(home)
126 app.close(home)
127
128 #logging
129 if home.exitApp :
130 console.debug("sortie de l'application")
131 else :
132 actual_wiimotes = self.WT.get_count()
133 if self.firstSong :
134 self.firstSong = False
135 else :
136 envLogger.info('NEW_LOG_FILE')
137 console.info('chanson : %s', home.songFile)
138 console.info('mode : %s', home.modeSelect.value)
139 if actual_wiimotes is None :
140 console.info('HID : souris')
141 elif actual_wiimotes == 0 :
142 console.info('HID : souris (pas de wiimote trouvée)')
143 else :
144 console.info('HID : wiimote %d', home.selectedWiimote.value + 1)
145 #---
146
147 return (home.exitApp,
148 home.songFile,
149 home.selectedPlayMode,
150 home.selectedWiimoteIndex)
151
152 def selectInstrument(self) :
153 """ lance l'écran de sélection de l'instrument et retourne
154 un dictionnaire comportant la description de l'instrument
155 """
156 selector = InstrumentSelector()
157 selector.run()
158 selector.stop()
159 pygame.event.clear()
160 EventDispatcher.reset()
161 instru = selector.selectedInstrument
162 if instru :
163 console.info('instrument : %s', instru['name'])
164 console.info('preset : %d', instru['preset'])
165 console.info('bank : %d', instru['bank'])
166 console.info('ajustement octave : %d', instru['octave'])
167 return instru
168
169 def runPlayingScreen(self, songFile, playMode, instrumentDescription) :
170 """ Lance l'écran de jeu principal avec la chanson 'songFile' dans le mode 'playMode'
171 avec l'instrument midi 'instrumentDescription'.
172 """
173 playMode = PLAYING_MODES_DICT[playMode]
174 bank, preset = instrumentDescription['bank'], instrumentDescription['preset']
175 octave = instrumentDescription['octave']
176 self.synth.adjust_octave(0, octave)
177 self.synth.program_select(0, bank, preset)
178 if playMode == PLAYING_MODES_DICT['IMPRO'] :
179 playingScreen = PlayingScreen(self.synth)
180 else :
181 song = musicXml2Song(songFile)
182 playingScreen = SongPlayingScreen(self.synth, song, mode=playMode)
183 playingScreen.run()
184 pygame.event.clear()
185 EventDispatcher.reset()
186
187
188 class _WTFacade :
189 """ Classe utilitaire pour singer l'api
190 de pygame_wiimouse en cas d'abscence de wiimote.
191 """
192 selectWimoteIndex = 0
193 def pause(self):
194 pass
195 def resume(self):
196 pass
197 def selectWiimote(self, i):
198 pass
199 def get_count(self) :
200 return None