Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
games
fretsonfire
fretsonfire-1.3.110-song-chooser.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File fretsonfire-1.3.110-song-chooser.patch of Package fretsonfire
--- src/Dialogs.py +++ src/Dialogs.py @@ -43,7 +43,7 @@ import Player import Guitar -def wrapText(font, pos, text, rightMargin = 0.9, scale = 0.002, visibility = 0.0): +def wrapText(font, pos, text, rightMargin = 0.9, scale = 0.002, visibility = 0.0, hide = 0, hidestring = ""): """ Wrap a piece of text inside given margins. @@ -52,13 +52,17 @@ @param rightMargin: Right margin @param scale: Text scale @param visibility: Visibility factor [0..1], 0 is fully visible + @param hide: Hide text instead of line wrap """ x, y = pos space = font.getStringSize(" ", scale = scale)[0] - + hidew, hideh = font.getStringSize(hidestring, scale = scale) + rightMargin = rightMargin - hidew for n, word in enumerate(text.split(" ")): w, h = font.getStringSize(word, scale = scale) - if x + w > rightMargin or word == "\n": + if x + w > rightMargin and hide: + word = hidestring + if (x + w > rightMargin and not hide) or word == "\n": x = pos[0] y += h if word == "\n": @@ -67,6 +71,9 @@ glRotate(visibility * (n + 1) * -45, 0, 0, 1) font.render(word, (x, y + visibility * n), scale = scale) glPopMatrix() + if x + w > rightMargin and hide: + x += hidew + space + break x += w + space return (x - space, y) @@ -122,7 +129,7 @@ elif key == pygame.K_BACKSPACE and not self.accepted: self.text = self.text[:-1] elif unicode and ord(unicode) > 31 and not self.accepted: - self.text += unicode + self.text += str(unicode) return True def run(self, ticks): @@ -338,7 +345,11 @@ self.initialItem = selectedSong self.library = selectedLibrary self.searchText = "" + self.playSongName = "" + self.cassetteShow = self.engine.config.get("game", "casseteview") + self.autoPreview = self.engine.config.get("game", "autopreview") + self.artistSort = self.engine.config.get("game", "artistsort") # Use the default library if this one doesn't exist if not self.library or not os.path.isdir(self.engine.resource.fileName(self.library)): self.library = Song.DEFAULT_LIBRARY @@ -433,7 +444,7 @@ else: self.engine.view.popLayer(self) self.accepted = True - if not self.song: + if not self.song and self.autoPreview: self.engine.data.acceptSound.play() elif c in [Player.CANCEL, Player.KEY2]: if self.library != Song.DEFAULT_LIBRARY: @@ -453,7 +464,7 @@ if self.matchesSearch(self.items[self.selectedIndex]): break self.updateSelection() - if not self.song: + if not self.song and self.autoPreview: self.engine.data.selectSound.play() elif c in [Player.DOWN, Player.ACTION2]: if self.matchesSearch(self.items[self.selectedIndex]): @@ -462,12 +473,45 @@ if self.matchesSearch(self.items[self.selectedIndex]): break self.updateSelection() - if not self.song: + if not self.song and self.autoPreview: + self.engine.data.selectSound.play() + elif key == pygame.K_PAGEUP: + if self.matchesSearch(self.items[self.selectedIndex]): + while 1: + self.selectedIndex = (self.selectedIndex - 10) % len(self.items) + if self.matchesSearch(self.items[self.selectedIndex]): + break + self.updateSelection() + if not self.song and self.autoPreview: self.engine.data.selectSound.play() + elif key == pygame.K_PAGEDOWN: + if self.matchesSearch(self.items[self.selectedIndex]): + while 1: + self.selectedIndex = (self.selectedIndex + 10) % len(self.items) + if self.matchesSearch(self.items[self.selectedIndex]): + break + self.updateSelection() + if not self.song and self.autoPreview: + self.engine.data.selectSound.play() elif key == pygame.K_BACKSPACE and not self.accepted: self.searchText = self.searchText[:-1] + self.doSearch() + elif key == pygame.K_SPACE: + if self.playSongName == self.getSelectedSong(): + self.playSongName = "" + self.song.fadeout(1000) + else: + self.playSelectedSong(forceplay=1) + elif key == pygame.K_HOME: + self.artistSort = (self.artistSort + 1) % 2 + if self.artistSort: + self.items.sort(key=lambda l: (l.artist.lower() if isinstance(l, Song.SongInfo) else '0')) + else: + self.items.sort(key=lambda l: (l.name.lower())) + elif key == pygame.K_TAB: + self.cassetteShow = not self.cassetteShow elif unicode and ord(unicode) > 31 and not self.accepted: - self.searchText += unicode + self.searchText += str(unicode) self.doSearch() return True @@ -504,9 +548,9 @@ song.play() self.song = song - def playSelectedSong(self): + def playSelectedSong(self, forceplay = 0): song = self.getSelectedSong() - if not song: + if not song or (not self.autoPreview and not forceplay): return if self.songLoader: @@ -517,10 +561,12 @@ return if self.song: + self.playSongName = "" self.song.fadeout(1000) self.songLoader = self.engine.resource.load(self, None, lambda: Song.loadSong(self.engine, song, playbackOnly = True, library = self.library), onLoad = self.songLoaded) + self.playSongName = self.getSelectedSong() def run(self, ticks): self.time += ticks / 50.0 @@ -608,73 +654,160 @@ self.background.transform.scale(math.sin(t / 8) + 2, math.sin(t / 8) + 2) self.background.draw() - # render the item list - try: - glMatrixMode(GL_PROJECTION) - glPushMatrix() - glLoadIdentity() - gluPerspective(60, self.engine.view.aspectRatio, 0.1, 1000) - glMatrixMode(GL_MODELVIEW) - glLoadIdentity() - - glEnable(GL_DEPTH_TEST) - glDisable(GL_CULL_FACE) - glDepthMask(1) - - offset = 10 * (v ** 2) - self.camera.origin = (-10 + offset, -self.cameraOffset, 4 + offset) - self.camera.target = ( 0 + offset, -self.cameraOffset, 2.5 + offset) - self.camera.apply() - - y = 0.0 - for i, item in enumerate(self.items): - if not self.matchesSearch(item): - continue + x = .6 + y = .15 + + if self.cassetteShow: + # render the item list + try: + glMatrixMode(GL_PROJECTION) + glPushMatrix() + glLoadIdentity() + gluPerspective(60, self.engine.view.aspectRatio, 0.1, 1000) + glMatrixMode(GL_MODELVIEW) + glLoadIdentity() + + glEnable(GL_DEPTH_TEST) + glDisable(GL_CULL_FACE) + glDepthMask(1) + + offset = 10 * (v ** 2) + self.camera.origin = (-10 + offset, -self.cameraOffset, 4 + offset) + self.camera.target = ( 0 + offset, -self.cameraOffset, 2.5 + offset) + self.camera.apply() + + y = 0.0 + for i, item in enumerate(self.items): + if not self.matchesSearch(item): + continue - c = math.sin(self.itemAngles[i] * math.pi / 180) + c = math.sin(self.itemAngles[i] * math.pi / 180) - if isinstance(item, Song.SongInfo): - h = c * self.cassetteWidth + (1 - c) * self.cassetteHeight - else: - h = c * self.libraryWidth + (1 - c) * self.libraryHeight + if isinstance(item, Song.SongInfo): + h = c * self.cassetteWidth + (1 - c) * self.cassetteHeight + else: + h = c * self.libraryWidth + (1 - c) * self.libraryHeight - d = (y + h * .5 + self.camera.origin[1]) / (4 * (self.camera.target[2] - self.camera.origin[2])) + d = (y + h * .5 + self.camera.origin[1]) / (4 * (self.camera.target[2] - self.camera.origin[2])) - if i == self.selectedIndex: - self.selectedOffset = y + h / 2 - Theme.setSelectedColor() - else: - Theme.setBaseColor() + if i == self.selectedIndex: + self.selectedOffset = y + h / 2 + Theme.setSelectedColor() + else: + Theme.setBaseColor() - glTranslatef(0, -h / 2, 0) + glTranslatef(0, -h / 2, 0) - glPushMatrix() - if abs(d) < 1.2: - if isinstance(item, Song.SongInfo): - glRotate(self.itemAngles[i], 0, 0, 1) - self.renderCassette(item.cassetteColor, self.itemLabels[i]) - elif isinstance(item, Song.LibraryInfo): - glRotate(-self.itemAngles[i], 0, 0, 1) - if i == self.selectedIndex: - glRotate(self.time * 4, 1, 0, 0) - self.renderLibrary(item.color, self.itemLabels[i]) - glPopMatrix() + glPushMatrix() + if abs(d) < 1.2: + if isinstance(item, Song.SongInfo): + glRotate(self.itemAngles[i], 0, 0, 1) + self.renderCassette(item.cassetteColor, self.itemLabels[i]) + elif isinstance(item, Song.LibraryInfo): + glRotate(-self.itemAngles[i], 0, 0, 1) + if i == self.selectedIndex: + glRotate(self.time * 4, 1, 0, 0) + self.renderLibrary(item.color, self.itemLabels[i]) + glPopMatrix() - glTranslatef(0, -h / 2, 0) - y += h - glDisable(GL_DEPTH_TEST) - glDisable(GL_CULL_FACE) - glDepthMask(0) + glTranslatef(0, -h / 2, 0) + y += h + + glDisable(GL_DEPTH_TEST) + glDisable(GL_CULL_FACE) + glDepthMask(0) - finally: - glMatrixMode(GL_PROJECTION) - glPopMatrix() - glMatrixMode(GL_MODELVIEW) + finally: + glMatrixMode(GL_PROJECTION) + glPopMatrix() + glMatrixMode(GL_MODELVIEW) + else: + self.engine.view.setOrthogonalProjection(normalize = True) + font = self.engine.data.font - # render the song info + try: + glEnable(GL_BLEND) + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) + glEnable(GL_COLOR_MATERIAL) + Theme.setBaseColor(1 - v) + n = (0, 0) + glBegin(GL_QUADS) + glColor4f(0,0,0, .2) + glVertex2f(.04, .02) + glVertex2f(.04, .652) + glVertex2f(.58, .652) + glVertex2f(.58, .02) + glEnd() + glBegin(GL_LINE_LOOP) + glColor4f(.7,.7,.7,1) + glVertex2f(.04, .02) + glVertex2f(.04, .652) + glVertex2f(.58, .652) + glVertex2f(.58, .02) + glEnd() + + length = 0 + select = 0 + it = 0 + for i, item in enumerate(self.items): + if not self.matchesSearch(item): + continue + if isinstance(item, Song.SongInfo) or isinstance(item, Song.LibraryInfo): + length+=1 + if self.selectedIndex == i: + select = length + + Theme.setSelectedColor(1 - v) + scale = 0.0008 + for i, item in enumerate(self.items): + if not self.matchesSearch(item): + continue + if isinstance(item, Song.SongInfo) or isinstance(item, Song.LibraryInfo): + it+=1 + if it >= (select - 5) or it >= (select + 11): + if self.selectedIndex == i: + glBegin(GL_QUADS) + glColor4f(1,1,1, .1) + else: + glBegin(GL_QUADS) + if it % 2 == 0: + glColor4f(0,0,0, .3) + else: + glColor4f(0,0,0, .5) + glVertex2f(.045, n[1] + font.getHeight() * scale) + glVertex2f(.045, n[1] + 3*font.getHeight() * scale) + glVertex2f(.575, n[1] + 3*font.getHeight() * scale) + glVertex2f(.575, n[1] + font.getHeight() * scale) + glEnd() + Theme.setSelectedColor(1 - v) + if self.artistSort: + n = wrapText(font, (.05, n[1] + font.getHeight() * scale), item.artist if isinstance(item, Song.SongInfo) else _("Songs library"), 0.57, visibility = 0.0, scale = scale, hide = 1, hidestring = "...") + Theme.setBaseColor(1 - v) + n = wrapText(font, (.07, n[1] + font.getHeight() * scale), item.name, 0.57, visibility = 0.0, scale = scale, hide = 1, hidestring = "..." ) + else: + n = wrapText(font, (.05, n[1] + font.getHeight() * scale), item.name, 0.57, visibility = 0.0, scale = scale, hide = 1, hidestring = "...") + Theme.setBaseColor(1 - v) + n = wrapText(font, (.07, n[1] + font.getHeight() * scale), item.artist if isinstance(item, Song.SongInfo) else _("Songs library"), 0.57, visibility = 0.0, scale = scale, hide = 1, hidestring = "..." ) + if ((n[1] + 2*font.getHeight() * scale) >= .65): + break + + perc = float(select)/float(length) if length > 0 else 0 + glBegin(GL_QUADS) + glColor4f(1,1,1,.8) + glVertex2f(.575, .02 + .59*perc) + glColor4f(.3,.3,.3,.8) + glVertex2f(.575, .02 + .59*perc + .04) + glColor4f(1,1,1,.8) + glVertex2f(.586, .02 + .59*perc + .04) + glColor4f(.3,.3,.3,.8) + glVertex2f(.586, .02 + .59*perc) + glEnd() + + finally: + self.engine.view.resetProjection() self.engine.view.setOrthogonalProjection(normalize = True) font = self.engine.data.font - + # render the song info try: glEnable(GL_BLEND) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) --- src/fretsonfire.pot +++ src/fretsonfire.pot @@ -120,63 +120,67 @@ msgid "__lefttoright__" msgstr "" -#: Dialogs.py:271 +#: Dialogs.py:278 msgid "<OK>" msgstr "" -#: Dialogs.py:357 +#: Dialogs.py:368 msgid "Browsing Collection..." msgstr "" -#: Dialogs.py:683 +#: Dialogs.py:784 Dialogs.py:790 +msgid "Songs library" +msgstr "" + +#: Dialogs.py:818 msgid "Filter: %s" msgstr "" -#: Dialogs.py:685 +#: Dialogs.py:820 msgid "Not found" msgstr "" -#: Dialogs.py:688 +#: Dialogs.py:823 msgid "Loading Preview..." msgstr "" -#: Dialogs.py:731 +#: Dialogs.py:866 msgid "One song in this library" msgstr "" -#: Dialogs.py:733 +#: Dialogs.py:868 msgid "%d songs in this library" msgstr "" -#: Dialogs.py:758 +#: Dialogs.py:893 msgid "[Parent Folder]" msgstr "" -#: Dialogs.py:760 +#: Dialogs.py:895 msgid "%s [Folder]" msgstr "" -#: Dialogs.py:966 +#: Dialogs.py:1101 msgid "%.2f beats per minute" msgstr "" -#: Dialogs.py:1030 +#: Dialogs.py:1165 msgid "Pick!" msgstr "" -#: Dialogs.py:1069 +#: Dialogs.py:1204 msgid "Choose a Song" msgstr "" -#: Dialogs.py:1084 +#: Dialogs.py:1219 msgid "Choose a File" msgstr "" -#: Dialogs.py:1110 +#: Dialogs.py:1245 msgid "Play with the keys and press Escape when you're done." msgstr "" -#: Dialogs.py:1120 +#: Dialogs.py:1255 msgid "Loading..." msgstr "" @@ -392,11 +396,11 @@ msgid "Upload Highscores" msgstr "" -#: GameEngine.py:51 GameEngine.py:53 GameEngine.py:54 GameEngine.py:55 +#: GameEngine.py:51 GameEngine.py:53 GameEngine.py:54 GameEngine.py:55 GameEngine.py:56 GameEngine.py:57 GameEngine.py:58 msgid "No" msgstr "" -#: GameEngine.py:51 GameEngine.py:53 GameEngine.py:54 GameEngine.py:55 +#: GameEngine.py:51 GameEngine.py:53 GameEngine.py:54 GameEngine.py:55 GameEngine.py:56 GameEngine.py:57 GameEngine.py:58 msgid "Yes" msgstr "" @@ -409,106 +413,118 @@ msgstr "" #: GameEngine.py:55 -msgid "Fullscreen Mode" +msgid "Cassete list mode" msgstr "" #: GameEngine.py:56 +msgid "Song auto preview" +msgstr "" + +#: GameEngine.py:57 +msgid "Sort by artist" +msgstr "" + +#: GameEngine.py:58 +msgid "Fullscreen Mode" +msgstr "" + +#: GameEngine.py:59 msgid "2x" msgstr "" -#: GameEngine.py:56 +#: GameEngine.py:59 msgid "4x" msgstr "" -#: GameEngine.py:56 +#: GameEngine.py:59 msgid "6x" msgstr "" -#: GameEngine.py:56 +#: GameEngine.py:59 msgid "8x" msgstr "" -#: GameEngine.py:56 +#: GameEngine.py:59 msgid "Antialiasing Quality" msgstr "" -#: GameEngine.py:56 +#: GameEngine.py:59 msgid "None" msgstr "" -#: GameEngine.py:58 +#: GameEngine.py:61 msgid "Frames per Second" msgstr "" -#: GameEngine.py:59 +#: GameEngine.py:62 msgid "High" msgstr "" -#: GameEngine.py:59 +#: GameEngine.py:62 msgid "Low" msgstr "" -#: GameEngine.py:59 +#: GameEngine.py:62 msgid "Normal" msgstr "" -#: GameEngine.py:59 +#: GameEngine.py:62 msgid "SVG Quality" msgstr "" -#: GameEngine.py:60 +#: GameEngine.py:63 msgid "Sample Frequency" msgstr "" -#: GameEngine.py:61 +#: GameEngine.py:64 msgid "Sample Bits" msgstr "" -#: GameEngine.py:63 +#: GameEngine.py:66 msgid "Buffer Size" msgstr "" -#: GameEngine.py:64 +#: GameEngine.py:67 msgid "A/V delay" msgstr "" -#: GameEngine.py:65 +#: GameEngine.py:68 msgid "Loud" msgstr "" -#: GameEngine.py:65 +#: GameEngine.py:68 msgid "Painful" msgstr "" -#: GameEngine.py:65 +#: GameEngine.py:68 msgid "Quiet" msgstr "" -#: GameEngine.py:65 +#: GameEngine.py:68 msgid "Screw Up Sounds" msgstr "" -#: GameEngine.py:65 Mod.py:33 +#: GameEngine.py:68 Mod.py:33 msgid "Off" msgstr "" -#: GameEngine.py:66 +#: GameEngine.py:69 msgid "Guitar Volume" msgstr "" -#: GameEngine.py:67 +#: GameEngine.py:70 msgid "Song Volume" msgstr "" -#: GameEngine.py:68 +#: GameEngine.py:71 msgid "Rhythm Volume" msgstr "" -#: GameEngine.py:69 +#: GameEngine.py:72 msgid "Text scale" msgstr "" -#: GameEngine.py:135 +#: GameEngine.py:138 msgid "Frets on Fire" msgstr "" --- src/GameEngine.py +++ src/GameEngine.py @@ -52,6 +52,9 @@ Config.define("game", "uploadurl", str, "http://fretsonfire.sourceforge.net/play") Config.define("game", "leftymode", bool, False, text = _("Lefty mode"), options = {False: _("No"), True: _("Yes")}) Config.define("game", "tapping", bool, True, text = _("Tappable notes"), options = {False: _("No"), True: _("Yes")}) +Config.define("game", "casseteview", bool, True, text = _("Cassete list mode"), options = {False: _("No"), True: _("Yes")}) +Config.define("game", "autopreview", bool, True, text = _("Song auto preview"), options = {False: _("No"), True: _("Yes")}) +Config.define("game", "artistsort", bool, False, text = _("Sort by artist"), options = {False: _("No"), True: _("Yes")}) Config.define("video", "fullscreen", bool, False, text = _("Fullscreen Mode"), options = {False: _("No"), True: _("Yes")}) Config.define("video", "multisamples", int, 4, text = _("Antialiasing Quality"), options = {0: _("None"), 2: _("2x"), 4: _("4x"), 6: _("6x"), 8: _("8x")}) Config.define("video", "resolution", str, "640x480") --- src/Settings.py +++ src/Settings.py @@ -140,6 +140,9 @@ ConfigChoice(engine.config, "game", "leftymode", autoApply = True), ConfigChoice(engine.config, "game", "tapping", autoApply = True), ConfigChoice(engine.config, "game", "uploadscores", autoApply = True), + ConfigChoice(engine.config, "game", "casseteview", autoApply = True), + ConfigChoice(engine.config, "game", "autopreview", autoApply = True), + ConfigChoice(engine.config, "game", "artistsort", autoApply = True), ] gameSettingsMenu = Menu.Menu(engine, gameSettings + applyItem)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor