diff --git a/NuGet.Config b/NuGet.Config
index ec2f39ad..de31da0b 100644
--- a/NuGet.Config
+++ b/NuGet.Config
@@ -1,13 +1,11 @@
-
-
+
-
+
-
\ No newline at end of file
diff --git a/Output/Cover/Genius Standard.xml b/Output/Cover/01_Genius Standard.xml
similarity index 100%
rename from Output/Cover/Genius Standard.xml
rename to Output/Cover/01_Genius Standard.xml
diff --git a/Output/Cover/02_Genius Blue.xml b/Output/Cover/02_Genius Blue.xml
new file mode 100644
index 00000000..4d51eb2b
--- /dev/null
+++ b/Output/Cover/02_Genius Blue.xml
@@ -0,0 +1,166 @@
+
+
+
+ Genius Blue
+ Genius
+ Jiiniasu
+
+
+
+
+
+
+ %TEXT%
+
+ Normal
+
+
+
+ 550
+
+
+
+
+ 0.855
+ 0.937
+ 0.945
+ 0.8
+
+
+
+ 24
+
+
+ 100
+
+
+ 1
+ 1
+ 1
+ 1
+
+
+ Cover.png
+
+ 1.0
+
+ True
+
+
+
+
+ %TEXT%
+
+ Normal
+
+
+
+ 550
+
+
+
+
+ 0.855
+ 0.937
+ 0.945
+ 0.8
+
+
+
+ -150
+
+
+ 100
+
+
+ 1
+ 1
+ 1
+ 1
+
+
+ Cover.png
+
+ 1.0
+
+ True
+
+
+
+
+ %TEXT%
+
+ Normal
+
+
+
+ 550
+
+
+
+
+ 0.855
+ 0.937
+ 0.945
+ 0.8
+
+
+
+ 150
+
+
+ 100
+
+
+ 1
+ 1
+ 1
+ 1
+
+
+ Cover.png
+
+ 1.0
+
+ True
+
+
+
+
+ %TEXT%
+
+ Normal
+
+
+
+ 120
+
+
+
+
+ 0.855
+ 0.937
+ 0.945
+ 0.8
+
+
+
+ -150
+
+
+ 100
+
+
+ 1
+ 1
+ 1
+ 1
+
+
+ Cover.png
+
+ 1.0
+
+ True
+
+
diff --git a/Output/Cover/03_Genius Red.xml b/Output/Cover/03_Genius Red.xml
new file mode 100644
index 00000000..26c2c8ae
--- /dev/null
+++ b/Output/Cover/03_Genius Red.xml
@@ -0,0 +1,166 @@
+
+
+
+ Genius Red
+ Genius
+ Jiiniasu
+
+
+
+
+
+
+ %TEXT%
+
+ Normal
+
+
+
+ 550
+
+
+
+
+ 0.988
+ 0.682
+ 0.733
+ 0.8
+
+
+
+ 24
+
+
+ 100
+
+
+ 1
+ 1
+ 1
+ 1
+
+
+ Cover.png
+
+ 1.0
+
+ True
+
+
+
+
+ %TEXT%
+
+ Normal
+
+
+
+ 550
+
+
+
+
+ 0.988
+ 0.682
+ 0.733
+ 0.8
+
+
+
+ -150
+
+
+ 100
+
+
+ 1
+ 1
+ 1
+ 1
+
+
+ Cover.png
+
+ 1.0
+
+ True
+
+
+
+
+ %TEXT%
+
+ Normal
+
+
+
+ 550
+
+
+
+
+ 0.988
+ 0.682
+ 0.733
+ 0.8
+
+
+
+ 150
+
+
+ 100
+
+
+ 1
+ 1
+ 1
+ 1
+
+
+ Cover.png
+
+ 1.0
+
+ True
+
+
+
+
+ %TEXT%
+
+ Normal
+
+
+
+ 120
+
+
+
+
+ 0.988
+ 0.682
+ 0.733
+ 0.8
+
+
+
+ -150
+
+
+ 100
+
+
+ 1
+ 1
+ 1
+ 1
+
+
+ Cover.png
+
+ 1.0
+
+ True
+
+
diff --git a/Output/Languages/English.xml b/Output/Languages/English.xml
index 63a4bad3..b315840e 100644
--- a/Output/Languages/English.xml
+++ b/Output/Languages/English.xml
@@ -152,12 +152,21 @@
(%v songs)
(%v song)
%a - %t
+ A-Z = Jump to the letter • F3 = Search • CTRL+R = Random selection • CTRL+S = Start medley • CTRL+# = Change song sorting • CTRL+T = Enable/Disable category view • Space = Open song options • ESC = Back to main menu
+ A-Z = Search artist and title, prefixes for the search → a: = artist • t: = title • c: = creator • e: = edition • g: = genre • y: = year (e.g. 1999 or 1980-1989) • l: = language • al: = album • fi: = file name • fo: = folder name
+ 1-6 = Press your team number to use a random song joker
+ Sorting: %s
+ No Medley for this song!
Pause
Stop singing
Continue
Skip this song
Restart round
Restart game
+ No more songs in playlist!
+ No webcam available!
+ Aspect Ratio: %a
+ Skipped %s seconds
Scores
Rating
Points
diff --git a/Output/Languages/German.xml b/Output/Languages/German.xml
index 1de7ea61..9076e3b8 100644
--- a/Output/Languages/German.xml
+++ b/Output/Languages/German.xml
@@ -147,10 +147,19 @@
(%v Lieder)
(%v Lied)
%a -%t
+ A-Z = Zum Buchstaben springen • F3 = Suchen • STRG+R = Zufällige Auswahl • STRG+S = Starte Medley • STRG+# = Song Sortierung ändern • STRG+T = Kategorieansicht ein-/ausschalten • Leertaste = Lied-Optionen öffnen • ESC = Zurück zum Hauptmenü
+ A-Z = Interpreten und Titel durchsuchen, Präfixe für die Suche → a: = Interpret • t: = Titel • c: = Ersteller • e: = Edition • g: = Genre • y: = Jahr (z.B. 1999 oder 1980-1989) • l: = Sprache • al: = Album • fi: = Dateiname • fo: = Ordnername
+ 1-6 = Drücke die Teamnummer um einen Zufallssong Joker zu verwenden
+ Sortierung: %s
+ Kein Medley für diesen Song!
Pause
Lied beenden
Fortfahren
Lied überspringen
+ Keine weiteren Songs in der Playlist!
+ Keine Webcam verfügbar!
+ Seitenverhältnis: %a
+ %s Sekunden gesprungen
Auswertung
Bewertung
Punkte
diff --git a/Output/Readme.txt b/Output/Readme.txt
index 13d36037..edea3878 100644
--- a/Output/Readme.txt
+++ b/Output/Readme.txt
@@ -132,12 +132,20 @@ Song screen
[F3] to open/close the song search menu
[SPACE] to open/close the song menu
[TAB] to switch selection of song menu and playlist (if opened)
+[CTRL] + [H] to show the highscore of the selected song
+[CTRL] + [T] to toggle category / tabs view
+[CTRL] + [1]..[0] to change the song sorting (just changed for runtime, not saved!), in order from keys 1 to 0:
+ folder, artist, artist by letter, title by letter, edition, genre, language, year, decade, date added
[CTRL] + [R] to select a random song
[CTRL] + [A] to sing all songs
[CTRL] + [S] to sing current song in medley version
[CTRL] + [V] to sing all songs from a category
+[CTRL] + [L] to filter the song list to the current displayed playlist. Press again to remove this filter.
[NUM_1]..[NUM_6] to use a Joker for team 1..6
-[A]..[Z] to jump to category/song title starting with that letter
+[A]..[Z] to jump to category/song title starting with that letters (multiple letters possible)
+[PAGE UP] or [PAGE DOWN] to scroll one page up/down
+[CTRL] + [PAGE UP or DOWN] to go inside next or previous category while being in a category
+[HOME] or [END] to scroll up to first song or down to last song
Name selection screen
[1]..[6] to activate player selection.
@@ -149,6 +157,8 @@ Name selection screen
Sing screen
[P] to toggle pause.
[CTRL] + [S] to skip a song if there is another one in the playlist.
+[SHIFT] + [RIGHT] to skip 10 seconds within the playing song (not in party modes).
+[CTRL] + [RIGHT] to skip 30 seconds within the playing song (not in party modes).
[T] to change the time format of the timer.
[I] to change view of player information.
[W] to activate the configured webcam.
@@ -156,6 +166,7 @@ Sing screen
Score and highscore screen
[LEFT] or [RIGHT] to show (high)scores of another round (if there is more than one)
+ if opened from song list screen: Switch between game modes (Normal, Medley, Duet, Short)
=================================
diff --git a/Output/Themes/Changelog/Changelog_ScreenSong.txt b/Output/Themes/Changelog/Changelog_ScreenSong.txt
index 4b71ef3c..7b5e00a2 100644
--- a/Output/Themes/Changelog/Changelog_ScreenSong.txt
+++ b/Output/Themes/Changelog/Changelog_ScreenSong.txt
@@ -1,5 +1,37 @@
ScreenSong
+++++++++++
+Version 10:
+
+Add:
+
+
+++++++++++
+Version 9:
+
+Add:
+
+
+Changed values at:
+
+
+++++++++++
+Version 8:
+
+Add:
+ to SongMenu
+
+
+
+++++++++++
+Version 7:
+
+Add:
+
+
+
+Shows key shortcut and search usage as small text line at the bottom of the screen.
+
++++++++++
Version 6:
@@ -43,4 +75,4 @@ to SongMenu
Add:
and
to SongMenu.SongMenuTileBoard
-++++++++++
\ No newline at end of file
+++++++++++
diff --git a/Output/Themes/Genius/01_Standard.xml b/Output/Themes/Genius/01_Standard.xml
index 8147bbdf..f3174336 100644
--- a/Output/Themes/Genius/01_Standard.xml
+++ b/Output/Themes/Genius/01_Standard.xml
@@ -353,6 +353,7 @@
DeleteIcon.png
SaveIcon.png
SingIcon.png
+ ListIcon.png
MinusIcon.png
PlusIcon.png
VolUp.png
diff --git a/Output/Themes/Genius/02_Ice_Blue.xml b/Output/Themes/Genius/02_Ice_Blue.xml
index 0e9d9806..9d27bd3b 100644
--- a/Output/Themes/Genius/02_Ice_Blue.xml
+++ b/Output/Themes/Genius/02_Ice_Blue.xml
@@ -353,6 +353,7 @@
DeleteIcon.png
SaveIcon.png
SingIcon.png
+ ListIcon.png
MinusIcon.png
PlusIcon.png
VolUp.png
diff --git a/Output/Themes/Genius/03_Crimson_Red.xml b/Output/Themes/Genius/03_Crimson_Red.xml
index aa3f4cfb..c29f5e8e 100644
--- a/Output/Themes/Genius/03_Crimson_Red.xml
+++ b/Output/Themes/Genius/03_Crimson_Red.xml
@@ -353,6 +353,7 @@
DeleteIcon.png
SaveIcon.png
SingIcon.png
+ ListIcon.png
MinusIcon.png
PlusIcon.png
VolUp.png
diff --git a/Output/Themes/Genius/ListIcon.png b/Output/Themes/Genius/ListIcon.png
new file mode 100644
index 00000000..33bd9d47
Binary files /dev/null and b/Output/Themes/Genius/ListIcon.png differ
diff --git a/Output/Themes/Genius/Screens/ScreenSing.xml b/Output/Themes/Genius/Screens/ScreenSing.xml
index 821093fb..44badc9c 100644
--- a/Output/Themes/Genius/Screens/ScreenSing.xml
+++ b/Output/Themes/Genius/Screens/ScreenSing.xml
@@ -2,7 +2,7 @@
ScreenSing
- 9
+ 10
@@ -46,7 +46,7 @@
0
- 0
+ 610
1280
90
-0.75
@@ -136,7 +136,7 @@
40
- 10
+ 623
45
36
-1
@@ -627,8 +627,33 @@
-0.75
+
+
+
+
+ 980
+ 0
+ 300
+ 30
+ -0.75
+
+
+
+ 1130
+ 2
+ -3
+ 25
+ 280
+
+
+ Center
+ Center
+
+ Outline
+
+
640
10
@@ -1501,7 +1526,7 @@
637
- 7
+ 620
1200
42
-1
@@ -1512,7 +1537,7 @@
637
- 48
+ 662
1200
35
-1
diff --git a/Output/Themes/Genius/Screens/ScreenSong.xml b/Output/Themes/Genius/Screens/ScreenSong.xml
index 1b74ad72..61852554 100644
--- a/Output/Themes/Genius/Screens/ScreenSong.xml
+++ b/Output/Themes/Genius/Screens/ScreenSong.xml
@@ -2,7 +2,7 @@
ScreenSong
- 6
+ 10
@@ -70,8 +70,33 @@
-2.1
+
+
+
+
+ 490
+ 0
+ 300
+ 30
+ -0.75
+
+
+
+ 640
+ 2
+ -1
+ 25
+ 280
+
+
+ Center
+ Center
+
+ Outline
+ TR_SCREENSONG_SORTING
+
950
65
@@ -238,6 +263,48 @@
Outline
TR_SCREENSONG_SONGOPTIONS
+
+ 40
+ 700
+ 0
+ 16
+ 1200
+
+
+ Left
+ Bottom
+
+ Outline
+ TR_SCREENSONG_HELPMESSAGE
+
+
+ 40
+ 700
+ 0
+ 16
+ 1200
+
+
+ Left
+ Bottom
+
+ Outline
+ TR_SCREENSONG_HELPMESSAGESEARCH
+
+
+ 40
+ 700
+ 0
+ 16
+ 1200
+
+
+ Left
+ Bottom
+
+ Outline
+ TR_SCREENSONG_HELPMESSAGEPARTY
+
+
@@ -811,19 +905,33 @@
- 222
+ 391
490
-1.01
28
- 340
+ 100
- Center
+ Right
Top
Outline
+
+ 52
+ 490
+ -1.01
+ 28
+ 100
+
+
+ Left
+ Top
+
+ Outline
+
+
@@ -896,16 +1004,16 @@
10
10
- 375
+ 410
42
- 850
+ 830
555
-1
- 375
+ 410
42
- 450
+ 410
550
-1
@@ -938,19 +1046,33 @@
- 222
+ 391
490
-1.01
28
- 340
+ 100
- Center
+ Right
Top
Outline
+
+ 52
+ 490
+ -1.01
+ 28
+ 100
+
+
+ Left
+ Top
+
+ Outline
+
+
@@ -1338,6 +1460,33 @@
+
+ ListIcon
+ ListIcon
+
+ 1120
+ 548
+ 35
+ 35
+ -1.01
+
+
+
+
+ 180
+ 5
+ 0
+ 25
+ 350
+
+
+ Center
+ Center
+
+ Outline
+
+
+
DeleteIcon
DeleteIcon
diff --git a/PitchTracker/PitchTracker.vcxproj b/PitchTracker/PitchTracker.vcxproj
index e601abf7..41ff0000 100644
--- a/PitchTracker/PitchTracker.vcxproj
+++ b/PitchTracker/PitchTracker.vcxproj
@@ -33,6 +33,7 @@
v120
v140
v141
+ v142
Unicode
@@ -43,6 +44,7 @@
v120
v140
v141
+ v142
Unicode
@@ -53,6 +55,7 @@
v120
v140
v141
+ v142
true
Unicode
@@ -64,6 +67,7 @@
v120
v140
v141
+ v142
true
Unicode
diff --git a/README.md b/README.md
index 36330d98..8c0b75a6 100644
--- a/README.md
+++ b/README.md
@@ -52,5 +52,4 @@ Vocaluxe Homepage: https://vocaluxe.org/
GitHub Wiki: https://github.com/Vocaluxe/Vocaluxe/wiki
GitHub Issues Tracker: https://github.com/Vocaluxe/Vocaluxe/issues
Translations: https://www.transifex.com/projects/p/vocaluxe/
-Support Forum (German): http://www.ultra-star.de
Song-Database (USDB): http://usdb.animux.de/
diff --git a/Vocaluxe/Base/CBackgroundMusic.cs b/Vocaluxe/Base/CBackgroundMusic.cs
index 5050b408..44295ce2 100644
--- a/Vocaluxe/Base/CBackgroundMusic.cs
+++ b/Vocaluxe/Base/CBackgroundMusic.cs
@@ -316,56 +316,33 @@ namespace Vocaluxe.Base
CSound.SetGlobalVolume(CConfig.PreviewMusicVolume);
}
+ //Change song position only if song is changed or near to end
bool songChanged = _CurPlayer.SongID != song.ID;
+ if (!songChanged && _CurPlayer.Position + 30 < _CurPlayer.Length)
+ return;
_PreviewPlayer.Load(song);
-
- //Change song position only if song is changed or near to end
- if (songChanged || _CurPlayer.Position + 30 < _CurPlayer.Length || _PreviewStartHelperTask == null)
+ lock (_PreviewStartHelperTaskLock)
{
- lock (_PreviewStartHelperTaskLock)
+ _PreviewStartHelperTask = new Task(() =>
{
- _PreviewStartHelperTask = new Task(() =>
- {
- float length = _PreviewPlayer.Length;
- if (length < 1)
- length = 30; // If length is unknow or invalid assume a length of 30s
+ float length = _PreviewPlayer.Length;
+ if (length < 1)
+ length = 30; // If length is unknow or invalid assume a length of 30s
- if (start < 0)
- start = (song.Preview.Source == EDataSource.None) ? length / 4f : song.Preview.StartTime;
- if (start > length - 5f)
- start = Math.Max(0f, Math.Min(length / 4f, length - 5f));
- if (start >= 0.5f)
- start -= 0.5f;
+ if (start < 0)
+ start = (song.Preview.Source == EDataSource.None) ? length / 4f : song.Preview.StartTime;
+ if (start > length - 5f)
+ start = Math.Max(0f, Math.Min(length / 4f, length - 5f));
+ if (start >= 0.5f)
+ start -= 0.5f;
- _PreviewPlayer.Position = start;
- Play();
- });
- }
- _CurPlayer = _PreviewPlayer;
+ _PreviewPlayer.Position = start;
+ Play();
+ });
}
- else
- {
- if (_PreviewStartHelperTask != null)
- {
- lock (_PreviewStartHelperTaskLock)
- {
- // Recheck the condition as it cloud have change before we got the lock
- if (_PreviewStartHelperTask != null)
- {
- _PreviewStartHelperTask = null;
- }
- }
- }
- _PreviewPlayer.Position = _CurPlayer.Position;
- _CurPlayer = _PreviewPlayer;
- Play();
- }
-
-
-
-
+ _CurPlayer = _PreviewPlayer;
}
public static void StopPreview()
@@ -460,4 +437,4 @@ namespace Vocaluxe.Base
return _BGMusicFiles.Contains(element);
}
}
-}
\ No newline at end of file
+}
diff --git a/Vocaluxe/Base/CConfig.cs b/Vocaluxe/Base/CConfig.cs
index 5d4fb05a..ec3de79d 100644
--- a/Vocaluxe/Base/CConfig.cs
+++ b/Vocaluxe/Base/CConfig.cs
@@ -688,7 +688,7 @@ namespace Vocaluxe.Base
{
//Check if folder exists
if (Directory.Exists(folder))
- SongFolders.Add(folder);
+ SongFolders.Add(Path.GetFullPath(folder));
}
}
@@ -715,7 +715,7 @@ namespace Vocaluxe.Base
Regex spliterVal = new Regex(@"\s", RegexOptions.IgnoreCase);
//split arg with Spilter-Regex and save in parts
- string[] parts = spliterVal.Split(text, 2);
+ string[] parts = spliterVal.Split(text.Trim(), 2);
switch (parts.Length)
{
@@ -853,4 +853,4 @@ namespace Vocaluxe.Base
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Vocaluxe/Base/CCover.cs b/Vocaluxe/Base/CCover.cs
index 3ac5a87b..f464d6d9 100644
--- a/Vocaluxe/Base/CCover.cs
+++ b/Vocaluxe/Base/CCover.cs
@@ -133,6 +133,11 @@ namespace Vocaluxe.Base
{
_UnloadCovers();
_LoadCovers();
+
+ // Stefan1200: Added a workaround to fix issue #446, because switching the cover theme gets bugged on the song screen and needed a game restart.
+ // Toggle the tabs view fixes this bug somehow.
+ CSongs.Categorizer.Tabs = (CConfig.Config.Game.Tabs == EOffOn.TR_CONFIG_ON ? EOffOn.TR_CONFIG_OFF : EOffOn.TR_CONFIG_ON);
+ CSongs.Categorizer.Tabs = CConfig.Config.Game.Tabs;
}
private static void _UnloadCovers()
@@ -288,4 +293,4 @@ namespace Vocaluxe.Base
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Vocaluxe/Base/CMain.cs b/Vocaluxe/Base/CMain.cs
index 0689ccba..89824b8b 100644
--- a/Vocaluxe/Base/CMain.cs
+++ b/Vocaluxe/Base/CMain.cs
@@ -964,6 +964,11 @@ namespace Vocaluxe.Base
CPlaylists.SetName(playlistID, name);
}
+ public List GetIds()
+ {
+ return CPlaylists.Ids;
+ }
+
public List GetNames()
{
return CPlaylists.Names;
@@ -1044,4 +1049,4 @@ namespace Vocaluxe.Base
return CPlaylists.ContainsSong(playlistID, songID);
}
}
-}
\ No newline at end of file
+}
diff --git a/Vocaluxe/Base/CSongFilter.cs b/Vocaluxe/Base/CSongFilter.cs
index 20596803..6d9870e6 100644
--- a/Vocaluxe/Base/CSongFilter.cs
+++ b/Vocaluxe/Base/CSongFilter.cs
@@ -1,4 +1,4 @@
-#region license
+#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
@@ -93,6 +93,89 @@ namespace Vocaluxe.Base
if (_SearchString != "")
searchStrings = _SearchString.ToUpper().Split(new char[] {' '});
+ String searchForArtist = null; // a:
+ String searchForTitle = null; // t:
+ String searchForGenre = null; // g:
+ String searchForYear = null; // y:
+ String searchForLanguage = null; // l:
+ String searchForCreator = null; // c:
+ String searchForEdition = null; // e:
+ String searchForAlbum = null; // al:
+ String searchForFileName = null; // fi:
+ String searchForFolderName = null; // fo:
+ bool expertSearch = false;
+
+ if (searchStrings != null)
+ {
+ foreach (String searchToken in searchStrings)
+ {
+ if (searchToken.Length < 3)
+ continue;
+
+ String temp = searchToken.Substring(0, 2);
+ bool foundIt = true;
+
+ switch (temp)
+ {
+ case "A:":
+ searchForArtist = searchToken.Substring(2);
+ break;
+ case "T:":
+ searchForTitle = searchToken.Substring(2);
+ break;
+ case "G:":
+ searchForGenre = searchToken.Substring(2);
+ break;
+ case "Y:":
+ searchForYear = searchToken.Substring(2);
+ break;
+ case "L:":
+ searchForLanguage = searchToken.Substring(2);
+ break;
+ case "C:":
+ searchForCreator = searchToken.Substring(2);
+ break;
+ case "E:":
+ searchForEdition = searchToken.Substring(2);
+ break;
+ default:
+ foundIt = false;
+ break;
+ }
+
+ if (foundIt)
+ {
+ if (!expertSearch) expertSearch = true;
+ continue;
+ }
+
+ if (searchToken.Length < 4)
+ continue;
+
+ foundIt = true;
+ temp = searchToken.Substring(0, 3);
+
+ switch (temp)
+ {
+ case "AL:":
+ searchForAlbum = searchToken.Substring(3);
+ break;
+ case "FI:":
+ searchForFileName = searchToken.Substring(3);
+ break;
+ case "FO:":
+ searchForFolderName = searchToken.Substring(3);
+ break;
+ default:
+ foundIt = false;
+ break;
+ }
+
+ if (foundIt && !expertSearch)
+ expertSearch = true;
+ }
+ }
+
foreach (CSong song in CSongs.Songs)
{
if (_PlaylistID != -1 && !CBase.Playlist.ContainsSong(_PlaylistID, song.ID))
@@ -102,9 +185,85 @@ namespace Vocaluxe.Base
{
if (searchStrings == null)
_FilteredSongs.Add(song);
+ else if (expertSearch)
+ {
+ // Stefan1200: Stop at a maximum of 500 search result to prevent performance issues
+ if (_FilteredSongs.Count >= 500)
+ break;
+
+ if (searchForAlbum != null && song.Album.ToUpper().Contains(searchForAlbum))
+ _FilteredSongs.Add(song);
+ if (searchForArtist != null && song.Artist.ToUpper().Contains(searchForArtist))
+ _FilteredSongs.Add(song);
+ if (searchForTitle != null && song.Title.ToUpper().Contains(searchForTitle))
+ _FilteredSongs.Add(song);
+ if (searchForCreator != null && song.Creator.ToUpper().Contains(searchForCreator))
+ _FilteredSongs.Add(song);
+ if (searchForFileName != null && song.FileName.ToUpper().Contains(searchForFileName))
+ _FilteredSongs.Add(song);
+ if (searchForFolderName != null && song.FolderName.ToUpper().Contains(searchForFolderName))
+ _FilteredSongs.Add(song);
+
+ if (searchForGenre != null)
+ {
+ foreach (String genre in song.Genres)
+ {
+ if (genre.ToUpper().Contains(searchForGenre))
+ _FilteredSongs.Add(song);
+ }
+ }
+
+ if (searchForLanguage != null)
+ {
+ foreach (String language in song.Languages)
+ {
+ if (language.ToUpper().Contains(searchForLanguage))
+ _FilteredSongs.Add(song);
+ }
+ }
+
+ if (searchForEdition != null)
+ {
+ foreach (String edition in song.Editions)
+ {
+ if (edition.ToUpper().Contains(searchForEdition))
+ _FilteredSongs.Add(song);
+ }
+ }
+
+ if (searchForYear != null)
+ {
+ int pos = searchForYear.IndexOf("-");
+ if (pos == -1)
+ {
+ if (song.Year.Contains(searchForYear))
+ _FilteredSongs.Add(song);
+ }
+ else if (searchForYear.Length == 9)
+ {
+ int yearStart = -1;
+ int yearEnd = -1;
+ if (!Int32.TryParse(searchForYear.Substring(0, pos), out yearStart))
+ continue;
+ if (!Int32.TryParse(searchForYear.Substring(pos + 1), out yearEnd))
+ continue;
+
+ // Stefan1200: Prevent searches like 0000-9999, limit for a max distance of 100 years
+ if (yearEnd - yearStart > 100)
+ continue;
+
+ int yearSearch = -1;
+ if (!Int32.TryParse(song.Year, out yearSearch))
+ continue;
+
+ if (yearSearch >= yearStart && yearSearch <= yearEnd)
+ _FilteredSongs.Add(song);
+ }
+ }
+ }
else
{
- string search = song.Title.ToUpper() + " " + song.Artist.ToUpper() + " " + song.FolderName.ToUpper() + " " + song.FileName.ToUpper();
+ string search = song.Title.ToUpper() + " " + song.Artist.ToUpper();
if (searchStrings.All(search.Contains))
_FilteredSongs.Add(song);
@@ -114,4 +273,4 @@ namespace Vocaluxe.Base
_Changed = false;
}
}
-}
\ No newline at end of file
+}
diff --git a/Vocaluxe/Base/CSongSorter.cs b/Vocaluxe/Base/CSongSorter.cs
index 8a956107..d4b59f13 100644
--- a/Vocaluxe/Base/CSongSorter.cs
+++ b/Vocaluxe/Base/CSongSorter.cs
@@ -111,6 +111,24 @@ namespace Vocaluxe.Base
return res;
}
+ ///
+ /// Compares two songs by means of: first letter of sorting field, sorting field, title.
+ ///
+ private int _SortByLetterFieldTitle(CSongPointer s1, CSongPointer s2)
+ {
+ int res = String.Compare(s1.SortString[0].ToString(), s2.SortString[0].ToString(), StringComparison.CurrentCultureIgnoreCase);
+ return res != 0 ? res : _SortByFieldTitle(s1, s2);
+ }
+
+ ///
+ /// Compares two songs by means of: first letter of sorting field, sorting field, artist, title.
+ ///
+ private int _SortByLetterFieldArtistTitle(CSongPointer s1, CSongPointer s2)
+ {
+ int res = String.Compare(s1.SortString[0].ToString(), s2.SortString[0].ToString(), StringComparison.CurrentCultureIgnoreCase);
+ return res != 0 ? res : _SortByFieldArtistTitle(s1, s2);
+ }
+
private void _AddSongToList(CSong song, List list)
{
string value = null;
@@ -172,17 +190,26 @@ namespace Vocaluxe.Base
_AddSongToList(song, sortList);
switch (_SongSorting)
{
- case ESongSorting.TR_CONFIG_ARTIST_LETTER:
case ESongSorting.TR_CONFIG_ARTIST:
case ESongSorting.TR_CONFIG_NONE:
sortList.Sort(_SortByFieldTitle);
break;
+ case ESongSorting.TR_CONFIG_ARTIST_LETTER:
+ sortList.Sort(_SortByLetterFieldTitle);
+ break;
+ case ESongSorting.TR_CONFIG_TITLE_LETTER:
+ sortList.Sort(_SortByLetterFieldArtistTitle);
+ break;
default:
sortList.Sort(_SortByFieldArtistTitle);
break;
}
+
+ if (_SongSorting == ESongSorting.TR_CONFIG_DATEADDED)
+ sortList.Reverse();
+
_SortedSongs = sortList.ToArray();
_Changed = false;
}
}
-}
\ No newline at end of file
+}
diff --git a/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs b/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs
index 6af5d259..51031b77 100644
--- a/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs
+++ b/Vocaluxe/Lib/Video/Acinerella/CAcinerella.cs
@@ -397,7 +397,7 @@ namespace Vocaluxe.Lib.Video.Acinerella
{
lock (_GetLockToken(pAcDecoder))
{
- return _ac_get_audio_frame(pAcInstance, pAcDecoder) != 0;
+ return _ac_get_audio_frame(pAcInstance, pAcDecoder) == 0;
}
}
@@ -408,7 +408,8 @@ namespace Vocaluxe.Lib.Video.Acinerella
{
lock (_GetLockToken(pAcDecoder))
{
- return _ac_get_frame(pAcInstance, pAcDecoder) != 0;
+ int asd = _ac_get_frame(pAcInstance, pAcDecoder);
+ return asd == 0;
}
}
@@ -419,14 +420,14 @@ namespace Vocaluxe.Lib.Video.Acinerella
{
lock (_GetLockToken(pAcDecoder))
{
- return _ac_skip_frames(pAcInstance, pAcDecoder, num) != 0;
+ return _ac_skip_frames(pAcInstance, pAcDecoder, num) == 0;
}
}
// Seeks to the given target position in the file. The seek funtion is not able to seek a single audio/video stream
// but seeks the whole file forward. The deocder parameter is only used as an timecode reference.
// The parameter "dir" specifies the seek direction: 0 for forward, -1 for backward.
- // The target_pos paremeter is in milliseconds. Returns 1 if the functions succeded.}
+ // The target_pos paremeter is in milliseconds. Returns 0 if the functions succeded.}
//function ac_seek(pDecoder: PAc_decoder; dir: integer; target_pos: int64): integer; cdecl; external ac_dll;
[DllImport(_AcDll, EntryPoint = "ac_seek", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
private static extern Int32 _ac_seek(IntPtr pAcDecoder, Int32 dir, Int64 targetPos);
@@ -435,7 +436,7 @@ namespace Vocaluxe.Lib.Video.Acinerella
{
lock (_GetLockToken(pAcDecoder))
{
- return _ac_seek(pAcDecoder, dir, targetPos) != 0;
+ return _ac_seek(pAcDecoder, dir, targetPos) == 0;
}
}
diff --git a/Vocaluxe/Lib/Video/Acinerella/acinerella.c b/Vocaluxe/Lib/Video/Acinerella/acinerella.c
index a61fd875..73961cd0 100644
--- a/Vocaluxe/Lib/Video/Acinerella/acinerella.c
+++ b/Vocaluxe/Lib/Video/Acinerella/acinerella.c
@@ -23,7 +23,7 @@
#include
#include
#include
-#include "libavutil/imgutils.h"
+#include
#include
#include
@@ -37,17 +37,17 @@
#define PROBE_BUF_MAX (1 << 20)
#define ERR(E) \
- { \
+ do { \
if (!(E)) { \
goto error; \
} \
- }
+ } while (0)
#define AV_ERR(E) \
- { \
+ do { \
if ((E) < 0) { \
goto error; \
} \
- }
+ } while (0)
struct _ac_data {
ac_instance instance;
@@ -141,6 +141,13 @@ void init_info(lp_ac_file_info info)
info->bitrate = -1;
}
+/* avcodec_register_all(), av_register_all() deprecated since lavc 58.9.100 */
+#if (LIBAVCODEC_VERSION_MAJOR < 58) || \
+ ((LIBAVCODEC_VERSION_MAJOR == 58) && (LIBAVCODEC_VERSION_MINOR < 9))
+#define AC_NEED_REGISTER_ALL
+#endif
+
+#ifdef AC_NEED_REGISTER_ALL
int av_initialized = 0;
void ac_init_ffmpeg()
{
@@ -151,14 +158,17 @@ void ac_init_ffmpeg()
av_initialized = 1;
}
}
+#endif /* AC_NEED_REGISTER_ALL */
lp_ac_instance CALL_CONVT ac_init(void)
{
+#ifdef AC_NEED_REGISTER_ALL
ac_init_ffmpeg();
+#endif /* AC_NEED_REGISTER_ALL */
// Allocate a new instance of the videoplayer data and return it
lp_ac_data ptmp;
- ptmp = (lp_ac_data)av_malloc(sizeof(ac_data));
+ ERR(ptmp = (lp_ac_data)av_malloc(sizeof(ac_data)));
// Initialize the created structure
memset(ptmp, 0, sizeof(ac_data));
@@ -168,11 +178,16 @@ lp_ac_instance CALL_CONVT ac_init(void)
ptmp->instance.output_format = AC_OUTPUT_BGR24;
init_info(&(ptmp->instance.info));
return (lp_ac_instance)ptmp;
+
+error:
+ return NULL;
}
lp_ac_instance CALL_CONVT ac_init_of(ac_output_format outputFormat)
{
+#ifdef AC_NEED_REGISTER_ALL
ac_init_ffmpeg();
+#endif /* AC_NEED_REGISTER_ALL */
// Allocate a new instance of the videoplayer data and return it
lp_ac_data ptmp;
@@ -206,9 +221,11 @@ static int io_read(void *opaque, uint8_t *buf, int buf_size)
// If there is still memory in the probe buffer, consume this memory first
if (self->probe_buffer &&
self->probe_buffer_offs < self->probe_buffer_size) {
+
+ unsigned int buf_size_u = (unsigned int)buf_size;
// Copy as many bytes as possible from the probe buffer
size_t cnt =
- MIN(buf_size, self->probe_buffer_size - self->probe_buffer_offs);
+ MIN(buf_size_u, self->probe_buffer_size - self->probe_buffer_offs);
memcpy(buf, self->probe_buffer + self->probe_buffer_offs, cnt);
// Advance the read/write pointers
@@ -223,6 +240,9 @@ static int io_read(void *opaque, uint8_t *buf, int buf_size)
self->probe_buffer_size = 0;
self->probe_buffer_offs = 0;
}
+
+ // Return the actual bytes obtained from the memory buffer
+ return (int)cnt;
}
// Try to read the memory from the probe buffer
@@ -238,6 +258,17 @@ static int64_t io_seek(void *opaque, int64_t pos, int whence)
lp_ac_data self = ((lp_ac_data)opaque);
if (self->seek_proc != NULL) {
if ((whence >= 0) && (whence <= 2)) {
+ // Throw away the probe buffer if seek is performed.
+ // NOTE: This could be improved to check if the seek
+ // is inside the probe_buffer, but it would get really
+ // complicated as real seek would need to be omitted
+ // then.
+ if (self->probe_buffer) {
+ av_free(self->probe_buffer);
+ self->probe_buffer = NULL;
+ self->probe_buffer_size = 0;
+ self->probe_buffer_offs = 0;
+ }
return self->seek_proc(self->sender, pos, whence);
}
}
@@ -251,8 +282,10 @@ lp_ac_proberesult CALL_CONVT ac_probe_input_buffer(uint8_t *buf, int bufsize,
AVProbeData pd;
AVInputFormat *fmt = NULL;
+#ifdef AC_NEED_REGISTER_ALL
// Initialize FFMpeg libraries
ac_init_ffmpeg();
+#endif /* AC_NEED_REGISTER_ALL */
// Set the filename and mime_type
pd.mime_type = "";
@@ -263,8 +296,9 @@ lp_ac_proberesult CALL_CONVT ac_probe_input_buffer(uint8_t *buf, int bufsize,
// The given buffer has to be copied to a new one, which is aligned and
// padded
- uint8_t *aligned_buf = av_malloc(bufsize + AVPROBE_PADDING_SIZE);
- memset(aligned_buf, 0, bufsize + AVPROBE_PADDING_SIZE);
+ uint8_t *aligned_buf;
+ ERR(aligned_buf = av_malloc(bufsize + AVPROBE_PADDING_SIZE));
+ memset(aligned_buf, 0, bufsize + AVPROBE_PADDING_SIZE);
memcpy(aligned_buf, buf, bufsize);
// Set the probe data buffer
@@ -282,6 +316,9 @@ lp_ac_proberesult CALL_CONVT ac_probe_input_buffer(uint8_t *buf, int bufsize,
av_free(aligned_buf);
return (lp_ac_proberesult)fmt;
+
+error:
+ return NULL;
}
AVInputFormat *ac_probe_input_stream(void *sender, ac_read_callback read_proc,
@@ -302,6 +339,9 @@ AVInputFormat *ac_probe_input_stream(void *sender, ac_read_callback read_proc,
// Allocate some memory for the current probe buffer
uint8_t *tmp_buf = av_malloc(probe_size);
+ if (!tmp_buf) {
+ return fmt; // An error occurred, abort
+ }
memset(tmp_buf, 0, probe_size);
// Copy the old data to the new buffer
@@ -309,6 +349,8 @@ AVInputFormat *ac_probe_input_stream(void *sender, ac_read_callback read_proc,
memcpy(tmp_buf, *buf, *buf_read);
// Free the old data memory
av_free(*buf);
+ // Zero the pointer to avoid double free on read_proc error
+ *buf = NULL;
}
// Read the new data
@@ -319,6 +361,7 @@ AVInputFormat *ac_probe_input_stream(void *sender, ac_read_callback read_proc,
return fmt; // An error occurred, abort
}
if (size < read_size) {
+ av_free(tmp_buf);
last_iteration = 1;
probe_size = (int)*buf_read + size;
}
@@ -341,7 +384,8 @@ static void cpymetadata(const AVFormatContext *ctx, const char *key, char *tar,
{
const AVDictionaryEntry *entry = av_dict_get(ctx->metadata, key, NULL, 0);
if (entry) {
- strncpy_s(tar, len, entry->value, len);
+ strncpy_s(tar, len, entry->value, len-1);
+ tar[len - 1] = '\0';
} else {
strncpy_s(tar, len, "", len);
}
@@ -413,6 +457,7 @@ int CALL_CONVT ac_open(lp_ac_instance pacInstance, void *sender,
// Call the file open proc
if (self->open_proc != NULL) {
if (self->open_proc(sender) < 0) {
+ ac_close(pacInstance);
return -1;
}
}
@@ -434,22 +479,27 @@ int CALL_CONVT ac_open(lp_ac_instance pacInstance, void *sender,
}
// Reserve the buffer memory and initialise the context
- self->buffer = av_malloc(AC_BUFSIZE);
- self->pIo = avio_alloc_context(self->buffer, AC_BUFSIZE, 0, self, io_read,
- 0, seek_proc ? io_seek : NULL);
+ ERR(self->buffer = av_malloc(AC_BUFSIZE));
+ ERR(self->pIo = avio_alloc_context(self->buffer, AC_BUFSIZE, 0, self, io_read,
+ 0, seek_proc ? io_seek : NULL));
self->pIo->seekable = seek_proc != NULL;
// Open the given input stream (the io structure) with the given format of
// the stream (fmt) and write the pointer to the new format context to the
// pFormatCtx variable
- self->pFormatCtx = avformat_alloc_context();
+ ERR(self->pFormatCtx = avformat_alloc_context());
self->pFormatCtx->pb = self->pIo;
+
if (avformat_open_input(&(self->pFormatCtx), "", fmt, NULL) < 0) {
ac_close(pacInstance);
return -1;
}
return finalize_open(pacInstance);
+
+error:
+ ac_close(pacInstance);
+ return -1;
}
int CALL_CONVT ac_open_file(lp_ac_instance pacInstance, const char *filename)
@@ -601,16 +651,19 @@ void CALL_CONVT ac_get_stream_info(lp_ac_instance pacInstance, int nb,
lp_ac_package CALL_CONVT ac_read_package(lp_ac_instance pacInstance)
{
// Allocate the result packet
- lp_ac_package_data pkt = av_malloc(sizeof(ac_package_data));
+ lp_ac_package_data pkt;
+ ERR(pkt = av_malloc(sizeof(ac_package_data)));
memset(pkt, 0, sizeof(ac_package_data));
- pkt->pPack = av_malloc(sizeof(AVPacket));
+ ERR(pkt->pPack = av_malloc(sizeof(AVPacket)));
av_init_packet(pkt->pPack);
pkt->pPack->data = NULL;
pkt->pPack->size = 0;
// Try to read package
- if (av_read_frame(((lp_ac_data)(pacInstance))->pFormatCtx, pkt->pPack) >=
+ int av_read_frame_status =
+ av_read_frame(((lp_ac_data)(pacInstance))->pFormatCtx, pkt->pPack);
+ if (av_read_frame_status >=
0) {
if (pkt->pPack->dts != AV_NOPTS_VALUE) {
pkt->pts = (int)pkt->pPack->dts;
@@ -620,22 +673,18 @@ lp_ac_package CALL_CONVT ac_read_package(lp_ac_instance pacInstance)
}
ac_free_package((lp_ac_package)pkt);
return NULL;
+
+error:
+ ac_free_package((lp_ac_package)pkt);
+ return NULL;
}
// Frees the currently loaded package
void CALL_CONVT ac_free_package(lp_ac_package pPackage)
{
if (pPackage) {
- lp_ac_package_data self = (lp_ac_package_data)pPackage;
- if (self->pPack) {
- if (self->pPack->buf) {
- av_buffer_unref(&self->pPack->buf);
- }
- self->pPack->data = NULL;
- self->pPack->size = 0;
-
- av_packet_free_side_data(self->pPack);
- }
+ lp_ac_package_data self = (lp_ac_package_data)pPackage;
+ av_packet_unref(self->pPack);
av_free(self->pPack);
av_free(self);
}
@@ -672,7 +721,7 @@ void *ac_create_video_decoder(lp_ac_instance pacInstance,
{
// Allocate memory for a new decoder instance
lp_ac_video_decoder pDecoder;
- pDecoder = (lp_ac_video_decoder)(av_malloc(sizeof(ac_video_decoder)));
+ ERR(pDecoder = (lp_ac_video_decoder)(av_malloc(sizeof(ac_video_decoder))));
memset(pDecoder, 0, sizeof(ac_video_decoder));
// Set a few properties
@@ -686,20 +735,26 @@ void *ac_create_video_decoder(lp_ac_instance pacInstance,
// Find correspondenting codec
if (!(pDecoder->pCodec =
avcodec_find_decoder(pCodecParam->codec_id))) {
+ ac_free_video_decoder(pDecoder);
return NULL; // Codec could not have been found
}
- pDecoder->pCodecCtx = avcodec_alloc_context3(pDecoder->pCodec);
- avcodec_parameters_to_context(pDecoder->pCodecCtx, pCodecParam);
+ ERR(pDecoder->pCodecCtx = avcodec_alloc_context3(pDecoder->pCodec));
+ if (avcodec_parameters_to_context(pDecoder->pCodecCtx, pCodecParam) < 0)
+ {
+ ac_free_video_decoder(pDecoder);
+ return NULL;
+ }
// Open codec
if (avcodec_open2(pDecoder->pCodecCtx, pDecoder->pCodec, NULL) < 0) {
+ ac_free_video_decoder(pDecoder);
return NULL; // Codec could not have been opened
}
// Reserve frame variables
- pDecoder->pFrame = av_frame_alloc();
- pDecoder->pFrameRGB = av_frame_alloc();
+ ERR(pDecoder->pFrame = av_frame_alloc());
+ ERR(pDecoder->pFrameRGB = av_frame_alloc());
pDecoder->pSwsCtx = NULL;
@@ -712,14 +767,22 @@ void *ac_create_video_decoder(lp_ac_instance pacInstance,
(uint8_t *)av_malloc(pDecoder->decoder.buffer_size);
// Link decoder to buffer
- av_image_fill_arrays(pDecoder->pFrameRGB->data,
+ if(av_image_fill_arrays(pDecoder->pFrameRGB->data,
pDecoder->pFrameRGB->linesize,
pDecoder->decoder.pBuffer,
convert_pix_format(pacInstance->output_format),
pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height,
- 1);
+ 1) < 0)
+ {
+ ac_free_video_decoder(pDecoder);
+ return NULL;
+ }
return (void *)pDecoder;
+
+error:
+ ac_free_video_decoder(pDecoder);
+ return NULL;
}
// Init a audio decoder
@@ -771,8 +834,8 @@ void *ac_create_audio_decoder(lp_ac_instance pacInstance,
if (out_fmt == AV_SAMPLE_FMT_DBL || out_fmt == AV_SAMPLE_FMT_S32) {
out_fmt = AV_SAMPLE_FMT_FLT;
}
- pDecoder->pSwrCtx = swr_alloc_set_opts(NULL, layout, out_fmt, rate,
- layout, fmt, rate, 0, NULL);
+ ERR(pDecoder->pSwrCtx = swr_alloc_set_opts(NULL, layout, out_fmt, rate,
+ layout, fmt, rate, 0, NULL));
AV_ERR(swr_init(pDecoder->pSwrCtx));
}
return (void *)pDecoder;
@@ -813,31 +876,45 @@ int ac_decode_video_package(lp_ac_package pPackage,
{
lp_ac_package_data pkt = ((lp_ac_package_data)pPackage);
- if(avcodec_send_packet(pDecoder->pCodecCtx, pkt->pPack) != 0)
+ if(avcodec_send_packet(pDecoder->pCodecCtx, pkt->pPack) < 0)
{
- return 0;
+ return -1;
}
- if (avcodec_receive_frame(pDecoder->pCodecCtx, pDecoder->pFrame) != 0)
+ int avcodec_receive_frame_response;
+
+ do
{
- return 0;
- }
+ avcodec_receive_frame_response = avcodec_receive_frame(pDecoder->pCodecCtx,
+ pDecoder->pFrame);
+ if (avcodec_receive_frame_response == AVERROR(EAGAIN) ||
+ avcodec_receive_frame_response == AVERROR_EOF) {
+ return avcodec_receive_frame_response;
+ }
- pDecoder->pSwsCtx = sws_getCachedContext(
+ } while (avcodec_receive_frame_response > 0);
+
+ if((pDecoder->pSwsCtx = sws_getCachedContext(
pDecoder->pSwsCtx, pDecoder->pCodecCtx->width,
pDecoder->pCodecCtx->height, pDecoder->pCodecCtx->pix_fmt,
pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height,
convert_pix_format(pDecoder->decoder.pacInstance->output_format),
- SWS_BICUBIC, NULL, NULL, NULL);
-
- sws_scale(pDecoder->pSwsCtx,
+ SWS_BICUBIC, NULL, NULL, NULL)) < 0)
+ {
+ return -3;
+ }
+
+ if(sws_scale(pDecoder->pSwsCtx,
(const uint8_t *const *)(pDecoder->pFrame->data),
pDecoder->pFrame->linesize,
0, //?
pDecoder->pCodecCtx->height, pDecoder->pFrameRGB->data,
- pDecoder->pFrameRGB->linesize);
- return 1;
-
+ pDecoder->pFrameRGB->linesize) < 0)
+ {
+ return -4;
+ }
+
+ return 0;
}
int ac_skip_video_package(lp_ac_package pPackage,
@@ -845,17 +922,17 @@ int ac_skip_video_package(lp_ac_package pPackage,
{
lp_ac_package_data pkt = ((lp_ac_package_data)pPackage);
- if (avcodec_send_packet(pDecoder->pCodecCtx, pkt->pPack) != 0)
+ if (avcodec_send_packet(pDecoder->pCodecCtx, pkt->pPack) < 0)
{
- return 0;
+ return -1;
}
- if (avcodec_receive_frame(pDecoder->pCodecCtx, pDecoder->pFrame) != 0)
+ if (avcodec_receive_frame(pDecoder->pCodecCtx, pDecoder->pFrame) < 0)
{
- return 0;
+ return -2;
}
- return 1;
+ return 0;
}
int ac_decode_audio_package(lp_ac_package pPackage,
@@ -865,14 +942,14 @@ int ac_decode_audio_package(lp_ac_package pPackage,
int len = 0;
lp_ac_package_data pkt = ((lp_ac_package_data)pPackage);
- if (avcodec_send_packet(pDecoder->pCodecCtx, pkt->pPack) != 0)
+ if (avcodec_send_packet(pDecoder->pCodecCtx, pkt->pPack) < 0)
{
- return 0;
+ return -1;
}
- if (avcodec_receive_frame(pDecoder->pCodecCtx, pDecoder->pFrame) != 0)
+ if (avcodec_receive_frame(pDecoder->pCodecCtx, pDecoder->pFrame) < 0)
{
- return 0;
+ return -2;
}
// Calculate the output buffer size
@@ -885,38 +962,42 @@ int ac_decode_audio_package(lp_ac_package pPackage,
if (pDecoder->pSwrCtx) {
if (pDecoder->own_buffer_size != buffer_size) {
- pDecoder->decoder.pBuffer =
- av_realloc(pDecoder->decoder.pBuffer, buffer_size);
+ ERR(pDecoder->decoder.pBuffer =
+ av_realloc(pDecoder->decoder.pBuffer, buffer_size));
pDecoder->own_buffer_size = buffer_size;
}
- swr_convert(pDecoder->pSwrCtx, &(pDecoder->decoder.pBuffer),
+ if(swr_convert(pDecoder->pSwrCtx, &(pDecoder->decoder.pBuffer),
sample_count, (const uint8_t **)(pDecoder->pFrame->data),
- sample_count);
+ sample_count) < 0)
+ {
+ return -3;
+ }
} else {
// No conversion needs to be done, simply set the buffer pointer
pDecoder->decoder.pBuffer = pDecoder->pFrame->data[0];
}
return got_frame;
+error:
+ return -4;
}
int ac_skip_audio_package(lp_ac_package pPackage,
lp_ac_audio_decoder pDecoder)
-{
- int got_frame = 0;
+{
int len = 0;
lp_ac_package_data pkt = ((lp_ac_package_data)pPackage);
- if (avcodec_send_packet(pDecoder->pCodecCtx, pkt->pPack) != 0)
+ if (avcodec_send_packet(pDecoder->pCodecCtx, pkt->pPack) < 0)
{
- return 0;
+ return -1;
}
- if (avcodec_receive_frame(pDecoder->pCodecCtx, pDecoder->pFrame) != 0)
+ if (avcodec_receive_frame(pDecoder->pCodecCtx, pDecoder->pFrame) < 0)
{
- return 0;
+ return -2;
}
- return got_frame;
+ return 0;
}
int CALL_CONVT ac_decode_package(lp_ac_package pPackage, lp_ac_decoder pDecoder)
@@ -957,7 +1038,7 @@ int CALL_CONVT ac_decode_package(lp_ac_package pPackage, lp_ac_decoder pDecoder)
} else if (pDecoder->type == AC_DECODER_TYPE_AUDIO) {
return ac_decode_audio_package(pPackage, (lp_ac_audio_decoder)pDecoder);
}
- return 0;
+ return -10;
}
int CALL_CONVT ac_skip_package(lp_ac_package pPackage, lp_ac_decoder pDecoder)
@@ -1000,14 +1081,14 @@ int CALL_CONVT ac_skip_package(lp_ac_package pPackage, lp_ac_decoder pDecoder)
else if (pDecoder->type == AC_DECODER_TYPE_AUDIO) {
return ac_skip_audio_package(pPackage, (lp_ac_audio_decoder)pDecoder);
}
- return 0;
+ return -9;
}
int CALL_CONVT ac_skip_frames(lp_ac_instance pacInstance, lp_ac_decoder pDecoder, int num)
{
if (pDecoder == NULL)
{
- return 0;
+ return -1;
}
int skipedFrames = 0;
@@ -1018,7 +1099,7 @@ int CALL_CONVT ac_skip_frames(lp_ac_instance pacInstance, lp_ac_decoder pDecoder
if (pckt != NULL)
{
// Decode the package to figure out if its completing a frame
- if (pckt->stream_index == pDecoder->stream_index && ac_skip_package(pckt, pDecoder) != 0)
+ if (pckt->stream_index == pDecoder->stream_index && ac_skip_package(pckt, pDecoder) == 0)
{
skipedFrames++;
}
@@ -1027,17 +1108,17 @@ int CALL_CONVT ac_skip_frames(lp_ac_instance pacInstance, lp_ac_decoder pDecoder
}
else
{
- return 0;
+ return -2;
}
}
- return 1;
+ return 0;
}
int CALL_CONVT ac_get_frame(lp_ac_instance pacInstance, lp_ac_decoder pDecoder)
{
if (pDecoder == NULL)
{
- return 0;
+ return -1;
}
do
@@ -1045,7 +1126,7 @@ int CALL_CONVT ac_get_frame(lp_ac_instance pacInstance, lp_ac_decoder pDecoder)
lp_ac_package pckt = ac_read_package(pacInstance);
if (pckt == NULL)
{
- return 0;
+ return -2;
}
if(pckt->stream_index != pDecoder->stream_index)
@@ -1054,13 +1135,16 @@ int CALL_CONVT ac_get_frame(lp_ac_instance pacInstance, lp_ac_decoder pDecoder)
}
// The packet is for the video stream, try to decode it
- if (ac_decode_package(pckt, pDecoder) != 0)
- {
- ac_free_package(pckt);
- return 1;
- }
+ int _status = ac_decode_package(pckt, pDecoder);
ac_free_package(pckt);
+
+ if (_status > 0 || _status == AVERROR(EAGAIN))
+ {
+ continue;
+ }
+
+ return _status;
} while (true);
}
@@ -1069,7 +1153,7 @@ int CALL_CONVT ac_get_audio_frame(lp_ac_instance pacInstance, lp_ac_decoder pDec
{
if (pDecoder == NULL)
{
- return 0;
+ return -1;
}
do
@@ -1077,7 +1161,7 @@ int CALL_CONVT ac_get_audio_frame(lp_ac_instance pacInstance, lp_ac_decoder pDec
lp_ac_package pckt = ac_read_package(pacInstance);
if (pckt == NULL)
{
- return 0;
+ return -2;
}
if (pckt->stream_index != pDecoder->stream_index)
@@ -1085,15 +1169,16 @@ int CALL_CONVT ac_get_audio_frame(lp_ac_instance pacInstance, lp_ac_decoder pDec
continue;
}
- // The packet is for the audio stream, try to decode it
- if (ac_decode_package(pckt, pDecoder) != 0)
- {
- ac_free_package(pckt);
- return 1;
- }
+ // The packet is for the video stream, try to decode it
+ int _status = ac_decode_package(pckt, pDecoder);
- ac_free_package(pckt);
+ ac_free_package(pckt);
+ if (_status > 0 || _status == AVERROR(EAGAIN)) {
+ continue;
+ }
+
+ return _status;
} while (true);
}
@@ -1115,18 +1200,18 @@ int CALL_CONVT ac_seek(lp_ac_decoder pDecoder, int dir, int64_t target_pos)
pDecoder->stream_index,
av_rescale_q(pos, AV_TIME_BASE_Q, timebase),
flags) >= 0) {
- return 1;
+ return 0;
}
- return 0;
+ return -1;
}
// Free video decoder
void ac_free_video_decoder(lp_ac_video_decoder pDecoder)
{
if (pDecoder) {
- av_free(pDecoder->pFrame);
- av_free(pDecoder->pFrameRGB);
+ av_frame_free(&(pDecoder->pFrame));
+ av_frame_free(&(pDecoder->pFrameRGB));
sws_freeContext(pDecoder->pSwsCtx);
avcodec_free_context(&pDecoder->pCodecCtx);
av_free(pDecoder->decoder.pBuffer);
diff --git a/Vocaluxe/Screens/CScreenHighscore.cs b/Vocaluxe/Screens/CScreenHighscore.cs
index 0e6a746f..19769991 100644
--- a/Vocaluxe/Screens/CScreenHighscore.cs
+++ b/Vocaluxe/Screens/CScreenHighscore.cs
@@ -49,6 +49,7 @@ namespace Vocaluxe.Screens
private int _Round;
private int _Pos;
private bool _IsDuet;
+ private bool _FromScreenSong = false;
public override EMusicType CurrentMusicType
{
@@ -113,11 +114,13 @@ namespace Vocaluxe.Screens
break;
case Keys.Down:
- _ChangePos(1);
+ if (!_FromScreenSong)
+ _ChangePos(1);
break;
case Keys.Up:
- _ChangePos(-1);
+ if (!_FromScreenSong)
+ _ChangePos(-1);
break;
case Keys.Left:
@@ -234,13 +237,37 @@ namespace Vocaluxe.Screens
{
_Pos = 0;
int rounds = CGame.NumRounds;
- _Scores = new List[rounds];
- for (int round = 0; round < rounds; round++)
+
+ if (rounds == 0)
{
- int songID = CGame.GetSong(round).ID;
- EGameMode gameMode = CGame.GetGameMode(round);
+ _FromScreenSong = true;
+ _Round = (int)EGameMode.TR_GAMEMODE_NORMAL;
+ _Scores = new List[4];
+ int songID = CScreenSong.getSelectedSongID();
EHighscoreStyle style = CBase.Config.GetHighscoreStyle();
- _Scores[round] = CDataBase.LoadScore(songID, gameMode, style);
+ bool foundHighscoreEntries = false;
+
+ for (int gameModeNum = 0; gameModeNum < 4; gameModeNum++)
+ {
+ _Scores[gameModeNum] = CDataBase.LoadScore(songID, (EGameMode)gameModeNum, style);
+ if (!foundHighscoreEntries && _Scores[gameModeNum].Count > 0)
+ {
+ _Round = gameModeNum;
+ foundHighscoreEntries = true;
+ }
+ }
+ }
+ else
+ {
+ _FromScreenSong = false;
+ _Scores = new List[rounds];
+ for (int round = 0; round < rounds; round++)
+ {
+ int songID = CGame.GetSong(round).ID;
+ EGameMode gameMode = CGame.GetGameMode(round);
+ EHighscoreStyle style = CBase.Config.GetHighscoreStyle();
+ _Scores[round] = CDataBase.LoadScore(songID, gameMode, style);
+ }
}
}
@@ -248,15 +275,21 @@ namespace Vocaluxe.Screens
{
_IsDuet = false;
CPoints points = CGame.GetPoints();
- CSong song = CGame.GetSong(_Round);
+
+ CSong song;
+ if (_FromScreenSong)
+ song = CSongs.GetSong(CScreenSong.getSelectedSongID());
+ else
+ song = CGame.GetSong(_Round);
+
if (song == null)
return;
_Texts[_TextSongName].Text = song.Artist + " - " + song.Title;
- if (points.NumRounds > 1)
+ if (points != null && !_FromScreenSong && points.NumRounds > 1)
_Texts[_TextSongName].Text += " (" + (_Round + 1) + "/" + points.NumRounds + ")";
- switch (CGame.GetGameMode(_Round))
+ switch ((_FromScreenSong ? (EGameMode)_Round : CGame.GetGameMode(_Round)))
{
case EGameMode.TR_GAMEMODE_NORMAL:
_Texts[_TextSongMode].Text = "TR_GAMEMODE_NORMAL";
@@ -296,9 +329,20 @@ namespace Vocaluxe.Screens
private void _ChangeRound(int num)
{
- CPoints points = CGame.GetPoints();
- _Round += num;
- _Round = _Round.Clamp(0, points.NumRounds - 1);
+ if (_FromScreenSong)
+ {
+ if (_Round == (int)EGameMode.TR_GAMEMODE_SHORTSONG)
+ _Round = (int)EGameMode.TR_GAMEMODE_NORMAL;
+ else
+ ++_Round;
+ }
+ else
+ {
+ CPoints points = CGame.GetPoints();
+ _Round += num;
+ _Round = _Round.Clamp(0, points.NumRounds - 1);
+ }
+
_UpdateRound();
}
@@ -307,4 +351,4 @@ namespace Vocaluxe.Screens
CParty.LeavingHighscore();
}
}
-}
\ No newline at end of file
+}
diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs
index b5eb65ed..8e237bdd 100644
--- a/Vocaluxe/Screens/CScreenSing.cs
+++ b/Vocaluxe/Screens/CScreenSing.cs
@@ -1,4 +1,4 @@
-#region license
+#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
@@ -21,6 +21,7 @@ using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
+using System.Timers;
using System.Windows.Forms;
using Vocaluxe.Base;
using Vocaluxe.Base.Fonts;
@@ -30,6 +31,7 @@ using VocaluxeLib.Draw;
using VocaluxeLib.Log;
using VocaluxeLib.Menu;
using VocaluxeLib.Menu.SingNotes;
+using VocaluxeLib.PartyModes;
using VocaluxeLib.Songs;
namespace Vocaluxe.Screens
@@ -39,7 +41,7 @@ namespace Vocaluxe.Screens
// Version number for theme files. Increment it, if you've changed something on the theme files!
protected override int _ScreenVersion
{
- get { return 9; }
+ get { return 10; }
}
private struct STimeRect
@@ -49,6 +51,7 @@ namespace Vocaluxe.Screens
public float EndBeat;
}
+ private const string _TextShortInfoTop = "TextShortInfoTop";
private const string _TextSongName = "TextSongName";
private const string _TextTime = "TextTime";
private const string _TextDuetName1 = "TextDuetName1";
@@ -58,6 +61,7 @@ namespace Vocaluxe.Screens
private string[,,] _TextNames;
private List _TextsPause;
+ private const string _StaticShortInfoTop = "StaticShortInfoTop";
private const string _StaticSongText = "StaticSongText";
private const string _StaticLyrics = "StaticLyrics";
private const string _StaticLyricsDuet = "StaticLyricsDuet";
@@ -112,7 +116,7 @@ namespace Vocaluxe.Screens
private float _Length = -1f;
private CVideoStream _CurrentVideo;
- private EAspect _VideoAspect = EAspect.Crop;
+ private EAspect _VideoAspect = EAspect.Automatic;
private CTextureRef _CurrentWebcamFrameTexture;
private CTextureRef _Background;
@@ -123,6 +127,7 @@ namespace Vocaluxe.Screens
private float _RemainingTimeToFirstNote;
private float _TimeToFirstNoteDuet;
private float _RemainingTimeToFirstNoteDuet;
+ private float _TimeShowSongTextTotal;
private Stopwatch _TimerSongText;
private Stopwatch _TimerDuetText1;
@@ -132,6 +137,9 @@ namespace Vocaluxe.Screens
private bool _Webcam;
private CBackground _SlideShow;
+ private SScreenSongOptions _Sso;
+
+ private System.Timers.Timer _TimerShortInfoText;
public override EMusicType CurrentMusicType
{
@@ -142,12 +150,13 @@ namespace Vocaluxe.Screens
{
base.Init();
- var texts = new List { _TextSongName, _TextTime, _TextDuetName1, _TextDuetName2, _TextMedleyCountdown };
+ var texts = new List { _TextShortInfoTop, _TextSongName, _TextTime, _TextDuetName1, _TextDuetName2, _TextMedleyCountdown };
_BuildTextStrings(texts);
_ThemeTexts = texts.ToArray();
var statics = new List
{
+ _StaticShortInfoTop,
_StaticSongText,
_StaticLyrics,
_StaticLyricsDuet,
@@ -181,6 +190,25 @@ namespace Vocaluxe.Screens
_TimerSongText = new Stopwatch();
_TimerDuetText1 = new Stopwatch();
_TimerDuetText2 = new Stopwatch();
+
+ _TimerShortInfoText = new System.Timers.Timer(5000);
+ _TimerShortInfoText.AutoReset = false;
+ _TimerShortInfoText.Elapsed += OnTimedEventShortInfoText;
+ }
+
+ private void OnTimedEventShortInfoText(Object source, ElapsedEventArgs e)
+ {
+ _Statics[_StaticShortInfoTop].Visible = false;
+ _Texts[_TextShortInfoTop].Visible = false;
+ }
+
+ private void _ShowInfoText(String text)
+ {
+ _Texts[_TextShortInfoTop].Text = text;
+ _Statics[_StaticShortInfoTop].Visible = true;
+ _Texts[_TextShortInfoTop].Visible = true;
+ _TimerShortInfoText.Stop();
+ _TimerShortInfoText.Enabled = true;
}
public override void LoadTheme(string xmlPath)
@@ -245,6 +273,8 @@ namespace Vocaluxe.Screens
if (keyEvent.ModCtrl)
_NextSong();
}
+ else
+ _ShowInfoText(CBase.Language.Translate("TR_SCREENSING_NOMORESONGS"));
break;
case Keys.W:
if (CWebcam.IsDeviceAvailable())
@@ -255,6 +285,8 @@ namespace Vocaluxe.Screens
else
CWebcam.Stop();
}
+ else
+ _ShowInfoText(CBase.Language.Translate("TR_SCREENSING_NOWEBCAM"));
break;
case Keys.Enter:
if (_Pause)
@@ -264,9 +296,15 @@ namespace Vocaluxe.Screens
if (_Buttons[_ButtonCancel].Selected)
_Stop();
if (_Buttons[_ButtonRestartGame].Selected)
+ {
_RestartGame();
+ _SetPause(false);
+ }
if (_Buttons[_ButtonRestartRound].Selected)
+ {
_RestartRound();
+ _SetPause(false);
+ }
if (_Buttons[_ButtonSkip].Selected)
{
_NextSong();
@@ -284,9 +322,45 @@ namespace Vocaluxe.Screens
CSong song = CGame.GetSong();
song.VideoAspect = _VideoAspect;
+ _ShowInfoText(CBase.Language.Translate("TR_SCREENSING_ASPECTRATIO").Replace("%a", _VideoAspect.ToString()));
+
if (CConfig.Config.Debug.SaveModifiedSongs == EOffOn.TR_CONFIG_ON)
song.Save();
break;
+
+ // Restart Round and reload song file header
+ case Keys.R:
+ if (keyEvent.Mod == EModifier.Ctrl && _Pause)
+ {
+ _SetPause(false);
+ _RestartRound();
+ }
+ break;
+
+ // Restart Round and reload song file header
+ case Keys.F5:
+ if (_Pause)
+ {
+ _SetPause(false);
+ _RestartRound();
+ }
+ break;
+
+ // Skip 10/30 seconds
+ case Keys.Right:
+ if ((keyEvent.Mod == EModifier.Shift || keyEvent.Mod == EModifier.Ctrl) && !_Pause && !_Sso.Selection.PartyMode)
+ {
+ if (_TimerSongText.IsRunning)
+ _TimerSongText.Stop();
+
+ float newTime = _CurrentTime + (keyEvent.Mod == EModifier.Shift ? 10f : 30f);
+ if (CSound.GetLength(_CurrentStream) < newTime)
+ newTime = CSound.GetLength(_CurrentStream) - 1f;
+ CSound.SetPosition(_CurrentStream, newTime);
+
+ _ShowInfoText(CBase.Language.Translate("TR_SCREENSING_SKIPPEDSECONDS").Replace("%s", (keyEvent.Mod == EModifier.Shift ? "10" : "30")));
+ }
+ break;
}
}
@@ -356,6 +430,7 @@ namespace Vocaluxe.Screens
_SetPause(false);
_TimeRects.Clear();
+ _Sso = CParty.GetSongSelectionOptions();
_SingNotes[_SingBars].Init(0);
_AssignPlayerElements();
@@ -463,17 +538,11 @@ namespace Vocaluxe.Screens
if (alpha.Length > 2)
{
- _Lyrics[_LyricMainDuet].Alpha = alpha[0];
- _Lyrics[_LyricSubDuet].Alpha = alpha[1];
+ _Lyrics[_LyricMainDuet].Alpha = alpha[2];
+ _Lyrics[_LyricSubDuet].Alpha = alpha[3];
- _Statics[_StaticLyricsDuet].Alpha = alpha[0];
- _Statics[_StaticLyricHelperDuet].Alpha = alpha[0];
-
- _Lyrics[_LyricMain].Alpha = alpha[2];
- _Lyrics[_LyricSub].Alpha = alpha[3];
-
- _Statics[_StaticLyrics].Alpha = alpha[2];
- _Statics[_StaticLyricHelper].Alpha = alpha[2];
+ _Statics[_StaticLyricsDuet].Alpha = alpha[2];
+ _Statics[_StaticLyricHelperDuet].Alpha = alpha[2];
}
}
@@ -532,7 +601,7 @@ namespace Vocaluxe.Screens
_SingNotes[_SingBars].PlayerNotes[j].SetLine(nr);
}
- if (i == 0 && !song.IsDuet || i == 1 && song.IsDuet)
+ if (i == 0)
{
_Lyrics[_LyricMain].SetLine(lines[nr]);
_Lyrics[_LyricMainTop].SetLine(lines[nr]);
@@ -550,7 +619,7 @@ namespace Vocaluxe.Screens
_Lyrics[_LyricSubTop].Clear();
}
}
- if (i == 0 && song.IsDuet)
+ if (i == 1 && song.IsDuet)
{
_Lyrics[_LyricMainDuet].SetLine(lines[nr]);
_TimeToFirstNoteDuet = CGame.GetTimeFromBeats(lines[nr].FirstNoteBeat - lines[nr].StartBeat, song.BPM);
@@ -564,7 +633,7 @@ namespace Vocaluxe.Screens
}
else
{
- if (i == 0 && !song.IsDuet || i == 1 && song.IsDuet)
+ if (i == 0)
{
_Lyrics[_LyricMain].Clear();
_Lyrics[_LyricSub].Clear();
@@ -573,7 +642,7 @@ namespace Vocaluxe.Screens
_TimeToFirstNote = 0f;
}
- if (i == 0 && song.IsDuet)
+ if (i == 1 && song.IsDuet)
{
_Lyrics[_LyricMainDuet].Clear();
_Lyrics[_LyricSubDuet].Clear();
@@ -610,23 +679,23 @@ namespace Vocaluxe.Screens
private void _UpdateSongText()
{
- if (_TimerSongText.IsRunning && !_Lyrics[_LyricMainDuet].Visible && !_Lyrics[_LyricMainTop].Visible)
+ if (_TimerSongText.IsRunning)
{
float t = _TimerSongText.ElapsedMilliseconds / 1000f;
- if (t < 10f)
+ if (t < _TimeShowSongTextTotal)
{
_Statics[_StaticSongText].Visible = true;
_Texts[_TextSongName].Visible = true;
- if (t < 7f)
+ if (t < (_TimeShowSongTextTotal - 3f))
{
_Statics[_StaticSongText].Color.A = 1f;
_Texts[_TextSongName].Color.A = 1f;
}
else
{
- _Statics[_StaticSongText].Color.A = (10f - t) / 3f;
- _Texts[_TextSongName].Color.A = (10f - t) / 3f;
+ _Statics[_StaticSongText].Color.A = (_TimeShowSongTextTotal - t) / 3f;
+ _Texts[_TextSongName].Color.A = (_TimeShowSongTextTotal - t) / 3f;
}
}
else
@@ -665,7 +734,7 @@ namespace Vocaluxe.Screens
timer.Stop();
}
}
- else if (!timer.IsRunning && timer.ElapsedMilliseconds == 0 && _Lyrics[_LyricMainDuet].Alpha > 0 && CGame.GetSong().IsDuet)
+ else if (!timer.IsRunning && timer.ElapsedMilliseconds == 0 && _Lyrics[_LyricMainTop].Alpha > 0 && CGame.GetSong().IsDuet)
timer.Start();
else
textName.Visible = false;
@@ -698,7 +767,7 @@ namespace Vocaluxe.Screens
_TimerDuetText2.Stop();
}
}
- else if (!_TimerDuetText2.IsRunning && _TimerDuetText2.ElapsedMilliseconds == 0 && _Lyrics[_LyricMain].Alpha > 0 && CGame.GetSong().IsDuet)
+ else if (!_TimerDuetText2.IsRunning && _TimerDuetText2.ElapsedMilliseconds == 0 && _Lyrics[_LyricMainDuet].Alpha > 0 && CGame.GetSong().IsDuet)
_TimerDuetText2.Start();
else
_Texts[_TextDuetName2].Visible = false;
@@ -794,18 +863,21 @@ namespace Vocaluxe.Screens
if (_CurrentVideo != null && CConfig.Config.Video.VideosInSongs == EOffOn.TR_CONFIG_ON && !_Webcam)
{
background = _CurrentVideo.Texture;
- aspect = _VideoAspect;
}
else if (_Webcam)
{
background = _CurrentWebcamFrameTexture;
- aspect = _VideoAspect;
}
else
background = _Background;
if (background != null)
{
SRectF bounds = CSettings.RenderRect;
+
+ if (_VideoAspect == EAspect.Automatic)
+ _VideoAspect = ((background.OrigAspect <= 1.5 || background.OrigAspect >= 1.9) ? EAspect.LetterBox : EAspect.Crop);
+ aspect = _VideoAspect;
+
SRectF rect = CHelper.FitInBounds(bounds, background.OrigAspect, aspect);
CDraw.DrawTexture(background, rect, background.Color, bounds);
}
@@ -876,7 +948,7 @@ namespace Vocaluxe.Screens
_Statics[_StaticLyricHelperTop].Color.R,
_Statics[_StaticLyricHelperTop].Color.G,
_Statics[_StaticLyricHelperTop].Color.B,
- _Statics[_StaticLyricHelperTop].Color.A * _Statics[_StaticLyricHelper].Alpha * alpha);
+ _Statics[_StaticLyricHelperTop].Color.A * _Statics[_StaticLyricHelperTop].Alpha * alpha);
float distance = _Lyrics[_LyricMainTop].GetCurrentLyricPosX() - rect.X - rect.W;
CDraw.DrawTexture(_Statics[_StaticLyricHelperTop].Texture,
@@ -965,7 +1037,7 @@ namespace Vocaluxe.Screens
_CloseSong();
CGame.ResetPlayer();
- _LoadCurrentSong();
+ _LoadCurrentSong(false);
_StartSong();
}
@@ -1045,7 +1117,7 @@ namespace Vocaluxe.Screens
///
/// Prepare streams and screen for current song.
///
- private void _LoadCurrentSong()
+ private void _LoadCurrentSong(bool reloadNotes = true)
{
if (CGame.IsFinished())
{
@@ -1061,6 +1133,9 @@ namespace Vocaluxe.Screens
return;
}
+ if (!_Sso.Selection.PartyMode && (CGame.GameMode == EGameMode.TR_GAMEMODE_NORMAL || CGame.GameMode == EGameMode.TR_GAMEMODE_DUET))
+ song.ReloadSong(reloadNotes);
+
string songname = song.Artist + " - " + song.Title;
int rounds = CGame.GetNumSongs();
if (rounds > 1)
@@ -1083,11 +1158,11 @@ namespace Vocaluxe.Screens
voiceAssignments[i] = CGame.Players[i].VoiceNr;
}
+ _VideoAspect = song.VideoAspect;
if (!String.IsNullOrEmpty(song.VideoFileName))
{
_CurrentVideo = CVideo.Load(Path.Combine(song.Folder, song.VideoFileName));
CVideo.Skip(_CurrentVideo, song.Start, song.VideoGap);
- _VideoAspect = song.VideoAspect;
}
CDraw.RemoveTexture(ref _Background);
@@ -1145,7 +1220,25 @@ namespace Vocaluxe.Screens
_TimerDuetText1.Reset();
_TimerDuetText2.Reset();
- if (!song.IsDuet)
+ // Getting the real start of the first line from the first voice, no other voices are on top since #454.
+ // Needed for displaying song name on duet game mode or lyric on top settings (implemented with #455).
+ CVoice voice = song.Notes.GetVoice(0); // As long as only voice 0 is on top (no matter if duet or other modes).
+ CSongLine[] lines = voice.Lines;
+ float realGap = CGame.GetTimeFromBeats(lines[0].FirstNoteBeat, song.BPM) + (song.Gap - song.Start);
+ _TimeShowSongTextTotal = 10f;
+ if (_Lyrics[_LyricMainDuet].Visible || _Lyrics[_LyricMainTop].Visible)
+ {
+ if (realGap < 11f)
+ {
+ _TimeShowSongTextTotal = 0;
+ }
+ else if (realGap < 17f)
+ {
+ _TimeShowSongTextTotal = realGap - 7f;
+ }
+ }
+
+ if (_TimeShowSongTextTotal > 0)
_TimerSongText.Start();
}
@@ -1173,6 +1266,7 @@ namespace Vocaluxe.Screens
_Lyrics[_LyricSubDuet].Clear();
_Lyrics[_LyricMainTop].Clear();
_Lyrics[_LyricSubTop].Clear();
+ _Texts[_TextShortInfoTop].Text = String.Empty;
_Texts[_TextSongName].Text = String.Empty;
_Texts[_TextDuetName1].Text = String.Empty;
_Texts[_TextDuetName2].Text = String.Empty;
@@ -1196,8 +1290,8 @@ namespace Vocaluxe.Screens
if (CGame.GetSong() != null && CGame.GetSong().IsDuet)
{
- bottomLyricsVisible = true;
- topLyricsVisible = false;
+ bottomLyricsVisible = false;
+ topLyricsVisible = true;
duetLyricsVisible = true;
}
@@ -1223,7 +1317,9 @@ namespace Vocaluxe.Screens
_Lyrics[_LyricMainDuet].Visible = false;
_Lyrics[_LyricSubDuet].Visible = false;
+ _Statics[_StaticShortInfoTop].Visible = false;
_Statics[_StaticSongText].Visible = false;
+ _Texts[_TextShortInfoTop].Visible = false;
_Texts[_TextSongName].Visible = false;
_Texts[_TextDuetName1].Visible = false;
_Texts[_TextDuetName2].Visible = false;
@@ -1399,7 +1495,7 @@ namespace Vocaluxe.Screens
}
// sub
- if (currentLineSub < lines.Length - 2)
+ if ((currentLineSub + 1) < lines.Length)
{
float diff = CGame.GetTimeFromBeats(lines[currentLineSub + 1].FirstNoteBeat, song.BPM) - currentTime;
@@ -1828,4 +1924,4 @@ namespace Vocaluxe.Screens
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Vocaluxe/Screens/CScreenSong.cs b/Vocaluxe/Screens/CScreenSong.cs
index 60031c4d..49f09f16 100644
--- a/Vocaluxe/Screens/CScreenSong.cs
+++ b/Vocaluxe/Screens/CScreenSong.cs
@@ -1,4 +1,4 @@
-#region license
+#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
@@ -19,6 +19,7 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
+using System.Timers;
using System.Windows.Forms;
using Vocaluxe.Base;
using VocaluxeLib;
@@ -42,14 +43,18 @@ namespace Vocaluxe.Screens
// Version number for theme files. Increment it, if you've changed something on the theme files!
protected override int _ScreenVersion
{
- get { return 6; }
+ get { return 10; }
}
private const string _TextCategory = "TextCategory";
private const string _TextSelection = "TextSelection";
private const string _TextSearchBarTitle = "TextSearchBarTitle";
private const string _TextSearchBar = "TextSearchBar";
+ private const string _TextHelpBar = "TextHelpBar";
+ private const string _TextHelpBarSearch = "TextHelpBarSearch";
+ private const string _TextHelpBarParty = "TextHelpBarParty";
private const string _TextOptionsTitle = "TextOptionsTitle";
+ private const string _TextShortInfoTop = "TextShortInfoTop";
private const string _ButtonOpenOptions = "ButtonOpenOptions";
private const string _ButtonOptionsSing = "ButtonOptionsSing";
@@ -63,6 +68,7 @@ namespace Vocaluxe.Screens
private const string _ButtonOptionsRandomMedley = "ButtonOptionsRandomMedley";
private const string _ButtonOptionsStartMedley = "ButtonOptionsStartMedley";
private const string _ButtonStart = "ButtonStart";
+ private const string _ButtonOptionsHighscore = "ButtonOptionsHighscore";
private const string _SelectSlideOptionsMode = "SelectSlideOptionsMode";
private const string _SelectSlideOptionsPlaylistAdd = "SelectSlideOptionsPlaylistAdd";
@@ -71,12 +77,16 @@ namespace Vocaluxe.Screens
private const string _StaticSearchBar = "StaticSearchBar";
private const string _StaticOptionsBG = "StaticOptionsBG";
+ private const string _StaticShortInfoTop = "StaticShortInfoTop";
private const string _SongMenuName = "SongMenu";
private const string _PlaylistName = "Playlist";
private string _SearchText = String.Empty;
private bool _SearchActive;
+ private int _JumpTo_lastCharTime = 0;
+ private String _JumpTo_lastSearchString = "";
+
private readonly List _ButtonsJoker = new List();
private readonly List _TextsPlayer = new List();
private ESongOptionsView _CurSongOptionsView;
@@ -93,6 +103,20 @@ namespace Vocaluxe.Screens
private ISongMenu _SongMenu;
private CPlaylist _Playlist;
+ private System.Timers.Timer _TimerShortInfoText;
+
+ private static int _StaticSelectedSongID;
+
+ private static void setStaticSelectedSongID(int songID)
+ {
+ _StaticSelectedSongID = songID;
+ }
+
+ public static int getSelectedSongID()
+ {
+ return _StaticSelectedSongID;
+ }
+
public override EMusicType CurrentMusicType
{
get { return CSongs.IsInCategory ? EMusicType.Preview : EMusicType.Background; }
@@ -124,6 +148,7 @@ namespace Vocaluxe.Screens
blist.Add(_ButtonStart);
blist.Add(_ButtonOptionsRandomMedley);
blist.Add(_ButtonOptionsStartMedley);
+ blist.Add(_ButtonOptionsHighscore);
_TextsPlayer.Clear();
for (int i = 0; i < CSettings.MaxNumPlayer; i++)
@@ -134,9 +159,13 @@ namespace Vocaluxe.Screens
tlist.Add(_TextSelection);
tlist.Add(_TextSearchBarTitle);
tlist.Add(_TextSearchBar);
+ tlist.Add(_TextHelpBar);
+ tlist.Add(_TextHelpBarSearch);
+ tlist.Add(_TextHelpBarParty);
tlist.Add(_TextOptionsTitle);
+ tlist.Add(_TextShortInfoTop);
- _ThemeStatics = new string[] {_StaticSearchBar, _StaticOptionsBG};
+ _ThemeStatics = new string[] {_StaticSearchBar, _StaticOptionsBG, _StaticShortInfoTop};
_ThemeTexts = tlist.ToArray();
_ThemeButtons = blist.ToArray();
_ThemeSelectSlides = new string[] {_SelectSlideOptionsMode, _SelectSlideOptionsPlaylistAdd, _SelectSlideOptionsPlaylistOpen, _SelectSlideOptionsNumMedleySongs};
@@ -144,6 +173,10 @@ namespace Vocaluxe.Screens
_ThemePlaylists = new string[] {_PlaylistName};
_DragAndDropCover = GetNewStatic();
+
+ _TimerShortInfoText = new System.Timers.Timer(5000);
+ _TimerShortInfoText.AutoReset = false;
+ _TimerShortInfoText.Elapsed += OnTimedEventShortInfoText;
}
protected override void _OnSongMenuChanged()
@@ -184,6 +217,11 @@ namespace Vocaluxe.Screens
keyEvent.Handled = true;
return true;
}
+ if (keyEvent.Key == Keys.Enter && _Playlist.isButtonPlaylistListSelected())
+ {
+ _TogglePlaylistFilter();
+ return true;
+ }
}
// Playlist selection is handled below not in base!
@@ -279,13 +317,71 @@ namespace Vocaluxe.Screens
else if (!_Sso.Selection.PartyMode)
_SearchActive = true;
break;
+
+ case Keys.V:
+ if (keyEvent.Mod == EModifier.Ctrl && !_Sso.Selection.PartyMode)
+ _StartRandomVisibleSongs();
+ break;
+
+ case Keys.R:
+ if (keyEvent.Mod == EModifier.Ctrl && !_Sso.Selection.RandomOnly)
+ _SelectNextRandom(-1);
+ break;
+
+ case Keys.S:
+ if (keyEvent.Mod == EModifier.Ctrl && CSongs.NumSongsVisible > 0 && !_Sso.Selection.PartyMode)
+ _StartMedleySong(_SongMenu.GetPreviewSongNr());
+ break;
+
+ case Keys.T:
+ if (keyEvent.Mod == EModifier.Ctrl && !_Sso.Selection.PartyMode)
+ {
+ _ToggleTabs();
+ }
+ break;
+
+ case Keys.D0:
+ case Keys.D1:
+ case Keys.D2:
+ case Keys.D3:
+ case Keys.D4:
+ case Keys.D5:
+ case Keys.D6:
+ case Keys.D7:
+ case Keys.D8:
+ case Keys.D9:
+ if (keyEvent.Mod == EModifier.Ctrl && !_Sso.Selection.PartyMode)
+ {
+ int tempSortNr = -1;
+ int.TryParse(keyEvent.Key.ToString().Substring(1), out tempSortNr);
+
+ if (tempSortNr == 0)
+ tempSortNr = 10;
+
+ _ToggleSort(tempSortNr);
+ }
+ break;
+
+ case Keys.H:
+ if (keyEvent.Mod == EModifier.Ctrl && CSongs.NumSongsVisible > 0 && !_Sso.Selection.PartyMode)
+ {
+ _ShowHighscore();
+ }
+ break;
+
+ case Keys.L:
+ if (keyEvent.Mod == EModifier.Ctrl)
+ {
+ _TogglePlaylistFilter();
+ }
+ break;
}
if (!_SearchActive)
{
switch (keyEvent.Key)
{
case Keys.Space:
- if (!_Sso.Selection.PartyMode)
+ if (!_Sso.Selection.PartyMode && !_Playlist.isPlaylistNameEditMode())
_ToggleSongOptions(ESongOptionsView.General);
break;
@@ -293,23 +389,9 @@ namespace Vocaluxe.Screens
if (keyEvent.Mod == EModifier.Ctrl && !_Sso.Selection.PartyMode)
_StartRandomAllSongs();
break;
- case Keys.V:
- if (keyEvent.Mod == EModifier.Ctrl && !_Sso.Selection.PartyMode)
- _StartRandomVisibleSongs();
- break;
-
- case Keys.R:
- if (keyEvent.Mod == EModifier.Ctrl && !_Sso.Selection.RandomOnly)
- _SelectNextRandom(-1);
- break;
-
- case Keys.S:
- if (keyEvent.Mod == EModifier.Ctrl && CSongs.NumSongsVisible > 0 && !_Sso.Selection.PartyMode)
- _StartMedleySong(_SongMenu.GetPreviewSongNr());
- break;
case Keys.F:
- if (keyEvent.Mod == EModifier.Ctrl)
+ if (keyEvent.Mod == EModifier.Ctrl && !_Sso.Selection.PartyMode)
_SearchActive = true;
break;
@@ -390,6 +472,10 @@ namespace Vocaluxe.Screens
_ToggleSongOptions(ESongOptionsView.None);
_StartRandomMedley(_SelectSlides[_SelectSlideOptionsNumMedleySongs].Selection + 1, !CSongs.IsInCategory);
}
+ else if (_Buttons[_ButtonOptionsHighscore].Selected)
+ {
+ _ShowHighscore();
+ }
break;
case Keys.Escape:
@@ -425,6 +511,11 @@ namespace Vocaluxe.Screens
_SongMenu.SmallView = false;
return true;
}
+ if (mouseEvent.LB && _Playlist.isButtonPlaylistListSelected())
+ {
+ _TogglePlaylistFilter();
+ return true;
+ }
}
else if (CHelper.IsInBounds(_SongMenu.Rect, mouseEvent))
{
@@ -565,6 +656,10 @@ namespace Vocaluxe.Screens
_StartRandomMedley(_SelectSlides[_SelectSlideOptionsNumMedleySongs].Selection + 1, !CSongs.IsInCategory);
return true;
}
+ else if (_Buttons[_ButtonOptionsHighscore].Selected)
+ {
+ _ShowHighscore();
+ }
else if (_Sso.Selection.RandomOnly && _Sso.Selection.NumJokers != null)
{
if (_Buttons[_ButtonStart].Selected)
@@ -679,6 +774,9 @@ namespace Vocaluxe.Screens
_DragAndDropCover.Visible = false;
_Playlist.DragAndDropSongID = -1;
+ _Statics[_StaticShortInfoTop].Visible = false;
+ _Texts[_TextShortInfoTop].Visible = false;
+
UpdateGame();
}
@@ -727,12 +825,18 @@ namespace Vocaluxe.Screens
_Texts[_TextSearchBar].Visible = true;
_Texts[_TextSearchBarTitle].Visible = true;
+ _Texts[_TextHelpBar].Visible = false;
+ _Texts[_TextHelpBarSearch].Visible = true;
+ _Texts[_TextHelpBarParty].Visible = false;
_Statics[_StaticSearchBar].Visible = true;
}
else
{
_Texts[_TextSearchBar].Visible = false;
_Texts[_TextSearchBarTitle].Visible = false;
+ _Texts[_TextHelpBar].Visible = !_Sso.Selection.PartyMode;
+ _Texts[_TextHelpBarSearch].Visible = false;
+ _Texts[_TextHelpBarParty].Visible = _Sso.Selection.PartyMode;
_Statics[_StaticSearchBar].Visible = false;
}
@@ -782,9 +886,6 @@ namespace Vocaluxe.Screens
CParty.OnSongChange(_SelectedSongID, ref _Sso);
}
- _Sso = CParty.GetSongSelectionOptions();
-
-
if (_Sso.Selection.PartyMode)
{
CSongs.Sort(_Sso.Sorting.SongSorting, _Sso.Sorting.Tabs, _Sso.Sorting.IgnoreArticles, _Sso.Sorting.SearchString, _Sso.Sorting.DuetOptions, _Sso.Sorting.FilterPlaylistID);
@@ -848,6 +949,60 @@ namespace Vocaluxe.Screens
}
}
+ private void _ToggleSort(int sortNr)
+ {
+ if (CBase.Songs.IsInCategory() && _Sso.Selection.CategoryChangeAllowed)
+ {
+ CBase.Songs.SetCategory(-1);
+ }
+
+ CSongs.Sorter.SongSorting = (ESongSorting)sortNr;
+ CConfig.Config.Game.SongSorting = CSongs.Sorter.SongSorting;
+ _Sso.Sorting.SongSorting = CSongs.Sorter.SongSorting;
+
+ _SongMenu.Update(_Sso);
+ _SongMenu.OnShow();
+
+ _ShowInfoText(CBase.Language.Translate("TR_SCREENSONG_SORTING").Replace("%s", CBase.Language.Translate(_Sso.Sorting.SongSorting.ToString())));
+ }
+
+ private void _ShowInfoText(String text)
+ {
+ _Texts[_TextShortInfoTop].Text = text;
+ _Statics[_StaticShortInfoTop].Visible = true;
+ _Texts[_TextShortInfoTop].Visible = true;
+ _TimerShortInfoText.Stop();
+ _TimerShortInfoText.Enabled = true;
+ }
+
+ private void OnTimedEventShortInfoText(Object source, ElapsedEventArgs e)
+ {
+ _Statics[_StaticShortInfoTop].Visible = false;
+ _Texts[_TextShortInfoTop].Visible = false;
+ }
+
+ private void _ToggleTabs()
+ {
+ EOffOn tmpStatus = CSongs.Categorizer.Tabs;
+
+ if (tmpStatus == EOffOn.TR_CONFIG_ON)
+ CSongs.Categorizer.Tabs = EOffOn.TR_CONFIG_OFF;
+ else
+ CSongs.Categorizer.Tabs = EOffOn.TR_CONFIG_ON;
+
+ CConfig.Config.Game.Tabs = CSongs.Categorizer.Tabs;
+ _Sso.Sorting.Tabs = CSongs.Categorizer.Tabs;
+ _SongMenu.Update(_Sso);
+ _SongMenu.OnShow();
+ }
+
+ private void _ShowHighscore()
+ {
+ CGame.ClearSongs();
+ CScreenSong.setStaticSelectedSongID(CSongs.VisibleSongs[_SongMenu.GetPreviewSongNr()].ID);
+ CBase.Graphics.FadeTo(EScreen.Highscore);
+ }
+
private void _StartSong(int songNr)
{
if (CSongs.IsInCategory && (songNr >= 0))
@@ -885,7 +1040,10 @@ namespace Vocaluxe.Screens
if (CSongs.IsInCategory && (songNr >= 0))
{
if (!CSongs.VisibleSongs[songNr].IsGameModeAvailable(EGameMode.TR_GAMEMODE_MEDLEY))
+ {
+ _ShowInfoText(CBase.Language.Translate("TR_SCREENSONG_NOMEDLEY"));
return;
+ }
CGame.Reset();
CGame.ClearSongs();
@@ -1042,8 +1200,14 @@ namespace Vocaluxe.Screens
private void _JumpTo(char letter)
{
+ // Stefan1200: Add all letters from a key press within one second to a search string. Clear search string, if last key press is older than one second.
+ String searchString;
+ if (Environment.TickCount - _JumpTo_lastCharTime < 1000)
+ searchString = _JumpTo_lastSearchString + letter.ToString();
+ else
+ searchString = letter.ToString();
+
int start = 0;
- int curSelected = CSongs.IsInCategory ? _SongMenu.GetSelectedSongNr() : _SongMenu.GetSelectedCategory();
bool firstLevel = CConfig.Config.Game.Tabs == EOffOn.TR_CONFIG_OFF && CSongs.IsInCategory;
bool secondSort = CConfig.Config.Game.Tabs == EOffOn.TR_CONFIG_ON &&
(CConfig.Config.Game.SongSorting == ESongSorting.TR_CONFIG_ARTIST ||
@@ -1055,34 +1219,25 @@ namespace Vocaluxe.Screens
//TODO: What's to do with multiple tags?
//Flamefire: What? We only sorted by one tag, sorting by multiple tags (e.g. Album) will be by e.g. the first entry. That can be used here too as otherwhise it will confuse users because it jumps randomly
ReadOnlyCollection songs = CSongs.VisibleSongs;
- int ct = songs.Count;
int visibleID = -1;
switch (CConfig.Config.Game.SongSorting)
{
case ESongSorting.TR_CONFIG_ARTIST:
case ESongSorting.TR_CONFIG_ARTIST_LETTER:
- if (curSelected >= 0 && curSelected < ct - 1 && songs[curSelected].Artist.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase))
- start = curSelected + 1;
- visibleID = _FindIndex(songs, start, element => element.Artist.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase));
+ visibleID = _FindIndex(songs, start, element => (_Sso.Sorting.IgnoreArticles == EOffOn.TR_CONFIG_ON ? element.ArtistSorting.StartsWith(searchString, StringComparison.OrdinalIgnoreCase) : element.Artist.StartsWith(searchString, StringComparison.OrdinalIgnoreCase)));
break;
case ESongSorting.TR_CONFIG_YEAR:
case ESongSorting.TR_CONFIG_DECADE:
- if (curSelected >= 0 && curSelected < ct - 1 && songs[curSelected].Year.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase))
- start = curSelected + 1;
- visibleID = _FindIndex(songs, start, element => element.Year.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase));
+ visibleID = _FindIndex(songs, start, element => element.Year.StartsWith(searchString, StringComparison.OrdinalIgnoreCase));
break;
case ESongSorting.TR_CONFIG_TITLE_LETTER:
- if (curSelected >= 0 && curSelected < ct - 1 && songs[curSelected].Title.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase))
- start = curSelected + 1;
- visibleID = _FindIndex(songs, start, element => element.Title.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase));
+ visibleID = _FindIndex(songs, start, element => (_Sso.Sorting.IgnoreArticles == EOffOn.TR_CONFIG_ON ? element.TitleSorting.StartsWith(searchString, StringComparison.OrdinalIgnoreCase) : element.Title.StartsWith(searchString, StringComparison.OrdinalIgnoreCase)));
break;
case ESongSorting.TR_CONFIG_FOLDER:
- if (curSelected >= 0 && curSelected < ct - 1 && songs[curSelected].Folder.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase))
- start = curSelected + 1;
- visibleID = _FindIndex(songs, start, element => element.Folder.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase));
+ visibleID = _FindIndex(songs, start, element => element.FolderName.StartsWith(searchString, StringComparison.OrdinalIgnoreCase));
break;
}
if (visibleID > -1)
@@ -1091,22 +1246,17 @@ namespace Vocaluxe.Screens
else if (secondSort && CSongs.IsInCategory)
{
ReadOnlyCollection songs = CSongs.VisibleSongs;
- int ct = songs.Count;
int visibleID = -1;
switch (CConfig.Config.Game.SongSorting)
{
case ESongSorting.TR_CONFIG_FOLDER:
case ESongSorting.TR_CONFIG_TITLE_LETTER:
- if (curSelected >= 0 && curSelected < ct - 1 && songs[curSelected].Artist.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase))
- start = curSelected + 1;
- visibleID = _FindIndex(songs, start, element => element.Artist.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase));
+ visibleID = _FindIndex(songs, start, element => (_Sso.Sorting.IgnoreArticles == EOffOn.TR_CONFIG_ON ? element.ArtistSorting.StartsWith(searchString, StringComparison.OrdinalIgnoreCase) : element.Artist.StartsWith(searchString, StringComparison.OrdinalIgnoreCase)));
break;
case ESongSorting.TR_CONFIG_ARTIST:
case ESongSorting.TR_CONFIG_ARTIST_LETTER:
- if (curSelected >= 0 && curSelected < ct - 1 && songs[curSelected].Title.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase))
- start = curSelected + 1;
- visibleID = _FindIndex(songs, start, element => element.Title.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase));
+ visibleID = _FindIndex(songs, start, element => (_Sso.Sorting.IgnoreArticles == EOffOn.TR_CONFIG_ON ? element.TitleSorting.StartsWith(searchString, StringComparison.OrdinalIgnoreCase) : element.Title.StartsWith(searchString, StringComparison.OrdinalIgnoreCase)));
break;
}
if (visibleID > -1)
@@ -1115,13 +1265,30 @@ namespace Vocaluxe.Screens
else if (!CSongs.IsInCategory)
{
ReadOnlyCollection categories = CSongs.Categories;
- int ct = categories.Count;
- if (curSelected >= 0 && curSelected < ct - 1 && categories[curSelected].Name.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase))
- start = curSelected + 1;
- int visibleID = _FindIndex(categories, start, element => element.Name.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase));
+ int visibleID = _FindIndex(categories, start, element => element.Name.StartsWith(searchString, StringComparison.OrdinalIgnoreCase));
if (visibleID > -1)
_SongMenu.SetSelectedCategory(visibleID);
}
+
+ // Stefan1200: Remember search string and current TickCount in class variables.
+ _JumpTo_lastCharTime = Environment.TickCount;
+ _JumpTo_lastSearchString = searchString;
+ }
+
+ public void _TogglePlaylistFilter()
+ {
+ if (_Sso.Sorting.FilterPlaylistID == _Playlist.ActivePlaylistID)
+ {
+ if (_Playlist.ActivePlaylistID == -1)
+ return;
+
+ _Sso.Sorting.FilterPlaylistID = -1;
+ }
+ else
+ _Sso.Sorting.FilterPlaylistID = _Playlist.ActivePlaylistID;
+
+ CSongs.Sort(_Sso.Sorting.SongSorting, _Sso.Sorting.Tabs, _Sso.Sorting.IgnoreArticles, _Sso.Sorting.SearchString, _Sso.Sorting.DuetOptions, _Sso.Sorting.FilterPlaylistID);
+ _SongMenu.OnShow();
}
private void _ApplyNewSearchFilter(string newFilterString)
@@ -1176,6 +1343,7 @@ namespace Vocaluxe.Screens
_Buttons[_ButtonOptionsOpenSelectedItem].Visible = false;
_Buttons[_ButtonOptionsRandomMedley].Visible = false;
_Buttons[_ButtonOptionsStartMedley].Visible = false;
+ _Buttons[_ButtonOptionsHighscore].Visible = false;
_Texts[_TextOptionsTitle].Visible = false;
_Statics[_StaticOptionsBG].Visible = false;
_Buttons[_ButtonOpenOptions].Visible = true;
@@ -1232,6 +1400,7 @@ namespace Vocaluxe.Screens
_SelectSlides[_SelectSlideOptionsPlaylistAdd].Visible = true;
_Buttons[_ButtonOptionsSing].Visible = true;
_Buttons[_ButtonOptionsPlaylist].Visible = true;
+ _Buttons[_ButtonOptionsHighscore].Visible = true;
_SelectElement(_Buttons[_ButtonOptionsSing]);
_SetSelectSlidePlaylistToCurrentPlaylist();
}
@@ -1395,4 +1564,4 @@ namespace Vocaluxe.Screens
}
#endregion Playlist Actions
}
-}
\ No newline at end of file
+}
diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj
index 08514033..6975931b 100644
--- a/Vocaluxe/Vocaluxe.csproj
+++ b/Vocaluxe/Vocaluxe.csproj
@@ -565,10 +565,10 @@
This project references NuGet package(s) that are missing on this computer. Rebuild for automatic package restore. The missing file is {0}.
-
+
-
+
@@ -578,10 +578,10 @@
-
+
-
+
diff --git a/Vocaluxe/packages.config b/Vocaluxe/packages.config
index 0dbfb55c..5f608d07 100644
--- a/Vocaluxe/packages.config
+++ b/Vocaluxe/packages.config
@@ -1,10 +1,10 @@
-
+
-
+
diff --git a/VocaluxeLib/CHelper.cs b/VocaluxeLib/CHelper.cs
index 20efe943..35a6ae5c 100644
--- a/VocaluxeLib/CHelper.cs
+++ b/VocaluxeLib/CHelper.cs
@@ -1,4 +1,4 @@
-#region license
+#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
@@ -101,6 +101,7 @@ namespace VocaluxeLib
switch (aspect)
{
+ case EAspect.Automatic:
case EAspect.Crop:
if (boundsAspectRatio >= aspectRatio)
{
@@ -138,7 +139,7 @@ namespace VocaluxeLib
}
break;
case EAspect.LetterBox:
- if (boundsAspectRatio <= aspectRatio)
+ if (boundsAspectRatio < aspectRatio)
{
scaledWidth = bounds.W;
scaledHeight = bounds.W / aspectRatio;
@@ -149,6 +150,10 @@ namespace VocaluxeLib
scaledWidth = bounds.H * aspectRatio;
}
break;
+ case EAspect.PillarBox:
+ scaledWidth = bounds.W * 0.77f;
+ scaledHeight = bounds.W / aspectRatio;
+ break;
default:
return bounds;
}
@@ -306,4 +311,4 @@ namespace VocaluxeLib
return bmp;
}
}
-}
\ No newline at end of file
+}
diff --git a/VocaluxeLib/Enums.cs b/VocaluxeLib/Enums.cs
index 8ba2a416..02cb86a7 100644
--- a/VocaluxeLib/Enums.cs
+++ b/VocaluxeLib/Enums.cs
@@ -64,8 +64,10 @@ namespace VocaluxeLib
#region Fonts
public enum EAspect
{
+ Automatic,
Crop,
LetterBox,
+ PillarBox,
Stretch,
Zoom1,
Zoom2
@@ -436,4 +438,4 @@ namespace VocaluxeLib
TR_USERROLE_PROFILEEDITOR = 32
// ReSharper restore InconsistentNaming
}
-}
\ No newline at end of file
+}
diff --git a/VocaluxeLib/Extensions.cs b/VocaluxeLib/Extensions.cs
index 5e36958d..ab91177c 100644
--- a/VocaluxeLib/Extensions.cs
+++ b/VocaluxeLib/Extensions.cs
@@ -171,10 +171,10 @@ namespace VocaluxeLib
public static SRectF Scale(this SRectF rect, float scale)
{
return new SRectF(
- rect.X - rect.W * (scale - 1f),
- rect.Y - rect.H * (scale - 1f),
- rect.W + 2 * rect.W * (scale - 1f),
- rect.H + 2 * rect.H * (scale - 1f),
+ rect.X - rect.W * (scale - 1f) * 0.5f,
+ rect.Y - rect.H * (scale - 1f) * 0.5f,
+ rect.W * scale,
+ rect.H * scale,
rect.Z);
}
diff --git a/VocaluxeLib/IBasic.cs b/VocaluxeLib/IBasic.cs
index e182273b..ad09e6a2 100644
--- a/VocaluxeLib/IBasic.cs
+++ b/VocaluxeLib/IBasic.cs
@@ -304,6 +304,7 @@ namespace VocaluxeLib
{
bool Exists(int playlistID);
string GetName(int playlistID);
+ List GetIds();
List GetNames();
void SetName(int playlistID, string name);
@@ -336,4 +337,4 @@ namespace VocaluxeLib
bool IsPlaying();
float GetLength();
}
-}
\ No newline at end of file
+}
diff --git a/VocaluxeLib/Menu/CMenuPartySongSelection.cs b/VocaluxeLib/Menu/CMenuPartySongSelection.cs
index 815d4ded..44e609e9 100644
--- a/VocaluxeLib/Menu/CMenuPartySongSelection.cs
+++ b/VocaluxeLib/Menu/CMenuPartySongSelection.cs
@@ -100,6 +100,8 @@ namespace VocaluxeLib.Menu
protected int NumMinMedleySongs = 3;
protected int NumMaxMedleySongs = 10;
+ private List _PlaylistIDs;
+
public override void Init()
{
base.Init();
@@ -188,6 +190,8 @@ namespace VocaluxeLib.Menu
_SelectSlides[_SelectSlideSorting].AddValue(ss.ToString());
_SelectSlides[_SelectSlidePlaylist].Clear();
+ _SelectSlides[_SelectSlidePlaylist].NumVisible = 1; // Make sure that only one playlist at a time will be displayed (or the names overlap)
+ _PlaylistIDs = CBase.Playlist.GetIds();
List playlists = CBase.Playlist.GetNames();
for (int i = 0; i < playlists.Count; i++)
{
@@ -220,7 +224,12 @@ namespace VocaluxeLib.Menu
_SongMode = _SelectSlides[_SelectSlideSongMode].Selection;
_Source = _SelectSlides[_SelectSlideSource].Selection;
NumMedleySongs = NumMinMedleySongs + _SelectSlides[_SelectSlideNumMedleySongs].Selection;
- Playlist = _SelectSlides[_SelectSlidePlaylist].Selection;
+
+ int playlistSelection = _SelectSlides[_SelectSlidePlaylist].Selection;
+ if (playlistSelection >= 0 && playlistSelection < _PlaylistIDs.Count)
+ Playlist = _PlaylistIDs[playlistSelection];
+ else
+ Playlist = -1;
if (_SelectSlides[_SelectSlideSorting].Selection != _Sorting)
{
diff --git a/VocaluxeLib/Menu/CPlaylist.cs b/VocaluxeLib/Menu/CPlaylist.cs
index 0a523d21..13388a46 100644
--- a/VocaluxeLib/Menu/CPlaylist.cs
+++ b/VocaluxeLib/Menu/CPlaylist.cs
@@ -81,6 +81,7 @@ namespace VocaluxeLib.Menu
public SThemeButton ButtonPlaylistSave;
public SThemeButton ButtonPlaylistDelete;
public SThemeButton ButtonPlaylistSing;
+ public SThemeButton ButtonPlaylistList;
public SThemeSelectSlide SelectSlideGameMode;
}
@@ -163,6 +164,7 @@ namespace VocaluxeLib.Menu
private readonly CButton _ButtonPlaylistSave;
private readonly CButton _ButtonPlaylistDelete;
private readonly CButton _ButtonPlaylistSing;
+ private readonly CButton _ButtonPlaylistList;
private readonly CText _Text1;
private readonly CSelectSlide _SelectSlideGameMode;
private readonly CStatic _StaticPlaylistHeader;
@@ -235,6 +237,7 @@ namespace VocaluxeLib.Menu
_ButtonPlaylistDelete = new CButton(_PartyModeID);
_ButtonPlaylistSave = new CButton(_PartyModeID);
_ButtonPlaylistSing = new CButton(_PartyModeID);
+ _ButtonPlaylistList = new CButton(_PartyModeID);
_SelectSlideGameMode = new CSelectSlide(_PartyModeID);
Visible = false;
@@ -254,6 +257,7 @@ namespace VocaluxeLib.Menu
_ButtonPlaylistDelete = new CButton(_Theme.ButtonPlaylistDelete, _PartyModeID);
_ButtonPlaylistSave = new CButton(_Theme.ButtonPlaylistSave, _PartyModeID);
_ButtonPlaylistSing = new CButton(_Theme.ButtonPlaylistSing, _PartyModeID);
+ _ButtonPlaylistList = new CButton(_Theme.ButtonPlaylistList, _PartyModeID);
_SelectSlideGameMode = new CSelectSlide(_Theme.SelectSlideGameMode, _PartyModeID);
_AddStatic(_StaticPlaylistFooter);
@@ -263,6 +267,7 @@ namespace VocaluxeLib.Menu
_AddButton(_ButtonPlaylistDelete);
_AddButton(_ButtonPlaylistSave);
_AddButton(_ButtonPlaylistSing);
+ _AddButton(_ButtonPlaylistList);
Visible = false;
Selected = false;
@@ -279,6 +284,7 @@ namespace VocaluxeLib.Menu
_Theme.ButtonPlaylistClose = (SThemeButton)_ButtonPlaylistClose.GetTheme();
_Theme.ButtonPlaylistSave = (SThemeButton)_ButtonPlaylistSave.GetTheme();
_Theme.ButtonPlaylistDelete = (SThemeButton)_ButtonPlaylistDelete.GetTheme();
+ _Theme.ButtonPlaylistList = (SThemeButton)_ButtonPlaylistList.GetTheme();
}
public void UpdateGame()
@@ -321,6 +327,7 @@ namespace VocaluxeLib.Menu
_ButtonPlaylistName.UnloadSkin();
_ButtonPlaylistSave.UnloadSkin();
_ButtonPlaylistSing.UnloadSkin();
+ _ButtonPlaylistList.UnloadSkin();
_StaticPlaylistFooter.UnloadSkin();
_StaticPlaylistHeader.UnloadSkin();
@@ -342,6 +349,7 @@ namespace VocaluxeLib.Menu
_ButtonPlaylistName.LoadSkin();
_ButtonPlaylistSave.LoadSkin();
_ButtonPlaylistSing.LoadSkin();
+ _ButtonPlaylistList.LoadSkin();
_StaticPlaylistFooter.LoadSkin();
_StaticPlaylistHeader.LoadSkin();
@@ -492,7 +500,7 @@ namespace VocaluxeLib.Menu
break;
case Keys.Enter:
- _StartPlaylistSong(_CurrentPlaylistElement);
+ _StartPlaylistSong(_CurrentPlaylistElement + _Offset);
break;
case Keys.Add: //move the selected song up
@@ -640,6 +648,8 @@ namespace VocaluxeLib.Menu
_StartPlaylistSongs();
else if (_ButtonPlaylistSave.Selected)
CBase.Playlist.Save(ActivePlaylistID);
+ else if (isButtonPlaylistListSelected())
+ return false; // Currently CScreenSong do this event!
else if (_ButtonPlaylistDelete.Selected)
{
CBase.Playlist.Delete(ActivePlaylistID);
@@ -672,6 +682,11 @@ namespace VocaluxeLib.Menu
return true;
}
+ public bool isButtonPlaylistListSelected()
+ {
+ return _ButtonPlaylistList.Selected;
+ }
+
private void _SetSelectionToLastEntry()
{
if (_PlaylistElementContents.Count == 0)
@@ -781,6 +796,8 @@ namespace VocaluxeLib.Menu
//LB actions
if (mouseEvent.LB)
{
+ if (isButtonPlaylistListSelected())
+ return false; // Currently CScreenSong do this event!
if (_CurrentPlaylistElement != -1)
{
CBase.Playlist.GetSong(ActivePlaylistID, _CurrentPlaylistElement + _Offset).GameMode =
@@ -818,7 +835,7 @@ namespace VocaluxeLib.Menu
//Start selected song with double click
if (mouseEvent.LD && _CurrentPlaylistElement != -1)
- _StartPlaylistSong(_CurrentPlaylistElement);
+ _StartPlaylistSong(_CurrentPlaylistElement + _Offset);
//Change order with holding LB
if (mouseEvent.LBH && _CurrentPlaylistElement != -1 && _PlaylistElementContents.Count > 0 && DragAndDropSongID == -1)
@@ -972,6 +989,11 @@ namespace VocaluxeLib.Menu
return false;
}
+ public bool isPlaylistNameEditMode()
+ {
+ return _EditMode == EEditMode.PlaylistName;
+ }
+
private void _PrepareList()
{
_PlaylistElements.Clear();
@@ -1166,6 +1188,15 @@ namespace VocaluxeLib.Menu
_CompleteRect.W = _ButtonPlaylistDelete.Rect.W + _ButtonPlaylistDelete.Rect.X - _CompleteRect.X;
if (_ButtonPlaylistDelete.Rect.Y + _ButtonPlaylistDelete.Rect.H > _CompleteRect.Y + _CompleteRect.H)
_CompleteRect.H = _ButtonPlaylistDelete.Rect.H + _ButtonPlaylistDelete.Rect.Y - _CompleteRect.Y;
+ //ButtonPlaylistList
+ if (_ButtonPlaylistList.Rect.X < _CompleteRect.X)
+ _CompleteRect.X = _ButtonPlaylistList.Rect.X;
+ if (_ButtonPlaylistList.Rect.Y < _CompleteRect.Y)
+ _CompleteRect.Y = _ButtonPlaylistList.Rect.Y;
+ if (_ButtonPlaylistList.Rect.W + _ButtonPlaylistList.Rect.X > _CompleteRect.W + _CompleteRect.X)
+ _CompleteRect.W = _ButtonPlaylistList.Rect.W + _ButtonPlaylistList.Rect.X - _CompleteRect.X;
+ if (_ButtonPlaylistList.Rect.Y + _ButtonPlaylistList.Rect.H > _CompleteRect.Y + _CompleteRect.H)
+ _CompleteRect.H = _ButtonPlaylistList.Rect.H + _ButtonPlaylistList.Rect.Y - _CompleteRect.Y;
}
#region ThemeEdit
@@ -1197,4 +1228,4 @@ namespace VocaluxeLib.Menu
}
#endregion ThemeEdit
}
-}
\ No newline at end of file
+}
diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs
index 1a173393..e644159c 100644
--- a/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs
+++ b/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs
@@ -63,6 +63,7 @@ namespace VocaluxeLib.Menu.SongMenu
public SThemeText TextArtist;
public SThemeText TextTitle;
public SThemeText TextSongLength;
+ public SThemeText TextSongYear;
public SThemeStatic StaticCoverBig;
public SThemeStatic StaticTextBG;
@@ -111,6 +112,7 @@ namespace VocaluxeLib.Menu.SongMenu
public SThemeText TextArtist;
public SThemeText TextTitle;
public SThemeText TextSongLength;
+ public SThemeText TextSongYear;
public SThemeStatic StaticCoverBig;
public SThemeStatic StaticTextBG;
@@ -220,7 +222,7 @@ namespace VocaluxeLib.Menu.SongMenu
EScreen check = CBase.Graphics.GetNextScreenType();
if (CBase.Graphics.GetNextScreenType() == EScreen.Sing)
_ResetPreview(false);
- else if (CBase.Graphics.GetNextScreenType() != EScreen.Names || CBase.Config.GetBackgroundMusicStatus() == EBackgroundMusicOffOn.TR_CONFIG_OFF)
+ else if ((CBase.Graphics.GetNextScreenType() != EScreen.Names && CBase.Graphics.GetNextScreenType() != EScreen.Highscore) || CBase.Config.GetBackgroundMusicStatus() == EBackgroundMusicOffOn.TR_CONFIG_OFF)
_ResetPreview();
}
diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuList.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuList.cs
index 2c85058a..4d9f1746 100644
--- a/VocaluxeLib/Menu/SongMenu/CSongMenuList.cs
+++ b/VocaluxeLib/Menu/SongMenu/CSongMenuList.cs
@@ -43,6 +43,7 @@ namespace VocaluxeLib.Menu.SongMenu
private readonly CText _Artist;
private readonly CText _Title;
private readonly CText _SongLength;
+ private readonly CText _SongYear;
private float _SpaceW;
private float _SpaceH;
@@ -118,19 +119,21 @@ namespace VocaluxeLib.Menu.SongMenu
_Artist = new CText(_Theme.SongMenuList.TextArtist, _PartyModeID);
_Title = new CText(_Theme.SongMenuList.TextTitle, _PartyModeID);
_SongLength = new CText(_Theme.SongMenuList.TextSongLength, _PartyModeID);
+ _SongYear = new CText(_Theme.SongMenuList.TextSongYear, _PartyModeID);
_CoverBig = new CStatic(_Theme.SongMenuList.StaticCoverBig, _PartyModeID);
_TextBG = new CStatic(_Theme.SongMenuList.StaticTextBG, _PartyModeID);
_DuetIcon = new CStatic(_Theme.SongMenuList.StaticDuetIcon, _PartyModeID);
_VideoIcon = new CStatic(_Theme.SongMenuList.StaticVideoIcon, _PartyModeID);
_MedleyCalcIcon = new CStatic(_Theme.SongMenuList.StaticMedleyCalcIcon, _PartyModeID);
_MedleyTagIcon = new CStatic(_Theme.SongMenuList.StaticMedleyTagIcon, _PartyModeID);
- _SubElements.AddRange(new IMenuElement[] {_Artist, _Title, _SongLength, _DuetIcon, _VideoIcon, _MedleyCalcIcon, _MedleyTagIcon});
+ _SubElements.AddRange(new IMenuElement[] {_Artist, _Title, _SongLength, _SongYear, _DuetIcon, _VideoIcon, _MedleyCalcIcon, _MedleyTagIcon});
}
private void _ReadSubTheme()
{
_Theme.SongMenuList.TextArtist = (SThemeText)_Artist.GetTheme();
_Theme.SongMenuList.TextSongLength = (SThemeText)_SongLength.GetTheme();
+ _Theme.SongMenuList.TextSongYear = (SThemeText)_SongYear.GetTheme();
_Theme.SongMenuList.TextTitle = (SThemeText)_Title.GetTheme();
_Theme.SongMenuList.StaticCoverBig = (SThemeStatic)_CoverBig.GetTheme();
_Theme.SongMenuList.StaticDuetIcon = (SThemeStatic)_DuetIcon.GetTheme();
@@ -173,12 +176,12 @@ namespace VocaluxeLib.Menu.SongMenu
for (int i = 0; i < _ListLength; i++)
{
//Create Cover
- var rect = new SRectF(Rect.X + (_TileW + _SpaceW), Rect.Y + i * (_TileH + _SpaceH), _TileW, _TileH, Rect.Z);
+ var rect = new SRectF(Rect.X, Rect.Y + i * (_TileH + _SpaceH), _TileW, _TileH, Rect.Z);
var tile = new CStatic(_PartyModeID, _CoverBGTexture, _Color, rect);
_Tiles.Add(tile);
//Create text
- var textRect = new SRectF(MaxRect.X + 2 * (_TileW + _SpaceW), Rect.Y + i * (_TileH + _SpaceH), _ListTextWidth, _TileH, Rect.Z);
+ var textRect = new SRectF(MaxRect.X + (_TileW + _SpaceW), Rect.Y + i * (_TileH + _SpaceH), _ListTextWidth, _TileH, Rect.Z);
CText text = new CText(textRect.X, textRect.Y, textRect.Z,
textRect.H, textRect.W, EAlignment.Left, EStyle.Normal,
"Normal", _Artist.Color, "");
@@ -217,6 +220,7 @@ namespace VocaluxeLib.Menu.SongMenu
_Artist.Text = String.Empty;
_Title.Text = String.Empty;
_SongLength.Text = String.Empty;
+ _SongYear.Text = String.Empty;
_DuetIcon.Visible = false;
_VideoIcon.Visible = false;
_MedleyCalcIcon.Visible = false;
@@ -245,6 +249,7 @@ namespace VocaluxeLib.Menu.SongMenu
_CoverBig.Texture = song.CoverTextureBig;
_Artist.Text = song.Artist;
_Title.Text = song.Title;
+ _SongYear.Text = song.Year;
_DuetIcon.Visible = song.IsDuet;
_VideoIcon.Visible = song.VideoFileName != "";
_MedleyCalcIcon.Visible = song.Medley.Source == EDataSource.Calculated;
@@ -344,19 +349,53 @@ namespace VocaluxeLib.Menu.SongMenu
break;
case Keys.PageUp:
- if (catChangePossible)
+ if (catChangePossible && CBase.Songs.IsInCategory() && (keyEvent.Mod == EModifier.Ctrl || keyEvent.Mod == EModifier.Alt))
{
_PrevCategory();
keyEvent.Handled = true;
}
+ else if (moveAllowed)
+ {
+ if ((_SelectionNr - _ListLength) <= 0)
+ _SelectionNr = 0;
+ else
+ _SelectionNr = _SelectionNr - _ListLength;
+ keyEvent.Handled = true;
+ }
break;
case Keys.PageDown:
- if (catChangePossible)
+ if (catChangePossible && CBase.Songs.IsInCategory() && (keyEvent.Mod == EModifier.Ctrl || keyEvent.Mod == EModifier.Alt))
{
_NextCategory();
keyEvent.Handled = true;
}
+ else if (moveAllowed)
+ {
+ int maxCount_PageDown = (CBase.Songs.GetTabs() == EOffOn.TR_CONFIG_ON && !CBase.Songs.IsInCategory() ? CBase.Songs.GetNumCategories() : CBase.Songs.GetNumSongsVisible());
+ if ((_SelectionNr + _ListLength) >= maxCount_PageDown)
+ _SelectionNr = maxCount_PageDown - 1;
+ else
+ _SelectionNr = _SelectionNr + _ListLength;
+ keyEvent.Handled = true;
+ }
+ break;
+
+ case Keys.Home:
+ if (moveAllowed)
+ {
+ _SelectionNr = 0;
+ keyEvent.Handled = true;
+ }
+ break;
+
+ case Keys.End:
+ int maxCount_End = (CBase.Songs.GetTabs() == EOffOn.TR_CONFIG_ON && !CBase.Songs.IsInCategory() ? CBase.Songs.GetNumCategories() : CBase.Songs.GetNumSongsVisible());
+ if (moveAllowed)
+ {
+ _SelectionNr = maxCount_End - 1;
+ keyEvent.Handled = true;
+ }
break;
case Keys.Left:
@@ -511,7 +550,9 @@ namespace VocaluxeLib.Menu.SongMenu
}
_TextBG.Draw();
- CTextureRef vidtex = CBase.BackgroundMusic.IsPlayingPreview() ? CBase.BackgroundMusic.GetVideoTexture() : null;
+ CTextureRef vidtex = null;
+ if (CBase.Config.GetVideoPreview() == EOffOn.TR_CONFIG_ON)
+ vidtex = (CBase.BackgroundMusic.IsPlayingPreview() ? CBase.BackgroundMusic.GetVideoTexture() : null);
if (vidtex != null)
{
@@ -592,13 +633,28 @@ namespace VocaluxeLib.Menu.SongMenu
private void _UpdateList(bool force = false)
{
+ bool isInCategory = CBase.Songs.IsInCategory();
+ int itemCount = isInCategory ? CBase.Songs.GetNumSongsVisible() : CBase.Songs.GetNumCategories();
+ int halfListLength = _ListLength / 2;
int offset;
+
if (_SelectionNr < _Offset && _SelectionNr >= 0)
- offset = _SelectionNr;
+ {
+ if (_SelectionNr - halfListLength >= 0)
+ offset = _SelectionNr - halfListLength;
+ else
+ offset = 0;
+ }
else if (_SelectionNr >= _Offset + _ListLength)
- offset = _SelectionNr - _ListLength + 1;
+ {
+ if (_SelectionNr + halfListLength > itemCount)
+ offset = itemCount - _ListLength;
+ else
+ offset = _SelectionNr - halfListLength;
+ }
else
offset = _Offset;
+
_UpdateList(offset, force);
}
@@ -653,4 +709,4 @@ namespace VocaluxeLib.Menu.SongMenu
base.LoadSkin();
}
}
-}
\ No newline at end of file
+}
diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs
index 18bcad8f..a5000bdf 100644
--- a/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs
+++ b/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs
@@ -42,6 +42,7 @@ namespace VocaluxeLib.Menu.SongMenu
private CText _Artist;
private CText _Title;
private CText _SongLength;
+ private CText _SongYear;
private int _NumW;
private int _NumH;
@@ -113,13 +114,14 @@ namespace VocaluxeLib.Menu.SongMenu
_Artist = new CText(_Theme.SongMenuTileBoard.TextArtist, _PartyModeID);
_Title = new CText(_Theme.SongMenuTileBoard.TextTitle, _PartyModeID);
_SongLength = new CText(_Theme.SongMenuTileBoard.TextSongLength, _PartyModeID);
+ _SongYear = new CText(_Theme.SongMenuTileBoard.TextSongYear, _PartyModeID);
_CoverBig = new CStatic(_Theme.SongMenuTileBoard.StaticCoverBig, _PartyModeID);
_TextBG = new CStatic(_Theme.SongMenuTileBoard.StaticTextBG, _PartyModeID);
_DuetIcon = new CStatic(_Theme.SongMenuTileBoard.StaticDuetIcon, _PartyModeID);
_VideoIcon = new CStatic(_Theme.SongMenuTileBoard.StaticVideoIcon, _PartyModeID);
_MedleyCalcIcon = new CStatic(_Theme.SongMenuTileBoard.StaticMedleyCalcIcon, _PartyModeID);
_MedleyTagIcon = new CStatic(_Theme.SongMenuTileBoard.StaticMedleyTagIcon, _PartyModeID);
- _SubElements.AddRange(new IMenuElement[] {_Artist, _Title, _SongLength, _DuetIcon, _VideoIcon, _MedleyCalcIcon, _MedleyTagIcon});
+ _SubElements.AddRange(new IMenuElement[] {_Artist, _Title, _SongLength, _SongYear, _DuetIcon, _VideoIcon, _MedleyCalcIcon, _MedleyTagIcon});
}
private void _UpdateTileSelection()
@@ -135,6 +137,7 @@ namespace VocaluxeLib.Menu.SongMenu
{
_Theme.SongMenuTileBoard.TextArtist = (SThemeText)_Artist.GetTheme();
_Theme.SongMenuTileBoard.TextSongLength = (SThemeText)_SongLength.GetTheme();
+ _Theme.SongMenuTileBoard.TextSongYear = (SThemeText)_SongYear.GetTheme();
_Theme.SongMenuTileBoard.TextTitle = (SThemeText)_Title.GetTheme();
_Theme.SongMenuTileBoard.StaticCoverBig = (SThemeStatic)_CoverBig.GetTheme();
_Theme.SongMenuTileBoard.StaticDuetIcon = (SThemeStatic)_DuetIcon.GetTheme();
@@ -208,6 +211,7 @@ namespace VocaluxeLib.Menu.SongMenu
_Artist.Text = String.Empty;
_Title.Text = String.Empty;
_SongLength.Text = String.Empty;
+ _SongYear.Text = String.Empty;
_DuetIcon.Visible = false;
_VideoIcon.Visible = false;
_MedleyCalcIcon.Visible = false;
@@ -236,6 +240,7 @@ namespace VocaluxeLib.Menu.SongMenu
_CoverBig.Texture = song.CoverTextureBig;
_Artist.Text = song.Artist;
_Title.Text = song.Title;
+ _SongYear.Text = song.Year;
_DuetIcon.Visible = song.IsDuet;
_VideoIcon.Visible = song.VideoFileName != "";
_MedleyCalcIcon.Visible = song.Medley.Source == EDataSource.Calculated;
@@ -335,19 +340,55 @@ namespace VocaluxeLib.Menu.SongMenu
break;
case Keys.PageUp:
- if (catChangePossible)
+ if (catChangePossible && CBase.Songs.IsInCategory() && (keyEvent.Mod == EModifier.Ctrl || keyEvent.Mod == EModifier.Alt))
{
_PrevCategory();
keyEvent.Handled = true;
}
+ else if (moveAllowed)
+ {
+ int numSongsPerPage = _NumH * _NumW;
+ if ((_SelectionNr - numSongsPerPage) <= 0)
+ _SelectionNr = 0;
+ else
+ _SelectionNr = _SelectionNr - numSongsPerPage;
+ keyEvent.Handled = true;
+ }
break;
case Keys.PageDown:
- if (catChangePossible)
+ if (catChangePossible && CBase.Songs.IsInCategory() && (keyEvent.Mod == EModifier.Ctrl || keyEvent.Mod == EModifier.Alt))
{
_NextCategory();
keyEvent.Handled = true;
}
+ else if (moveAllowed)
+ {
+ int numSongsPerPage = _NumH * _NumW;
+ int maxCount_PageDown = (CBase.Songs.GetTabs() == EOffOn.TR_CONFIG_ON && !CBase.Songs.IsInCategory() ? CBase.Songs.GetNumCategories() : CBase.Songs.GetNumSongsVisible());
+ if ((_SelectionNr + numSongsPerPage) >= maxCount_PageDown)
+ _SelectionNr = maxCount_PageDown - 1;
+ else
+ _SelectionNr = _SelectionNr + numSongsPerPage;
+ keyEvent.Handled = true;
+ }
+ break;
+
+ case Keys.Home:
+ if (moveAllowed)
+ {
+ _SelectionNr = 0;
+ keyEvent.Handled = true;
+ }
+ break;
+
+ case Keys.End:
+ int maxCount_End = (CBase.Songs.GetTabs() == EOffOn.TR_CONFIG_ON && !CBase.Songs.IsInCategory() ? CBase.Songs.GetNumCategories() : CBase.Songs.GetNumSongsVisible());
+ if (moveAllowed)
+ {
+ _SelectionNr = maxCount_End - 1;
+ keyEvent.Handled = true;
+ }
break;
case Keys.Left:
@@ -485,7 +526,9 @@ namespace VocaluxeLib.Menu.SongMenu
_TextBG.Draw();
- CTextureRef vidtex = CBase.BackgroundMusic.IsPlayingPreview() ? CBase.BackgroundMusic.GetVideoTexture() : null;
+ CTextureRef vidtex = null;
+ if (CBase.Config.GetVideoPreview() == EOffOn.TR_CONFIG_ON)
+ vidtex = (CBase.BackgroundMusic.IsPlayingPreview() ? CBase.BackgroundMusic.GetVideoTexture() : null);
if (vidtex != null)
{
@@ -608,4 +651,4 @@ namespace VocaluxeLib.Menu.SongMenu
Init();
}
}
-}
\ No newline at end of file
+}
diff --git a/VocaluxeLib/Songs/CSong.cs b/VocaluxeLib/Songs/CSong.cs
index e6ddaf4d..bc101698 100644
--- a/VocaluxeLib/Songs/CSong.cs
+++ b/VocaluxeLib/Songs/CSong.cs
@@ -101,7 +101,7 @@ namespace VocaluxeLib.Songs
public readonly List BackgroundFileNames = new List();
public string VideoFileName = String.Empty;
- public EAspect VideoAspect = EAspect.Crop;
+ public EAspect VideoAspect = EAspect.Automatic;
public bool NotesLoaded { get; private set; }
@@ -288,6 +288,17 @@ namespace VocaluxeLib.Songs
return loader.ReadNotes();
}
+ public bool ReloadSong(bool reloadNotes)
+ {
+ var loader = new CSongLoader(this);
+ bool retValue = loader.ReadHeader();
+ if (!retValue)
+ return false;
+
+ retValue = loader.ReadNotes(reloadNotes);
+ return retValue;
+ }
+
public bool Save()
{
return Save(Path.Combine(Folder, FileName));
@@ -518,4 +529,4 @@ namespace VocaluxeLib.Songs
ShortEnd.Source = EDataSource.Calculated;
}
}
-}
\ No newline at end of file
+}
diff --git a/VocaluxeLib/Songs/CSongLoader.cs b/VocaluxeLib/Songs/CSongLoader.cs
index 99702bc8..762e9d3c 100644
--- a/VocaluxeLib/Songs/CSongLoader.cs
+++ b/VocaluxeLib/Songs/CSongLoader.cs
@@ -82,12 +82,16 @@ namespace VocaluxeLib.Songs
_Song.Languages.Clear();
_Song.Genres.Clear();
_Song.UnknownTags.Clear();
+ _Song.BackgroundFileNames.Clear();
_Song._Comment = "";
_Song.ManualEncoding = false;
_Song.Medley.Source = EDataSource.None;
_Song._CalculateMedley = true;
_Song.Preview.Source = EDataSource.None;
_Song.ShortEnd.Source = EDataSource.None;
+ _Song.Start = 0;
+ _Song.VideoGap = 0;
+ _Song.Preview.StartTime = 0;
var headerFlags = new EHeaderFlags();
StreamReader sr = null;
@@ -567,6 +571,8 @@ namespace VocaluxeLib.Songs
case ':':
case '*':
case 'F':
+ case 'R': // Read R (RAP) and G (Golden RAP) notes as Freestyle notes currently. Final implementation needed!
+ case 'G': // Read R (RAP) and G (Golden RAP) notes as Freestyle notes currently. Final implementation needed!
string[] noteData = line.Split(splitChars, 4);
if (noteData.Length < 4)
{
@@ -614,7 +620,7 @@ namespace VocaluxeLib.Songs
if (tag.Equals('*'))
noteType = ENoteType.Golden;
- else if (tag.Equals('F'))
+ else if (tag.Equals('F') || tag.Equals('R') || tag.Equals('G')) // Read R (RAP) and G (Golden RAP) notes as Freestyle notes currently. Final implementation needed!
noteType = ENoteType.Freestyle;
else
noteType = ENoteType.Normal;
@@ -761,4 +767,4 @@ namespace VocaluxeLib.Songs
}
}
}
-}
\ No newline at end of file
+}
diff --git a/VocaluxeLib/Utils/Player/CSongPlayer.cs b/VocaluxeLib/Utils/Player/CSongPlayer.cs
index 3ae765f4..7f166ea1 100644
--- a/VocaluxeLib/Utils/Player/CSongPlayer.cs
+++ b/VocaluxeLib/Utils/Player/CSongPlayer.cs
@@ -110,6 +110,7 @@ namespace VocaluxeLib.Utils.Player
if (_Video != null || !SongHasVideo)
return;
+
string videoFilePath = Path.Combine(_Song.Folder, _Song.VideoFileName);
_Video = CBase.Video.Load(videoFilePath);
if (_Video == null)
@@ -175,4 +176,4 @@ namespace VocaluxeLib.Utils.Player
_CloseVideo();
}
}
-}
\ No newline at end of file
+}
diff --git a/appveyor.yml b/appveyor.yml
index 9f00ce33..ae906561 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -136,7 +136,7 @@ deploy:
release: $(APPVEYOR_REPO_TAG_NAME)
description: $(APPVEYOR_REPO_COMMIT)
auth_token:
- secure: JSlN/em0JdspVn8jwaQ4IjugY6OQi0au4Qq0rhctJmcfGMaEGnUAOmDFULI48REW
+ secure: sGetWh2XUYs95VBT+QYNPtDW9Rh2/JBuxNNYXytpn7mMudUMcjSKDGErkCTum+ZE
artifact: ReleaseZip
prerelease: $(IS_BETA_RELEASE)
on:
@@ -148,7 +148,7 @@ deploy:
release: Latest Nightly build
description: $(APPVEYOR_REPO_COMMIT)
auth_token:
- secure: JSlN/em0JdspVn8jwaQ4IjugY6OQi0au4Qq0rhctJmcfGMaEGnUAOmDFULI48REW
+ secure: sGetWh2XUYs95VBT+QYNPtDW9Rh2/JBuxNNYXytpn7mMudUMcjSKDGErkCTum+ZE
artifact: ReleaseZip
prerelease: true
on: