X-Git-Url: https://scm.cri.ensmp.fr/git/minwii.git/blobdiff_plain/346a9b8e1fcfe30629f0d1ee4675e9e8f89890cf..4c4732c6ed8cb0aaa70fb2d4c6e5a958868c5349:/src/gui/PlayingScreen.py diff --git a/src/gui/PlayingScreen.py b/src/gui/PlayingScreen.py deleted file mode 100755 index 0b1b272..0000000 --- a/src/gui/PlayingScreen.py +++ /dev/null @@ -1,439 +0,0 @@ -''' -Created on 23 juil. 2009 - -@author: Samuel Benveniste -''' -from math import floor, ceil -import pygame -import sys -import colorsys -import constants -from gradients import gradients -from logging.PickleableEvent import PickleableEvent - - -class PlayingScreen: - ''' - The screen on which the game is played - - wiimotes: - The wiimotes used in this session - window: - The main display window - screen: - The main display surface - clock: - The clock used to animate the screen - savedScreen: - The background that is painted every time - playerScreen: - The buffer for painting everything before bliting - width: - The width of the window in pixels - height: - The height of the window in pixels - extendScale : - True if the scale is G to C instead of C to C - cascade: - True if crossing from note to note with a button pressed triggers a new note - scaleSize: - The size of the scale used - cursorPositions: - The positions of the cursors on the screen, in pixels - ''' - - - - def __init__(self, instrumentChoice=None, song = None, cascade=False, extendedScale=False, defaultInstrumentChannel = 16, defaultNote = 60): - ''' - Constructor - ''' - self.blinkLength = 200 - self.minimalVelocity = 64 - self.shortScaleSize = 8 - self.longScaleSize = 11 - if not extendedScale: - self.offset = self.longScaleSize - self.shortScaleSize - else: - self.offset = 0 - self.borderSize = 5 - self.savedHighlightedNote = 0 - - self.wiimotes = instrumentChoice.wiimotes - self.activeWiimotes = instrumentChoice.activeWiimotes - self.window = instrumentChoice.window - self.screen = instrumentChoice.screen - self.blitOrigin = instrumentChoice.blitOrigin - self.clock = instrumentChoice.clock - self.width = instrumentChoice.width - self.height = instrumentChoice.height - self.cursorPositions = instrumentChoice.cursorPositions - self.savedScreen = instrumentChoice.savedScreen - self.playerScreen = instrumentChoice.playerScreen - self.extendedScale = extendedScale - self.cascade = cascade - self.joys = instrumentChoice.joys - self.portOffset = instrumentChoice.portOffset - self.eventLog = instrumentChoice.eventLog - self.cursorPositions = instrumentChoice.cursorPositions - self.song = song - self.songIterator = self.moveToNextNote() - self.replay = instrumentChoice.replay - - self.defaultInstrumentChannel = defaultInstrumentChannel - self.defaultNote = defaultNote - - self.done = False - self.backToInstrumentChoice = False - self.easyMode = False - - self.highlightedNote = self.songIterator.next() - - self.blinkOn = False - self.savedBlinkOn = False - ##Will prevent the song to move on if two consecutive notes are identical and the buttons have not been released in between the two - ##i.e. it guarantees that there will be an attack between two identical consecutive notes - self.highlightIsFree = True - - self.noteRects = [] - self.boundingRect = None - self.notes = [] - self.buttonDown = [] - self.velocityLock = [] - - self._blinkOffset = 0 - - self.font = pygame.font.Font(None,50) - self.firstWiimote = 0 - while not self.activeWiimotes[self.firstWiimote] : - self.firstWiimote += 1 - self.renderedNoteNames = [self.font.render(constants.noteNumberToName(note),False,(0,0,0)) for note in self.wiimotes[self.firstWiimote].instrument.notes[self.offset:]] - - self.drawBackground() - self.initializeWiimotes() - - #The main loop - while not self.done : - - #Clear the cursors from the screen - if self.hasChanged(): - self.drawBackground() - self.playerScreen.blit(self.savedScreen, (0, 0)) - - # Limit frame speed to 50 FPS - # - timePassed = self.clock.tick(50) - - self._blinkOffset += timePassed - if self._blinkOffset > self.blinkLength: - self._blinkOffset -= self.blinkLength - self.blinkOn = not self.blinkOn - - if self.replay: - self.eventLog.update(timePassed) - pickledEventsToPost = self.eventLog.getPickledEvents() - for pickledEvent in pickledEventsToPost: - pygame.event.post(pickledEvent.event) - - events = pygame.event.get() - - if not self.replay: - pickledEvents = [PickleableEvent(event.type,event.dict) for event in events] - if pickledEvents != [] : - self.eventLog.appendEventGroup(pickledEvents) - - for event in events: - self.input(event) - - for i in range(len(self.wiimotes)): - if self.activeWiimotes[i]: - self.wiimotes[i].cursor.update(timePassed, self.cursorPositions[i]) - if self.buttonDown[i] : - self.wiimotes[i].cursor.flash() - self.wiimotes[i].cursor.blit(self.playerScreen) - - self.screen.blit(self.playerScreen, (0,0)) - - pygame.display.flip() - - for i in range(len(self.wiimotes)): - if self.activeWiimotes[i]: - self.wiimotes[i].stopNote(self.notes[i]) - - def drawBackground(self): - self.savedScreen.fill((255,255,255)) - - if self.extendedScale : - self.scaleSize = self.longScaleSize - else: - self.scaleSize = self.shortScaleSize - - self.noteRects = [pygame.Rect(i * self.width / self.scaleSize+self.blitOrigin[0], self.blitOrigin[1], self.width / self.scaleSize + 1, self.height+1) for i in range(self.scaleSize)] - #inflate last noteRect to cover the far right pixels - self.noteRects[-1].width = self.noteRects[-1].width + 1 - - #create bounding rect - self.boundingRect = self.noteRects[0].unionall(self.noteRects) - - #fill the rectangles with a color gradient - #We start with blue - startingHue = 0.66666666666666663 - - for rectNumber in range(self.scaleSize): - colorRatio = float(rectNumber) / (self.scaleSize - 1) - #hue will go from 0.6666... (blue) to 0 (red) as colorRation goes up - hue = startingHue * (1 - colorRatio) - if self.song != None: - if rectNumber + self.offset == self.highlightedNote: - #The color of the bottom of the rectangle in hls coordinates - bottomColorHls = (hue, 0.6, 1) - #The color of the top of the rectangle in hls coordinates - topColorHls = (hue, 0.9, 1) - else: - #The color of the bottom of the rectangle in hls coordinates - bottomColorHls = (hue, 0.2, 1) - #The color of the top of the rectangle in hls coordinates - topColorHls = (hue, 0.4, 1) - else: - #The color of the bottom of the rectangle in hls coordinates - bottomColorHls = (hue, 0.6, 1) - #The color of the top of the rectangle in hls coordinates - topColorHls = (hue, 0.9, 1) - - #convert to rgb ranging from 0 to 255 - bottomColorRgb = [floor(255 * i) for i in colorsys.hls_to_rgb(*bottomColorHls)] - topColorRgb = [floor(255 * i) for i in colorsys.hls_to_rgb(*topColorHls)] - #add transparency - bottomColorRgb.append(255) - topColorRgb.append(255) - #convert to tuple - bottomColorRgb = tuple(bottomColorRgb) - topColorRgb = tuple(topColorRgb) - - self.savedScreen.blit(gradients.vertical(self.noteRects[rectNumber].size, topColorRgb, bottomColorRgb), self.noteRects[rectNumber]) - - textBlitPoint = (self.noteRects[rectNumber].left+(self.noteRects[rectNumber].width-self.renderedNoteNames[rectNumber].get_width())/2, - self.noteRects[rectNumber].bottom-self.renderedNoteNames[rectNumber].get_height()) - - self.savedScreen.blit(self.renderedNoteNames[rectNumber], textBlitPoint) - - pygame.draw.rect(self.savedScreen, pygame.Color(0, 0, 0, 255), self.noteRects[rectNumber], 2) - - - if self.song != None and self.blinkOn: - borderSize = self.borderSize - pygame.draw.rect(self.savedScreen, pygame.Color(0, 0, 0, 0), self.noteRects[self.highlightedNote-self.offset].inflate(borderSize/2,borderSize/2), borderSize) - - def initializeWiimotes(self): - for loop in self.wiimotes: - if loop.port == None : - loop.port = pygame.midi.Output(loop.portNumber) - self.notes.append(0) - self.buttonDown.append(False) - self.velocityLock.append(False) - - def updateCursorPositionFromJoy(self, joyEvent): - joyName = pygame.joystick.Joystick(joyEvent.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if correctedJoyId < len(self.cursorPositions): - if joyEvent.axis == 0 : - self.cursorPositions[correctedJoyId] = (int((joyEvent.value + 1) / 2 * self.screen.get_width()), self.cursorPositions[correctedJoyId][1]) - if joyEvent.axis == 1 : - self.cursorPositions[correctedJoyId] = (self.cursorPositions[correctedJoyId][0], int((joyEvent.value + 1) / 2 * self.screen.get_height())) - - def heightToVelocity(self, pos, controllerNumber): - if self.song != None: - if self.boundingRect.collidepoint(pos) and (self.highlightedNote == self.notes[controllerNumber] or self.velocityLock[controllerNumber]): - velocity = int(floor((1 - (float(pos[1])-self.blitOrigin[1]) / self.height) * (127-self.minimalVelocity))+self.minimalVelocity) - else : - if self.easyMode: - velocity = None - else: - velocity = self.minimalVelocity/3 - else: - if self.boundingRect.collidepoint(pos): - velocity = int(floor((1 - (float(pos[1])-self.blitOrigin[1]) / self.height) * (127-self.minimalVelocity))+self.minimalVelocity) - else : - velocity = self.minimalVelocity - return(velocity) - - def widthToNote(self, pos): - nn = 0 - try : - while self.noteRects[nn].collidepoint(pos) == False: - nn = nn + 1 - return(nn + self.offset) - except(IndexError): - return(None) - - def input(self, event): - - if event.type == pygame.QUIT: - for loop in self.wiimotes: - del loop.port - pygame.midi.quit() - sys.exit(0) - - if event.type == pygame.KEYDOWN: - if event.key == pygame.K_q: - self.done = True - - if event.key == pygame.K_i: - self.backToInstrumentChoice = True - self.done = True - - if event.type == pygame.JOYAXISMOTION: - joyName = pygame.joystick.Joystick(event.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if self.activeWiimotes[correctedJoyId]: - self.updateCursorPositionFromJoy(event) - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - - if self.buttonDown[correctedJoyId]: - if self.notes[correctedJoyId] != None: - velocity = self.heightToVelocity(pos, correctedJoyId) - CCHexCode = wiimote.getCCHexCode() - wiimote.port.write_short(CCHexCode, 07, velocity) - if self.cascade: - n = self.widthToNote(pos) - if n != self.notes[correctedJoyId]: - wiimote.stopNote(self.notes[correctedJoyId]) - self.notes[correctedJoyId] = n - - if self.song != None : - if self.highlightedNote == self.notes[correctedJoyId]: - self.highlightedNote = self.songIterator.next() - self.velocityLock[correctedJoyId] = True - else: - self.velocityLock[correctedJoyId] = False - - velocity = self.heightToVelocity(pos, correctedJoyId) - - wiimote.playNote(self.notes[correctedJoyId],velocity) - - if event.type == pygame.JOYBUTTONDOWN : - - joyName = pygame.joystick.Joystick(event.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if self.activeWiimotes[correctedJoyId]: - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - - if not self.buttonDown[correctedJoyId]: - savedNote = self.notes[correctedJoyId] - self.notes[correctedJoyId] = self.widthToNote(pos) - - if self.song != None : - if self.highlightedNote == self.notes[correctedJoyId]: - self.highlightedNote = self.songIterator.next() - self.velocityLock[correctedJoyId] = True - - velocity = self.heightToVelocity(pos, correctedJoyId) - - if velocity != None : - if self.easyMode : - wiimote.stopNote(savedNote) - wiimote.playNote(self.notes[correctedJoyId],velocity) - self.buttonDown[correctedJoyId] = True - - if event.type == pygame.JOYBUTTONUP: - joyName = pygame.joystick.Joystick(event.joy).get_name() - correctedJoyId = constants.joyNames.index(joyName) - if self.activeWiimotes[correctedJoyId]: - self.buttonDown[correctedJoyId] = False - wiimote = self.wiimotes[correctedJoyId] - if not self.easyMode: - wiimote.stopNote(self.notes[correctedJoyId]) - self.velocityLock[correctedJoyId] = False - - if event.type == pygame.MOUSEMOTION: - - self.updateCursorPositionFromMouse(event) - - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - - if self.buttonDown[correctedJoyId]: - if self.notes[correctedJoyId] != None: - velocity = self.heightToVelocity(pos, correctedJoyId) - CCHexCode = wiimote.getCCHexCode() - wiimote.port.write_short(CCHexCode, 07, velocity) - if self.cascade: - n = self.widthToNote(pos) - if n != self.notes[correctedJoyId]: - wiimote.stopNote(self.notes[correctedJoyId]) - self.notes[correctedJoyId] = n - - if self.song != None : - if self.highlightedNote == self.notes[correctedJoyId]: - self.highlightedNote = self.songIterator.next() - self.velocityLock[correctedJoyId] = True - else: - self.velocityLock[correctedJoyId] = False - - velocity = self.heightToVelocity(pos, correctedJoyId) - - wiimote.playNote(self.notes[correctedJoyId],velocity) - - if event.type == pygame.MOUSEBUTTONDOWN: - - if event.button == 1: - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - wiimote = self.wiimotes[correctedJoyId] - pos = self.cursorPositions[correctedJoyId] - - if not self.buttonDown[correctedJoyId]: - self.notes[correctedJoyId] = self.widthToNote(pos) - - if self.song != None : - if self.highlightedNote == self.notes[correctedJoyId]: - self.highlightedNote = self.songIterator.next() - self.velocityLock[correctedJoyId] = True - - velocity = self.heightToVelocity(pos, correctedJoyId) - - wiimote.playNote(self.notes[correctedJoyId],velocity) - self.buttonDown[correctedJoyId] = True - - if event.button == 2: - - self.done = True - - if event.type == pygame.MOUSEBUTTONUP: - - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - wiimote = self.wiimotes[correctedJoyId] - wiimote.stopNote(self.notes[correctedJoyId]) - self.buttonDown[correctedJoyId] = False - self.velocityLock[correctedJoyId] = False - - def hasChanged(self): - changed = False - if self.song != None: - if self.blinkOn != self.savedBlinkOn or self.highlightedNote != self.savedHighlightedNote: - self.savedBlinkOn = self.blinkOn - self.savedHighlightedNote = self.highlightedNote - changed = True - return(changed) - - def updateCursorPositionFromMouse(self, mouseEvent): - correctedJoyId = 0 - while not self.activeWiimotes[correctedJoyId] : - correctedJoyId += 1 - self.cursorPositions[correctedJoyId] = mouseEvent.pos - - def moveToNextNote(self): - while True: - if self.song == None: - yield(None) - else: - for note in self.song: - yield note