diff --git a/GstreamerHelper/GstreamerAudioStream.cpp b/GstreamerHelper/GstreamerAudioStream.cpp index 7fbf632a..ed8d2c4a 100644 --- a/GstreamerHelper/GstreamerAudioStream.cpp +++ b/GstreamerHelper/GstreamerAudioStream.cpp @@ -69,13 +69,12 @@ int GstreamerAudioStream::Load(const wchar_t* Media) return -1; } Running = true; + gst_element_set_state(Element, GST_STATE_NULL); g_object_set(Element, "uri", Media, NULL); g_object_set(Element, "audio-sink", SinkBin, NULL); g_object_set(Element, "flags", GST_PLAY_FLAG_AUDIO, NULL); gst_element_set_state(Element, GST_STATE_PAUSED); - //gst_bus_timed_pop_filtered(Bus, -1, GST_MESSAGE_ASYNC_DONE); - RefreshDuration(); return ID; } @@ -84,8 +83,15 @@ int GstreamerAudioStream::Load(const wchar_t* Media) int GstreamerAudioStream::Load(const wchar_t* Media, bool Prescan) { Load(Media); - if(Prescan) + if(Prescan){ gst_bus_timed_pop_filtered(Bus, -1, GST_MESSAGE_ASYNC_DONE); + //Workaround: Waiting for the stream to be loaded (Length>0) + for(int i=0;i<40;i++){ + if(GetLength()>0.f) + break; + Sleep(5); + } + } return ID; } @@ -127,10 +133,7 @@ void GstreamerAudioStream::Play(void) { PauseStreamAfterFade = false; Running = true; - GstStateChangeReturn ret; - if(Element) - ret = gst_element_set_state(Element, GST_STATE_PLAYING); - if(ret == GST_STATE_CHANGE_ASYNC) + if(gst_element_set_state(Element, GST_STATE_PLAYING) == GST_STATE_CHANGE_ASYNC) gst_bus_timed_pop_filtered(Bus, -1, GST_MESSAGE_ASYNC_DONE); SetStreamVolume(Volume * 100.0); } @@ -180,7 +183,7 @@ void GstreamerAudioStream::SetStreamVolumeMax(float MaxVolume) float GstreamerAudioStream::GetLength() { - if(Duration <= 0) + if(Duration <= 0.f) RefreshDuration(); return Duration; } @@ -191,7 +194,7 @@ void GstreamerAudioStream::RefreshDuration() { gint64 time = -1000; if(gst_element_query_duration(Element, GST_FORMAT_TIME, &time)) - Duration = (gfloat)((gdouble)(time/GST_SECOND)); + Duration = (gfloat)((gdouble)time/GST_SECOND); } } diff --git a/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs b/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs index 33102ced..d3628d3e 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs @@ -675,7 +675,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe case ESongSource.TR_CATEGORY: CBase.Songs.SetCategory(_GameData.CategoryID); - for (int i = 0; i < CBase.Songs.NumSongsInCategory(_GameData.CategoryID); i++) + for (int i = 0; i < CBase.Songs.GetNumSongsVisible(); i++) { // ReSharper disable LoopCanBeConvertedToQuery foreach (EGameMode mode in CBase.Songs.GetVisibleSong(i).AvailableGameModes) diff --git a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs index a72bc05a..0e1aab3a 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs @@ -20,6 +20,7 @@ using System.Collections.Generic; using System.Linq; using System.Windows.Forms; using VocaluxeLib.Menu; +using VocaluxeLib.Songs; namespace VocaluxeLib.PartyModes.TicTacToe { @@ -59,7 +60,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe _ThemeButtons = new string[] {_ButtonNext, _ButtonBack}; _Data = new SDataFromScreen(); - SFromScreenConfig config = new SFromScreenConfig + var config = new SFromScreenConfig { PlaylistID = 0, NumFields = 9, @@ -76,7 +77,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe { try { - SDataToScreenConfig config = (SDataToScreenConfig)receivedData; + var config = (SDataToScreenConfig)receivedData; _Data.ScreenConfig.NumFields = config.NumFields; _Data.ScreenConfig.NumPlayerTeam1 = config.NumPlayerTeam1; _Data.ScreenConfig.NumPlayerTeam2 = config.NumPlayerTeam2; @@ -207,13 +208,13 @@ namespace VocaluxeLib.PartyModes.TicTacToe _SelectSlides[_SelectSlidePlaylist].Selection = _Data.ScreenConfig.PlaylistID; _SelectSlides[_SelectSlidePlaylist].Visible = _Data.ScreenConfig.SongSource == ESongSource.TR_PLAYLIST; - string[] categories = new string[CBase.Songs.GetNumCategories()]; + var categories = new string[CBase.Songs.GetNumCategories()]; for (int i = 0; i < CBase.Songs.GetNumCategories(); i++) categories[i] = CBase.Songs.GetCategory(i).Name; _SelectSlides[_SelectSlideCategory].Clear(); for (int i = 0; i < categories.Length; i++) { - string value = categories[i] + " (" + CBase.Songs.NumSongsInCategory(i) + " " + CBase.Language.Translate("TR_SONGS", _PartyModeID) + ")"; + string value = categories[i] + " (" + CBase.Songs.GetNumSongsNotSungInCategory(i) + " " + CBase.Language.Translate("TR_SONGS", _PartyModeID) + ")"; _SelectSlides[_SelectSlideCategory].AddValue(value); } _SelectSlides[_SelectSlideCategory].Selection = _Data.ScreenConfig.CategoryID; @@ -240,7 +241,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe _Data.ScreenConfig.CategoryID = _SelectSlides[_SelectSlideCategory].Selection; _Data.ScreenConfig.GameMode = (EPartyGameMode)_SelectSlides[_SelectSlideGameMode].Selection; - EGameMode gm = EGameMode.TR_GAMEMODE_NORMAL; + var gm = EGameMode.TR_GAMEMODE_NORMAL; switch (_Data.ScreenConfig.GameMode) { @@ -280,25 +281,22 @@ namespace VocaluxeLib.PartyModes.TicTacToe } if (_Data.ScreenConfig.SongSource == ESongSource.TR_CATEGORY) { - if (CBase.Songs.GetNumCategories() > 0) - { - if (CBase.Songs.NumSongsInCategory(_Data.ScreenConfig.CategoryID) > 0) - { - CBase.Songs.SetCategory(_Data.ScreenConfig.CategoryID); - _ConfigOk = false; - for (int i = 0; i < CBase.Songs.NumSongsInCategory(_Data.ScreenConfig.CategoryID); i++) - { - _ConfigOk = CBase.Songs.GetVisibleSong(i).AvailableGameModes.Any(mode => mode == gm); - if (_ConfigOk) - break; - } - CBase.Songs.SetCategory(-1); - } - else - _ConfigOk = false; - } - else + if (CBase.Songs.GetNumCategories() == 0) _ConfigOk = false; + else if (CBase.Songs.GetNumSongsNotSungInCategory(_Data.ScreenConfig.CategoryID) <= 0) + _ConfigOk = false; + else + { + CBase.Songs.SetCategory(_Data.ScreenConfig.CategoryID); + _ConfigOk = false; + foreach (CSong song in CBase.Songs.GetVisibleSongs()) + { + _ConfigOk = song.AvailableGameModes.Any(mode => mode == gm); + if (_ConfigOk) + break; + } + CBase.Songs.SetCategory(-1); + } } if (_Data.ScreenConfig.SongSource == ESongSource.TR_ALLSONGS) { diff --git a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs index b50c51ad..6cfad473 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs @@ -504,7 +504,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe CBase.BackgroundMusic.SetStatus(true); _PreviewStream = CBase.Sound.Load(song.GetMP3(), false); - CBase.Sound.SetPosition(_PreviewStream, song.PreviewStart); + CBase.Sound.SetPosition(_PreviewStream, song.Preview.StartTime); CBase.Sound.SetStreamVolume(_PreviewStream, 0f); CBase.Sound.Play(_PreviewStream); CBase.Sound.Fade(_PreviewStream, CBase.Config.GetBackgroundMusicVolume(), 1f); @@ -528,7 +528,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe CBase.BackgroundMusic.SetStatus(true); _PreviewStream = CBase.Sound.Load(song.GetMP3(), false); - CBase.Sound.SetPosition(_PreviewStream, song.PreviewStart); + CBase.Sound.SetPosition(_PreviewStream, song.Preview.StartTime); CBase.Sound.SetStreamVolume(_PreviewStream, 0f); CBase.Sound.Play(_PreviewStream); CBase.Sound.Fade(_PreviewStream, CBase.Config.GetBackgroundMusicVolume(), 1f); diff --git a/Vocaluxe.sln b/Vocaluxe.sln index d894246e..0896a6f6 100644 --- a/Vocaluxe.sln +++ b/Vocaluxe.sln @@ -1,6 +1,6 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Express 2012 for Windows Desktop +# Visual Studio 2012 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Vocaluxe", "Vocaluxe\Vocaluxe.csproj", "{2A1E0F2D-5392-4BB7-B0A1-A9DFA13E79FF}" ProjectSection(ProjectDependencies) = postProject {6F3E1874-F28A-40E9-AFBD-31934D593678} = {6F3E1874-F28A-40E9-AFBD-31934D593678} @@ -154,7 +154,4 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection - GlobalSection(Performance) = preSolution - HasPerformanceSessions = true - EndGlobalSection EndGlobal diff --git a/Vocaluxe/Base/CBackgroundMusic.cs b/Vocaluxe/Base/CBackgroundMusic.cs index 20a1c8ea..4f315e97 100644 --- a/Vocaluxe/Base/CBackgroundMusic.cs +++ b/Vocaluxe/Base/CBackgroundMusic.cs @@ -90,11 +90,6 @@ namespace Vocaluxe.Base get { return _CurrentPlaylistElement.SongID; } } - public static bool Duet - { - get { return _CurrentPlaylistElement.Duet; } - } - public static bool SongHasVideo { get { return File.Exists(_CurrentPlaylistElement.VideoFilePath); } @@ -581,17 +576,6 @@ namespace Vocaluxe.Base } } - public bool Duet - { - get - { - if (_Song != null) - return _Song.IsDuet; - - return false; - } - } - public CPlaylistElement(CSong song) { MusicFilePath = string.Empty; diff --git a/Vocaluxe/Base/CConfig.cs b/Vocaluxe/Base/CConfig.cs index 00d8b55a..9902d6b9 100644 --- a/Vocaluxe/Base/CConfig.cs +++ b/Vocaluxe/Base/CConfig.cs @@ -33,10 +33,19 @@ namespace Vocaluxe.Base { static class CConfig { - private static readonly XmlWriterSettings _Settings = new XmlWriterSettings(); + /// + /// Uniform settings for writing XML files. ALWAYS use this! + /// + public static readonly XmlWriterSettings XMLSettings = new XmlWriterSettings + { + Indent = true, + Encoding = Encoding.UTF8, + ConformanceLevel = ConformanceLevel.Document + }; // Debug public static EDebugLevel DebugLevel = EDebugLevel.TR_CONFIG_OFF; + public static EOffOn SaveModifiedSongs = EOffOn.TR_CONFIG_OFF; // Graphics #if WIN @@ -140,10 +149,6 @@ namespace Vocaluxe.Base public static void Init() { - _Settings.Indent = true; - _Settings.Encoding = Encoding.UTF8; - _Settings.ConformanceLevel = ConformanceLevel.Document; - SongFolder.Add(Path.Combine(Directory.GetCurrentDirectory(), CSettings.FolderSongs)); #if INSTALLER @@ -169,6 +174,7 @@ namespace Vocaluxe.Base return; xmlReader.TryGetEnumValue("//root/Debug/DebugLevel", ref DebugLevel); + xmlReader.TryGetEnumValue("//root/Debug/SaveModifiedSongs", ref SaveModifiedSongs); #region Graphics xmlReader.TryGetEnumValue("//root/Graphics/Renderer", ref Renderer); @@ -302,7 +308,7 @@ namespace Vocaluxe.Base XmlWriter writer = null; try { - writer = XmlWriter.Create(Path.Combine(CSettings.DataPath, CSettings.FileConfig), _Settings); + writer = XmlWriter.Create(Path.Combine(CSettings.DataPath, CSettings.FileConfig), XMLSettings); writer.WriteStartDocument(); writer.WriteStartElement("root"); @@ -328,6 +334,9 @@ namespace Vocaluxe.Base writer.WriteComment("DebugLevel: " + CHelper.ListStrings(Enum.GetNames(typeof(EDebugLevel)))); writer.WriteElementString("DebugLevel", Enum.GetName(typeof(EDebugLevel), DebugLevel)); + writer.WriteComment("SaveModifiedSongs: " + CHelper.ListStrings(Enum.GetNames(typeof(EOffOn)))); + writer.WriteElementString("SaveModifiedSongs", Enum.GetName(typeof(EOffOn), SaveModifiedSongs)); + writer.WriteEndElement(); #endregion Debug diff --git a/Vocaluxe/Base/CGame.cs b/Vocaluxe/Base/CGame.cs index ada61872..38c280f6 100644 --- a/Vocaluxe/Base/CGame.cs +++ b/Vocaluxe/Base/CGame.cs @@ -232,7 +232,7 @@ namespace Vocaluxe.Base for (int beat = _LastEvalBeat + 1; beat <= RecordedBeat; beat++) { if ((_SongQueue.GetCurrentGameMode() == EGameMode.TR_GAMEMODE_MEDLEY && song.Medley.EndBeat == beat) || - (_SongQueue.GetCurrentGameMode() == EGameMode.TR_GAMEMODE_SHORTSONG && song.ShortEnd == beat)) + (_SongQueue.GetCurrentGameMode() == EGameMode.TR_GAMEMODE_SHORTSONG && song.ShortEnd.EndBeat == beat)) Players[p].SongFinished = true; CSongLine[] lines = song.Notes.GetVoice(Players[p].VoiceNr).Lines; @@ -288,7 +288,7 @@ namespace Vocaluxe.Base //CSound.RecordSetTone(p, Tone); double points = (CSettings.MaxScore - CSettings.LinebonusScore) * (double)notes[note].PointsForBeat / song.Notes.GetVoice(Players[p].VoiceNr).Points; - if (notes[note].NoteType == ENoteType.Golden) + if (notes[note].Type == ENoteType.Golden) Players[p].PointsGoldenNotes += points; Players[p].Points += points; @@ -382,7 +382,7 @@ namespace Vocaluxe.Base { if (note.StartBeat < nextStart) { - if (note.Hit && note.HitNote.NoteType == ENoteType.Golden) + if (note.Hit && note.HitNote.Type == ENoteType.Golden) Players[p].PointsGoldenNotes += note.Points; Players[p].Points += note.Points; } @@ -392,7 +392,7 @@ namespace Vocaluxe.Base } while (line.NoteCount > n && n >= 0) { - if (line.Notes[n].Hit && line.Notes[n].HitNote.NoteType == ENoteType.Golden) + if (line.Notes[n].Hit && line.Notes[n].HitNote.Type == ENoteType.Golden) Players[p].PointsGoldenNotes -= line.Notes[n].Points; Players[p].Points -= line.Notes[n].Points; line.DeleteNote(n); diff --git a/Vocaluxe/Base/CLog.cs b/Vocaluxe/Base/CLog.cs index 350950bb..6f87a74c 100644 --- a/Vocaluxe/Base/CLog.cs +++ b/Vocaluxe/Base/CLog.cs @@ -117,8 +117,7 @@ namespace Vocaluxe.Base MessageBox.Show(errorText, CSettings.ProgramName, MessageBoxButtons.OK, MessageBoxIcon.Error); if (e != null) errorText += ": " + e; - _ErrorLog.Add(_NumErrors + ") " + errorText + "\r\n"); - _ErrorLog.Add(String.Empty); + _ErrorLog.Add(_NumErrors + ") " + errorText); if (exit) Environment.Exit(Environment.ExitCode); } diff --git a/Vocaluxe/Base/CMain.cs b/Vocaluxe/Base/CMain.cs index 2d2a9ea9..dbf75632 100644 --- a/Vocaluxe/Base/CMain.cs +++ b/Vocaluxe/Base/CMain.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Drawing; +using System.Xml; using Vocaluxe.Base.Fonts; using VocaluxeLib; using VocaluxeLib.Game; @@ -60,6 +61,11 @@ namespace Vocaluxe.Base class CBconfig : IConfig { + public EOffOn GetSaveModifiedSongs() + { + return CConfig.SaveModifiedSongs; + } + public void SetBackgroundMusicVolume(int newVolume) { CConfig.BackgroundMusicVolume = newVolume; @@ -110,7 +116,7 @@ namespace Vocaluxe.Base return CConfig.CoverSize; } - public IEnumerable GetSongFolder() + public IEnumerable GetSongFolders() { return CConfig.SongFolder; } @@ -139,6 +145,11 @@ namespace Vocaluxe.Base { return CConfig.GetMaxNumMics(); } + + public XmlWriterSettings GetXMLSettings() + { + return CConfig.XMLSettings; + } } class CBsettings : ISettings @@ -527,6 +538,11 @@ namespace Vocaluxe.Base return CGame.GetTimeFromBeats(beat, bpm); } + public float GetBeatFromTime(float time, float bpm, float gap) + { + return CGame.GetBeatFromTime(time, bpm, gap); + } + public void AddSong(int songID, EGameMode gameMode) { CGame.AddSong(songID, gameMode); @@ -596,9 +612,14 @@ namespace Vocaluxe.Base return CSongs.NumCategories; } - public int NumSongsInCategory(int categoryIndex) + public int GetNumSongsInCategory(int categoryIndex) { - return CSongs.NumSongsInCategory(categoryIndex); + return CSongs.GetNumSongsInCategory(categoryIndex); + } + + public int GetNumSongsNotSungInCategory(int categoryIndex) + { + return CSongs.GetNumSongsNotSungInCategory(categoryIndex); } public bool IsInCategory() @@ -653,10 +674,7 @@ namespace Vocaluxe.Base public CCategory GetCategory(int index) { - if (index >= CSongs.NumCategories) - return null; - - return new CCategory(CSongs.Categories[index]); + return CSongs.GetCategoryByIndex(index); } public void AddPartySongSung(int songID) diff --git a/Vocaluxe/Base/CSongSorter.cs b/Vocaluxe/Base/CSongSorter.cs index 9526cedb..eefb796f 100644 --- a/Vocaluxe/Base/CSongSorter.cs +++ b/Vocaluxe/Base/CSongSorter.cs @@ -157,10 +157,10 @@ namespace Vocaluxe.Base switch (_SongSorting) { case ESongSorting.TR_CONFIG_EDITION: - fieldName = "Edition"; + fieldName = "Editions"; break; case ESongSorting.TR_CONFIG_GENRE: - fieldName = "Genre"; + fieldName = "Genres"; break; case ESongSorting.TR_CONFIG_FOLDER: fieldName = "FolderName"; @@ -177,7 +177,7 @@ namespace Vocaluxe.Base fieldName = "Year"; break; case ESongSorting.TR_CONFIG_LANGUAGE: - fieldName = "Language"; + fieldName = "Languages"; break; case ESongSorting.TR_CONFIG_DATEADDED: fieldName = "DateAdded"; diff --git a/Vocaluxe/Base/CSongs.cs b/Vocaluxe/Base/CSongs.cs index aeed4b92..c031209c 100644 --- a/Vocaluxe/Base/CSongs.cs +++ b/Vocaluxe/Base/CSongs.cs @@ -64,7 +64,7 @@ namespace Vocaluxe.Base public static int NumSongsVisible { - get { return _CatIndex < 0 ? 0 : Categories[_CatIndex].Songs.Count(sp => !sp.IsSung); } + get { return VisibleSongs.Count; } } public static int NumCategories @@ -102,9 +102,19 @@ namespace Vocaluxe.Base /// /// Category index /// - public static int NumSongsInCategory(int catIndex) + public static int GetNumSongsInCategory(int catIndex) { - return _IsCatIndexValid(catIndex) ? Categories[catIndex].Songs.Count(sp => !sp.IsSung) : 0; + return _IsCatIndexValid(catIndex) ? Categories[catIndex].Songs.Count : 0; + } + + /// + /// Returns the number of song that are not sung in the category specified with CatIndex + /// + /// Category index + /// Number of visible songs in that category + public static int GetNumSongsNotSungInCategory(int catIndex) + { + return _IsCatIndexValid(catIndex) ? Categories[catIndex].GetNumSongsNotSung() : 0; } public static void NextCategory() @@ -157,9 +167,8 @@ namespace Vocaluxe.Base foreach (CSongPointer song in category.Songs.Where(song => song.SongID == songID)) { song.IsSung = true; - int catIndex = _GetCategoryNumber(category); - if (NumSongsInCategory(catIndex) == 0) - ResetPartySongSung(catIndex); + if (category.GetNumSongsNotSung() == 0) + ResetPartySongSung(_GetCategoryNumber(category)); return; } } @@ -269,6 +278,24 @@ namespace Vocaluxe.Base get { return Categorizer.Categories.AsReadOnly(); } } + /// + /// Gets category with given index or null for invalid index + /// + /// + /// category with given index or null for invalid index + public static CCategory GetCategoryByIndex(int index) + { + if (!_IsCatIndexValid(index)) + return null; + + return Categorizer.Categories[index]; + } + + /// + /// Gets visible song with given index or null for invalid index or song not visible + /// + /// + /// visible song with given index or null for invalid index or song not visible public static CSong GetVisibleSongByIndex(int index) { if (index < 0) @@ -312,7 +339,7 @@ namespace Vocaluxe.Base if (song == null) continue; song.ID = _Songs.Count; - if (song.ReadNotes()) + if (song.LoadNotes()) _Songs.Add(song); } CLog.StopBenchmark(2, "Read TXTs"); diff --git a/Vocaluxe/Base/CTheme.cs b/Vocaluxe/Base/CTheme.cs index ce48eda2..52bbc631 100644 --- a/Vocaluxe/Base/CTheme.cs +++ b/Vocaluxe/Base/CTheme.cs @@ -105,7 +105,6 @@ namespace Vocaluxe.Base private const int _SkinSystemVersion = 3; #region Vars - private static readonly XmlWriterSettings _Settings = new XmlWriterSettings(); private static readonly List _Themes = new List(); public static string[] ThemeNames { @@ -146,10 +145,6 @@ namespace Vocaluxe.Base #region Theme and Skin loading and writing public static void InitTheme() { - _Settings.Indent = true; - _Settings.Encoding = Encoding.UTF8; - _Settings.ConformanceLevel = ConformanceLevel.Document; - _ListThemes(); ListSkins(); @@ -289,7 +284,7 @@ namespace Vocaluxe.Base private static void _SaveTheme(int themeIndex) { #region ThemeMainFile - using (XmlWriter writer = XmlWriter.Create(Path.Combine(_Themes[themeIndex].Path, _Themes[themeIndex].FileName), _Settings)) + using (XmlWriter writer = XmlWriter.Create(Path.Combine(_Themes[themeIndex].Path, _Themes[themeIndex].FileName), CConfig.XMLSettings)) { writer.WriteStartDocument(); writer.WriteStartElement("root"); @@ -331,7 +326,7 @@ namespace Vocaluxe.Base { for (int skinIndex = 0; skinIndex < _Skins.Count; skinIndex++) { - using (XmlWriter writer = XmlWriter.Create(Path.Combine(_Skins[skinIndex].Path, _Skins[skinIndex].FileName), _Settings)) + using (XmlWriter writer = XmlWriter.Create(Path.Combine(_Skins[skinIndex].Path, _Skins[skinIndex].FileName), CConfig.XMLSettings)) { writer.WriteStartDocument(); writer.WriteStartElement("root"); diff --git a/Vocaluxe/CProgrammHelper.cs b/Vocaluxe/CProgrammHelper.cs new file mode 100644 index 00000000..de0a61a9 --- /dev/null +++ b/Vocaluxe/CProgrammHelper.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.Serialization; +using System.Security; +using System.Text; +using Microsoft.Win32; +using Vocaluxe.Base; + +namespace Vocaluxe +{ + /// + /// Some helper functions for the programm + /// + static class CProgrammHelper + { + private static bool _CheckUninstallKey(string name, string key) + { + using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(key)) + { + if (rk == null) + throw new SecurityException(); + foreach (string skName in rk.GetSubKeyNames()) + { + using (RegistryKey sk = rk.OpenSubKey(skName)) + { + if (sk == null || sk.GetValue("DisplayName") == null) + continue; + string displayName = sk.GetValue("DisplayName").ToString().ToLower(); + if (displayName.Equals(name) || displayName.StartsWith(name) || name.StartsWith(displayName)) + return true; + } + } + } + return false; + } + + /// + /// Checks if a given program is installed by checking the Uninstall registry key. + /// + /// Name of the programm. Got to equal the displayname in the key or one needs to be the start of the other one. NOT case sensitive. + /// + private static bool _IsProgramInstalled(string name) + { + const string uninstallKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"; + const string uninstallKeyx64 = @"SOFTWARE\WoW6432Node\Microsoft\Windows\CurrentVersion\Uninstall"; + name = name.ToLower(); + return _CheckUninstallKey(name, uninstallKey) || _CheckUninstallKey(name, uninstallKeyx64); + } + + private static bool _SystemDllExists(string dllName) + { + const string sysDir = "%windir%\\system32\\"; + return File.Exists(Environment.ExpandEnvironmentVariables(sysDir + dllName + ".dll")); + } + + private static bool _IsVC2012Installed() + { + return _SystemDllExists("msvcr110") && _SystemDllExists("msvcp110"); + } + + private static bool _IsVC2008Installed() + { + return _IsProgramInstalled("Microsoft Visual C++ 2008 Redistributable"); + } + + private static bool _IsVC2010Installed() + { + //Note: Maybe check for x64 or x86 + return _IsProgramInstalled("Microsoft Visual C++ 2010"); + } + + public static bool CheckRequirements() + { + if (!_IsVC2012Installed()) + { + CLog.LogError( + "VC++ 2012 Redistributables are missing. Please install them first.\r\nDownload: http://www.microsoft.com/de-de/download/details.aspx?id=30679", + true, true); + return false; + } + bool vc2008Installed = _IsVC2008Installed(); + if (!vc2008Installed) + { + CLog.LogError( + "VC++ 2008 Redistributables are missing. Portaudio might not be working.\r\nDownload: http://www.microsoft.com/de-de/download/details.aspx?id=29"); + } + if (!vc2008Installed && !_IsVC2010Installed()) + { + CLog.LogError( + "VC++ 2010 and 2008 Redistributables are missing. Please install them first. VC++ 2008 is preferred as Portaudio doesn't work with VC++ 2010.\r\nDownload(2008): http://www.microsoft.com/de-de/download/details.aspx?id=29 \r\nDownload(2010): http://www.microsoft.com/de-de/download/details.aspx?id=5555", + true, true); + return false; + } + return true; + } + } +} \ No newline at end of file diff --git a/Vocaluxe/GameModes/CGameModes.cs b/Vocaluxe/GameModes/CGameModes.cs index 460943ea..a7e7d4b2 100644 --- a/Vocaluxe/GameModes/CGameModes.cs +++ b/Vocaluxe/GameModes/CGameModes.cs @@ -52,7 +52,7 @@ namespace Vocaluxe.GameModes { protected override CSong _PrepareSong(CSong song) { - return song; + return (song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_NORMAL)) ? song : null; } } @@ -60,7 +60,7 @@ namespace Vocaluxe.GameModes { protected override CSong _PrepareSong(CSong song) { - return (song.IsDuet) ? song : null; + return (song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_DUET)) ? song : null; } } @@ -68,9 +68,11 @@ namespace Vocaluxe.GameModes { protected override CSong _PrepareSong(CSong song) { - var newSong = new CSong(song) {Finish = CGame.GetTimeFromBeats(song.ShortEnd, song.BPM) + CSettings.DefaultMedleyFadeOutTime + song.Gap}; + if (!song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_SHORTSONG)) + return null; + var newSong = new CSong(song) {Finish = CGame.GetTimeFromBeats(song.ShortEnd.EndBeat, song.BPM) + CSettings.DefaultMedleyFadeOutTime + song.Gap}; // set lines to short mode - newSong.Notes.SetMedley(song.Notes.GetVoice(0).Lines[0].FirstNoteBeat, song.ShortEnd); + newSong.Notes.SetMedley(0, song.ShortEnd.EndBeat); return newSong; } @@ -80,6 +82,8 @@ namespace Vocaluxe.GameModes { protected override CSong _PrepareSong(CSong song) { + if (!song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_MEDLEY)) + return null; var newSong = new CSong(song) {Start = CGame.GetTimeFromBeats(song.Medley.StartBeat, song.BPM) - song.Medley.FadeInTime + song.Gap}; if (newSong.Start < 0f) newSong.Start = 0f; diff --git a/Vocaluxe/Lib/Playlist/CPlaylistFile.cs b/Vocaluxe/Lib/Playlist/CPlaylistFile.cs index 3c17a424..d40234e9 100644 --- a/Vocaluxe/Lib/Playlist/CPlaylistFile.cs +++ b/Vocaluxe/Lib/Playlist/CPlaylistFile.cs @@ -29,33 +29,22 @@ namespace Vocaluxe.Lib.Playlist { public class CPlaylistFile { - private static readonly XmlWriterSettings _Settings = new XmlWriterSettings(); - public string PlaylistName; public string PlaylistFile; public List Songs = new List(); public CPlaylistFile() { - _Init(); PlaylistName = string.Empty; PlaylistFile = string.Empty; } public CPlaylistFile(string file) { - _Init(); PlaylistFile = file; _LoadPlaylist(); } - private void _Init() - { - _Settings.Indent = true; - _Settings.Encoding = Encoding.UTF8; - _Settings.ConformanceLevel = ConformanceLevel.Document; - } - public void SavePlaylist() { if (PlaylistFile == "") @@ -86,7 +75,7 @@ namespace Vocaluxe.Lib.Playlist XmlWriter writer; try { - writer = XmlWriter.Create(PlaylistFile, _Settings); + writer = XmlWriter.Create(PlaylistFile, CConfig.XMLSettings); } catch (Exception e) { @@ -180,7 +169,11 @@ namespace Vocaluxe.Lib.Playlist public void AddSong(int songID) { - var song = new CPlaylistSong {SongID = songID, GameMode = CSongs.GetSong(songID).IsDuet ? EGameMode.TR_GAMEMODE_DUET : EGameMode.TR_GAMEMODE_NORMAL}; + var song = new CPlaylistSong + { + SongID = songID, + GameMode = CSongs.GetSong(songID).IsGameModeAvailable(EGameMode.TR_GAMEMODE_DUET) ? EGameMode.TR_GAMEMODE_DUET : EGameMode.TR_GAMEMODE_NORMAL + }; Songs.Add(song); } diff --git a/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs b/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs index a22aa3bf..e922e565 100644 --- a/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs +++ b/Vocaluxe/Lib/Video/Acinerella/CDecoder.cs @@ -40,7 +40,7 @@ namespace Vocaluxe.Lib.Video.Acinerella private float _FrameDuration; // frame time in s private float _LastDecodedTime; // time of last decoded frame - private float _LastShownTime; // current video position + private float _LastShownTime; // time if the last shown frame in s private float _Time; private float _Gap; @@ -123,12 +123,6 @@ namespace Vocaluxe.Lib.Video.Acinerella public bool GetFrame(ref CTexture frame, float time, out float videoTime) { - if (_Paused) - { - videoTime = 0; - return false; - } - if (Loop) { lock (_MutexSyncSignals) @@ -137,16 +131,16 @@ namespace Vocaluxe.Lib.Video.Acinerella _LoopTimer.Restart(); } } - else if (Math.Abs(_SetTime - time) > float.Epsilon) + else if (Math.Abs(_SetTime - time) >= 1f / 1000f) //Check 1 ms difference { lock (_MutexSyncSignals) { _SetTime = time; } } - else + else if (Math.Abs(_LastShownTime - time) < 1f / 1000 && frame != null) //Check 1 ms difference { - videoTime = 0; + videoTime = _LastShownTime; return true; } _UploadNewFrame(ref frame); @@ -185,11 +179,6 @@ namespace Vocaluxe.Lib.Video.Acinerella } _LastDecodedTime = _SkipTime; - lock (_MutexSyncSignals) - { - _LastShownTime = _LastDecodedTime; - } - lock (_MutexFramebuffer) { _Framebuffer.Clear(); @@ -425,13 +414,15 @@ namespace Vocaluxe.Lib.Video.Acinerella float now = _SetTime + _Gap; float maxEnd = now - _FrameDuration * 2; //Get only frames younger than 2 CFrame frame; + bool paused = _Paused; while ((frame = _Framebuffer.Get()) != null) { float frameEnd = frame.Time + _FrameDuration; //Don't show frames that are shown during or after now if (frameEnd >= now) break; //All following frames are after that one - + if (paused) // Don't modify anything + break; _Framebuffer.SetRead(); //Get the last(newest) possible frame and skip the rest to force in-order showing if (frameEnd <= maxEnd) @@ -455,4 +446,4 @@ namespace Vocaluxe.Lib.Video.Acinerella } #endregion Threading } -} \ No newline at end of file +} diff --git a/Vocaluxe/Lib/Video/IVideoDecoder.cs b/Vocaluxe/Lib/Video/IVideoDecoder.cs index 3731081b..72d12ecd 100644 --- a/Vocaluxe/Lib/Video/IVideoDecoder.cs +++ b/Vocaluxe/Lib/Video/IVideoDecoder.cs @@ -21,31 +21,94 @@ namespace Vocaluxe.Lib.Video { interface IVideoDecoder { + /// + /// Initializes videodecoder. Got to be called before usage + /// + /// True on success, false if something went wrong. bool Init(); + + /// + /// Close all video streams + /// void CloseAll(); + /// + /// Loads the file with the given file path. + /// + /// Absolute file path of the video file + /// StreamID >=0 on success or -1 on failure int Load(string videoFileName); + + /// + /// Closes the stream with the given ID + /// + /// ID of the stream + /// true if stream was closed, false if stream doesn't exist or already closed bool Close(int streamID); + + /// + /// Gets the number of streams currently active + /// + /// int GetNumStreams(); + /// + /// Gets the length of the video in s + /// + /// Id of the stream + /// Length of the video in s float GetLength(int streamID); /// + /// Gets a frame of the video and sets the current video time /// - /// - /// - /// - /// - /// True if frame is valid + /// Id of the stream + /// Reference to already initialized video texture (from previous calls). If null, one will be created.
+ /// Returns the current video frame which might be outdated if time != current (internal) video position or unchanged (even null) if none is available. + /// The position in s of the video you want to get a frame of. If != current (internal) video position, it will seek to get to right position.
+ /// Note:Will be ignored for looped playback! + /// The actual position in s of the returned frame. Should be ~ time+VideoGap + /// True if frame is valid, false: frame and videoTime might be unchanged or invalid bool GetFrame(int streamID, ref CTexture frame, float time, out float videoTime); + /// + /// Seeks to given position + /// + /// Id of the stream + /// Position to seek to + /// New video gap -> Actual position will be start+gap + /// True on success bool Skip(int streamID, float start, float gap); + + /// + /// Set if the video should be looped + /// + /// Id of the stream + /// True if it should be looped void SetLoop(int streamID, bool loop); + + /// + /// Pauses the video (no new frames will be decoded) + /// + /// Id of the stream void Pause(int streamID); + + /// + /// Resumes a paused video + /// + /// Id of the stream void Resume(int streamID); + /// + /// Check if the given video is finished + /// + /// Id of the stream + /// True if all frames are shown bool Finished(int streamID); + /// + /// Do a step of the decoder in unthreaded decoders. Should be called once every frame. + /// void Update(); } } \ No newline at end of file diff --git a/Vocaluxe/Program.cs b/Vocaluxe/Program.cs index 44a215c0..affc6cc3 100644 --- a/Vocaluxe/Program.cs +++ b/Vocaluxe/Program.cs @@ -28,7 +28,6 @@ using Vocaluxe.Base.Server; namespace Vocaluxe { - // just a small comment for the new develop branch static class CMainProgram { private static CSplashScreen _SplashScreen; @@ -75,6 +74,9 @@ namespace Vocaluxe // Init Log CLog.Init(); + if (!CProgrammHelper.CheckRequirements()) + return; + CMain.Init(); CSettings.CreateFolders(); Application.DoEvents(); diff --git a/Vocaluxe/Properties/AssemblyInfo.cs b/Vocaluxe/Properties/AssemblyInfo.cs index 96cfb9a6..840ed612 100644 --- a/Vocaluxe/Properties/AssemblyInfo.cs +++ b/Vocaluxe/Properties/AssemblyInfo.cs @@ -49,5 +49,5 @@ using System.Runtime.InteropServices; // Revision // -[assembly: AssemblyVersion("0.3.0.81")] -[assembly: AssemblyFileVersion("0.3.0.81")] \ No newline at end of file +[assembly: AssemblyVersion("0.3.0.82")] +[assembly: AssemblyFileVersion("0.3.0.82")] \ No newline at end of file diff --git a/Vocaluxe/Screens/CPopupScreenPlayerControl.cs b/Vocaluxe/Screens/CPopupScreenPlayerControl.cs index c48b2f08..9ffe1779 100644 --- a/Vocaluxe/Screens/CPopupScreenPlayerControl.cs +++ b/Vocaluxe/Screens/CPopupScreenPlayerControl.cs @@ -200,7 +200,7 @@ namespace Vocaluxe.Screens CGame.ClearSongs(); var gm = EGameMode.TR_GAMEMODE_NORMAL; - if (CSongs.AllSongs[songNr].IsDuet) + if (CSongs.AllSongs[songNr].IsGameModeAvailable(EGameMode.TR_GAMEMODE_DUET)) gm = EGameMode.TR_GAMEMODE_DUET; CGame.AddSong(songNr, gm); diff --git a/Vocaluxe/Screens/CScreenNames.cs b/Vocaluxe/Screens/CScreenNames.cs index 6ad757c9..d6d0fb06 100644 --- a/Vocaluxe/Screens/CScreenNames.cs +++ b/Vocaluxe/Screens/CScreenNames.cs @@ -22,6 +22,7 @@ using Vocaluxe.Base; using VocaluxeLib; using VocaluxeLib.Draw; using VocaluxeLib.Menu; +using VocaluxeLib.Songs; namespace Vocaluxe.Screens { @@ -597,6 +598,8 @@ namespace Vocaluxe.Screens _CheckMics(); _CheckPlayers(); + CSong firstSong = CGame.GetSong(0); + for (int i = 0; i < CSettings.MaxNumPlayer; i++) { _Statics[_StaticPlayerAvatar[i]].Texture = CProfiles.IsProfileIDValid(CGame.Players[i].ProfileID) ? @@ -607,8 +610,9 @@ namespace Vocaluxe.Screens { _SelectSlides[_SelectSlideDuetPlayer[i]].Clear(); _SelectSlides[_SelectSlideDuetPlayer[i]].Visible = i + 1 <= CGame.NumPlayer; - _SelectSlides[_SelectSlideDuetPlayer[i]].AddValue(CGame.GetSong(0).DuetPart1); - _SelectSlides[_SelectSlideDuetPlayer[i]].AddValue(CGame.GetSong(0).DuetPart2); + + for (int j = 0; j < firstSong.Notes.VoiceCount; j++) + _SelectSlides[_SelectSlideDuetPlayer[i]].AddValue(firstSong.Notes.VoiceNames[j]); _SelectSlides[_SelectSlideDuetPlayer[i]].Selection = i % 2; } else diff --git a/Vocaluxe/Screens/CScreenScore.cs b/Vocaluxe/Screens/CScreenScore.cs index 51cd0273..ba4f9e42 100644 --- a/Vocaluxe/Screens/CScreenScore.cs +++ b/Vocaluxe/Screens/CScreenScore.cs @@ -298,10 +298,8 @@ namespace Vocaluxe.Screens string name = CProfiles.GetPlayerName(players[p].ProfileID, p); if (song != null && song.IsDuet) { - if (players[p].VoiceNr == 0 && song.DuetPart1 != "Part 1") - name += " (" + song.DuetPart1 + ")"; - else if (players[p].VoiceNr == 1 && song.DuetPart2 != "Part 2") - name += " (" + song.DuetPart2 + ")"; + if (song.Notes.VoiceNames.IsSet(players[p].VoiceNr)) + name += " (" + song.Notes.VoiceNames[players[p].VoiceNr] + ")"; } _Texts[_TextNames[p, CGame.NumPlayer - 1]].Text = name; diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs index e485c684..e792ba4e 100644 --- a/Vocaluxe/Screens/CScreenSing.cs +++ b/Vocaluxe/Screens/CScreenSing.cs @@ -327,7 +327,7 @@ namespace Vocaluxe.Screens _LoadNextSong(); _UpdateSongText(); - _UpdateDuetText(); + _UpdateDuetNames(); if (_FadeOut) return true; @@ -387,12 +387,8 @@ namespace Vocaluxe.Screens for (int p = 0; p < CGame.NumPlayer; p++) { - // ReSharper disable ConvertIfStatementToConditionalTernaryExpression - if (CGame.Players[p].Points < 10000) - // ReSharper restore ConvertIfStatementToConditionalTernaryExpression - _Texts[_TextScores[p, CGame.NumPlayer - 1]].Text = CGame.Players[p].Points.ToString("0000"); - else - _Texts[_TextScores[p, CGame.NumPlayer - 1]].Text = CGame.Players[p].Points.ToString("00000"); + string fmtString = (CGame.Players[p].Points < 10000) ? "0000" : "00000"; + _Texts[_TextScores[p, CGame.NumPlayer - 1]].Text = CGame.Players[p].Points.ToString(fmtString); } if (_CurrentVideo != -1 && !_FadeOut && CConfig.VideosInSongs == EOffOn.TR_CONFIG_ON) @@ -607,12 +603,12 @@ namespace Vocaluxe.Screens _FinishTime = song.Finish; _TimeToFirstNote = 0f; _TimeToFirstNoteDuet = 0f; - var duetPlayer = new int[CGame.NumPlayer]; + var voiceAssignments = new int[CGame.NumPlayer]; if (song.IsDuet) { //Save duet-assignment before resetting - for (int i = 0; i < duetPlayer.Length; i++) - duetPlayer[i] = CGame.Players[i].VoiceNr; + for (int i = 0; i < voiceAssignments.Length; i++) + voiceAssignments[i] = CGame.Players[i].VoiceNr; } CGame.ResetPlayer(); @@ -634,8 +630,9 @@ namespace Vocaluxe.Screens if (song.IsDuet) { - _Texts[_TextDuetName1].Text = song.DuetPart1; - _Texts[_TextDuetName2].Text = song.DuetPart2; + //TODO: Show more than 2 voicenames + _Texts[_TextDuetName1].Text = song.Notes.VoiceNames[0]; + _Texts[_TextDuetName2].Text = song.Notes.VoiceNames[1]; //More than one song: Player is not assigned to line by user //Otherwise, this is done by CScreenNames if (CGame.GetNumSongs() > 1) @@ -646,7 +643,7 @@ namespace Vocaluxe.Screens else { for (int i = 0; i < CGame.NumPlayer; i++) - CGame.Players[i].VoiceNr = duetPlayer[i]; + CGame.Players[i].VoiceNr = voiceAssignments[i]; } } @@ -672,14 +669,11 @@ namespace Vocaluxe.Screens NoteLines[3] = SingNotes[SingBars].AddPlayer(new SRectF(640f, 350f, 590f, 200f, -0.5f), CTheme.ThemeColors.Player[3]); break; */ - _TimerSongText.Stop(); _TimerSongText.Reset(); - _TimerDuetText1.Stop(); _TimerDuetText1.Reset(); - _TimerDuetText2.Stop(); _TimerDuetText2.Reset(); - if (song.Notes.Voices.Length != 2) + if (!song.IsDuet) _TimerSongText.Start(); _StartSong(); @@ -781,7 +775,7 @@ namespace Vocaluxe.Screens _CurrentBeat = CGame.CurrentBeat; - for (int i = 0; i < song.Notes.LinesCount; i++) + for (int i = 0; i < song.Notes.VoiceCount; i++) { if (i > 1) break; // for later @@ -1090,10 +1084,10 @@ namespace Vocaluxe.Screens if (song == null || !song.NotesLoaded) return null; - var alpha = new float[song.Notes.Voices.Length * 2]; + var alpha = new float[song.Notes.VoiceCount * 2]; float currentTime = _CurrentTime - song.Gap; - for (int i = 0; i < song.Notes.LinesCount; i++) + for (int i = 0; i < song.Notes.VoiceCount; i++) { CVoice voice = song.Notes.GetVoice(i); CSongLine[] lines = voice.Lines; @@ -1197,8 +1191,8 @@ namespace Vocaluxe.Screens } else { - _Statics[_StaticSongText].Color.A = (3f - (t - 7f)) / 3f; - _Texts[_TextSongName].Color.A = (3f - (t - 7f)) / 3f; + _Statics[_StaticSongText].Color.A = 10f - t / 3f; + _Texts[_TextSongName].Color.A = 10f - t / 3f; } } else @@ -1215,61 +1209,65 @@ namespace Vocaluxe.Screens } } - private void _UpdateDuetText() + private void _UpdateDuetNames(CText textName, Stopwatch timer) { - if (CGame.GetSong() != null) + if (timer.IsRunning) { - //Timer for first duet-part - if (_TimerDuetText1.IsRunning) + float t = timer.ElapsedMilliseconds / 1000f; + if (t < 10f) { - float t = _TimerDuetText1.ElapsedMilliseconds / 1000f; - if (t < 10f) - { - _Texts[_TextDuetName1].Visible = true; + textName.Visible = true; - if (t < 3f) - _Texts[_TextDuetName1].Color.A = (3f - (3f - t)) / 3f; - else if (t < 7f) - _Texts[_TextDuetName1].Color.A = 1f; - else - _Texts[_TextDuetName1].Color.A = (3f - (t - 7f)) / 3f; - } + if (t < 3f) + textName.Color.A = t / 3f; + else if (t < 7f) + textName.Color.A = 1f; else - { - _Texts[_TextDuetName1].Visible = false; - _TimerDuetText1.Stop(); - } + textName.Color.A = (10f - t) / 3f; } - else if (!_TimerDuetText1.IsRunning && _TimerDuetText1.ElapsedMilliseconds == 0 && _Lyrics[_LyricMainDuet].Alpha > 0 && CGame.GetSong().IsDuet) - _TimerDuetText1.Start(); else - _Texts[_TextDuetName1].Visible = false; - //Timer for second duet-part - if (_TimerDuetText2.IsRunning) { - float t = _TimerDuetText2.ElapsedMilliseconds / 1000f; - if (t < 10f) - { - _Texts[_TextDuetName2].Visible = true; - - if (t < 3f) - _Texts[_TextDuetName2].Color.A = (3f - (3f - t)) / 3f; - else if (t < 7f) - _Texts[_TextDuetName2].Color.A = 1f; - else - _Texts[_TextDuetName2].Color.A = (3f - (t - 7f)) / 3f; - } - else - { - _Texts[_TextDuetName2].Visible = false; - _TimerDuetText2.Stop(); - } + textName.Visible = false; + timer.Stop(); } - else if (!_TimerDuetText2.IsRunning && _TimerDuetText2.ElapsedMilliseconds == 0 && _Lyrics[_LyricMain].Alpha > 0 && CGame.GetSong().IsDuet) - _TimerDuetText2.Start(); - else - _Texts[_TextDuetName2].Visible = false; } + else if (!timer.IsRunning && timer.ElapsedMilliseconds == 0 && _Lyrics[_LyricMainDuet].Alpha > 0 && CGame.GetSong().IsDuet) + timer.Start(); + else + textName.Visible = false; + } + + private void _UpdateDuetNames() + { + if (CGame.GetSong() == null) + return; + //Timer for first duet-part + _UpdateDuetNames(_Texts[_TextDuetName1], _TimerDuetText1); + //Timer for second duet-part + if (_TimerDuetText2.IsRunning) + { + float t = _TimerDuetText2.ElapsedMilliseconds / 1000f; + if (t < 10f) + { + _Texts[_TextDuetName2].Visible = true; + + if (t < 3f) + _Texts[_TextDuetName2].Color.A = (3f - (3f - t)) / 3f; + else if (t < 7f) + _Texts[_TextDuetName2].Color.A = 1f; + else + _Texts[_TextDuetName2].Color.A = (3f - (t - 7f)) / 3f; + } + else + { + _Texts[_TextDuetName2].Visible = false; + _TimerDuetText2.Stop(); + } + } + else if (!_TimerDuetText2.IsRunning && _TimerDuetText2.ElapsedMilliseconds == 0 && _Lyrics[_LyricMain].Alpha > 0 && CGame.GetSong().IsDuet) + _TimerDuetText2.Start(); + else + _Texts[_TextDuetName2].Visible = false; } private void _UpdateTimeLine() diff --git a/Vocaluxe/Screens/CScreenSong.cs b/Vocaluxe/Screens/CScreenSong.cs index 17586fe5..50043dc4 100644 --- a/Vocaluxe/Screens/CScreenSong.cs +++ b/Vocaluxe/Screens/CScreenSong.cs @@ -658,7 +658,7 @@ namespace Vocaluxe.Screens CBackgroundMusic.Disabled = false; int song = _SongMenus[_SongMenu].GetActualSelection(); - if ((CSongs.Category >= 0 || CConfig.Tabs == EOffOn.TR_CONFIG_OFF) && song >= 0 && song < CSongs.VisibleSongs.Count) + if ((CSongs.IsInCategory || CConfig.Tabs == EOffOn.TR_CONFIG_OFF) && song >= 0 && song < CSongs.VisibleSongs.Count) _Texts[_TextSelection].Text = CSongs.VisibleSongs[song].Artist + " - " + CSongs.VisibleSongs[song].Title; else if (!CSongs.IsInCategory && song >= 0 && song < CSongs.Categories.Count) _Texts[_TextSelection].Text = CSongs.Categories[song].Name; @@ -819,9 +819,8 @@ namespace Vocaluxe.Screens CGame.Reset(); CGame.ClearSongs(); - CGame.AddVisibleSong(songNr, gm); - - CGraphics.FadeTo(EScreens.ScreenNames); + if (CGame.AddVisibleSong(songNr, gm)) + CGraphics.FadeTo(EScreens.ScreenNames); } } @@ -834,9 +833,8 @@ namespace Vocaluxe.Screens CGame.Reset(); CGame.ClearSongs(); - CGame.AddVisibleSong(songNr, gm); - - CGraphics.FadeTo(EScreens.ScreenNames); + if (CGame.AddVisibleSong(songNr, gm)) + CGraphics.FadeTo(EScreens.ScreenNames); } } @@ -844,14 +842,13 @@ namespace Vocaluxe.Screens { if ((CSongs.Category >= 0) && (songNr >= 0)) { - if (CSongs.VisibleSongs[songNr].Medley.Source == EMedleySource.None) + if (!CSongs.VisibleSongs[songNr].IsGameModeAvailable(EGameMode.TR_GAMEMODE_MEDLEY)) return; CGame.Reset(); CGame.ClearSongs(); - CGame.AddVisibleSong(songNr, EGameMode.TR_GAMEMODE_MEDLEY); - - CGraphics.FadeTo(EScreens.ScreenNames); + if (CGame.AddVisibleSong(songNr, EGameMode.TR_GAMEMODE_MEDLEY)) + CGraphics.FadeTo(EScreens.ScreenNames); } } @@ -1014,7 +1011,7 @@ namespace Vocaluxe.Screens if (firstLevel && !secondSort) { //TODO: What's to do with multiple tags? - //How can we get current letter? I think we have to save it - Or is there a better method? + //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; @@ -1027,7 +1024,6 @@ namespace Vocaluxe.Screens visibleID = _FindIndex(songs, start, element => element.Artist.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase)); break; - //TODO: Does this make sense? Maybe we should deactivate this for years? You could only jump between 1 and 2 case ESongSorting.TR_CONFIG_YEAR: case ESongSorting.TR_CONFIG_DECADE: if (curSelected >= 0 && curSelected < ct - 1 && songs[curSelected].Year.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase)) @@ -1142,26 +1138,37 @@ namespace Vocaluxe.Screens _Statics[_StaticOptionsBG].Visible = false; _Buttons[_ButtonOpenOptions].Visible = true; - if (CSongs.VisibleSongs.Count > 0) + if (view == ESongOptionsView.None) + _SongOptionsActive = false; + else if (CSongs.IsInCategory) + _SongOptionsActive = CSongs.VisibleSongs.Count > 0; + else + _SongOptionsActive = CSongs.Categories.Count > 0; + + if (!_SongOptionsActive) + return; + + //Has to be done here otherwhise changed playlist names will not appear until OnShow is called! + _UpdatePlaylistNames(); + + _Texts[_TextOptionsTitle].Visible = true; + _Buttons[_ButtonOptionsClose].Visible = true; + _Statics[_StaticOptionsBG].Visible = true; + _Buttons[_ButtonOpenOptions].Visible = false; + if (view == ESongOptionsView.Song) + _ShowSongOptionsSong(); + else if (view == ESongOptionsView.General) + _ShowSongOptionsGeneral(); + else if (view == ESongOptionsView.Medley) + _ShowSongOptionsMedley(); + } + + private void _CheckAndAddGameMode(EGameMode gameMode) + { + if (CSongs.VisibleSongs[_SongMenus[_SongMenu].GetSelectedSong()].IsGameModeAvailable(gameMode)) { - _SongOptionsActive = view != ESongOptionsView.None; - - if (_SongOptionsActive) - { - //Has to be done here otherwhise changed playlist names will not appear until OnShow is called! - _UpdatePlaylistNames(); - - _Texts[_TextOptionsTitle].Visible = true; - _Buttons[_ButtonOptionsClose].Visible = true; - _Statics[_StaticOptionsBG].Visible = true; - _Buttons[_ButtonOpenOptions].Visible = false; - if (view == ESongOptionsView.Song) - _ShowSongOptionsSong(); - else if (view == ESongOptionsView.General) - _ShowSongOptionsGeneral(); - else if (view == ESongOptionsView.Medley) - _ShowSongOptionsMedley(); - } + _SelectSlides[_SelectSlideOptionsMode].AddValue(Enum.GetName(typeof(EGameMode), gameMode)); + _AvailableGameModes.Add(gameMode); } } @@ -1172,23 +1179,11 @@ namespace Vocaluxe.Screens lastMode = _AvailableGameModes[_SelectSlides[_SelectSlideOptionsMode].Selection]; _AvailableGameModes.Clear(); _SelectSlides[_SelectSlideOptionsMode].Clear(); - if (CSongs.VisibleSongs[_SongMenus[_SongMenu].GetSelectedSong()].IsDuet) - { - _SelectSlides[_SelectSlideOptionsMode].AddValue(Enum.GetName(typeof(EGameMode), EGameMode.TR_GAMEMODE_DUET)); - _AvailableGameModes.Add(EGameMode.TR_GAMEMODE_DUET); - } - else - { - _SelectSlides[_SelectSlideOptionsMode].AddValue(Enum.GetName(typeof(EGameMode), EGameMode.TR_GAMEMODE_NORMAL)); - _AvailableGameModes.Add(EGameMode.TR_GAMEMODE_NORMAL); - _SelectSlides[_SelectSlideOptionsMode].AddValue(Enum.GetName(typeof(EGameMode), EGameMode.TR_GAMEMODE_SHORTSONG)); - _AvailableGameModes.Add(EGameMode.TR_GAMEMODE_SHORTSONG); - } - if (CSongs.VisibleSongs[_SongMenus[_SongMenu].GetSelectedSong()].Medley.Source != EMedleySource.None) - { - _SelectSlides[_SelectSlideOptionsMode].AddValue(Enum.GetName(typeof(EGameMode), EGameMode.TR_GAMEMODE_MEDLEY)); - _AvailableGameModes.Add(EGameMode.TR_GAMEMODE_MEDLEY); - } + _CheckAndAddGameMode(EGameMode.TR_GAMEMODE_NORMAL); + _CheckAndAddGameMode(EGameMode.TR_GAMEMODE_DUET); + _CheckAndAddGameMode(EGameMode.TR_GAMEMODE_SHORTSONG); + _CheckAndAddGameMode(EGameMode.TR_GAMEMODE_MEDLEY); + //Set SelectSlide-Selection to last selected game-mode if possible for (int i = 0; i < _AvailableGameModes.Count; i++) { diff --git a/Vocaluxe/SongQueue/CSongQueue.cs b/Vocaluxe/SongQueue/CSongQueue.cs index 3fb3169f..3ec026f1 100644 --- a/Vocaluxe/SongQueue/CSongQueue.cs +++ b/Vocaluxe/SongQueue/CSongQueue.cs @@ -67,7 +67,7 @@ namespace Vocaluxe.SongQueue private bool _AddSong(int songID, EGameMode gameMode) { - if (gameMode == EGameMode.TR_GAMEMODE_DUET && !CSongs.GetSong(songID).IsDuet) + if (!CSongs.GetSong(songID).IsGameModeAvailable(gameMode)) return false; _SongQueue.Add(new SSongQueueEntry(songID, gameMode)); diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index 952a7804..17132251 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -232,6 +232,7 @@ + Form @@ -336,4 +337,4 @@ --> - + \ No newline at end of file diff --git a/VocaluxeLib/CHelper.cs b/VocaluxeLib/CHelper.cs index 04ea1a90..02924158 100644 --- a/VocaluxeLib/CHelper.cs +++ b/VocaluxeLib/CHelper.cs @@ -62,7 +62,6 @@ namespace VocaluxeLib public static string ListStrings(string[] str) { string result = string.Empty; - for (int i = 0; i < str.Length; i++) { result += str[i]; @@ -150,6 +149,8 @@ namespace VocaluxeLib { var files = new List(); var dir = new DirectoryInfo(path); + if (!dir.Exists) + return files; try { @@ -169,13 +170,7 @@ namespace VocaluxeLib return files; } - public static bool TryParse(string value, out T result) - where T : struct - { - return TryParse(value, out result, false); - } - - public static bool TryParse(string value, out T result, bool ignoreCase) + public static bool TryParse(string value, out T result, bool ignoreCase=false) where T : struct { result = default(T); @@ -208,7 +203,7 @@ namespace VocaluxeLib static class CEncoding { - public static Encoding GetEncoding(string encodingName) + public static Encoding GetEncoding(this string encodingName) { switch (encodingName) { @@ -223,11 +218,11 @@ namespace VocaluxeLib case "UTF8": return Encoding.UTF8; default: - return Encoding.UTF8; + return Encoding.Default; } } - public static string GetEncodingName(Encoding enc) + public static string GetEncodingName(this Encoding enc) { string result = "UTF8"; diff --git a/VocaluxeLib/Extensions.cs b/VocaluxeLib/Extensions.cs new file mode 100644 index 00000000..d6c78529 --- /dev/null +++ b/VocaluxeLib/Extensions.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; + +namespace VocaluxeLib +{ + public static class Extensions + { + /// + /// Resizes the given list to the given size. Removes elements or adds default values + /// + /// + /// + /// + /// + public static void Resize(this List list, int size, T defaultValue = default(T)) + { + int curSize = list.Count; + if (size < curSize) + list.RemoveRange(size, curSize - size); + else if (size > curSize) + list.AddRange(Enumerable.Repeat(defaultValue, size - curSize)); + } + + /// + /// Makes the list at least the given size adding the given default values. + /// + /// + /// + /// + /// + public static void EnsureSize(this List list, int size, T defaultValue) + { + int curSize = list.Count; + if (size > curSize) + list.AddRange(Enumerable.Repeat(defaultValue, size - curSize)); + } + + /// + /// Makes the list at least the given size adding a new instance of T + /// + /// + /// + /// + public static void EnsureSize(this List list, int size) where T : new() + { + if (size > list.Count) + list.Add(new T()); + } + + /// + /// Gets all set bits starting from lowest (Bit 0) + /// + /// + /// + public static IEnumerable GetSetBits(this int value) + { + var result = new List(); + int curBit = 0; + //Evaluate as bitset + while (value > 0) + { + if ((value & 1) != 0) + result.Add(curBit); + value >>= 1; + curBit++; + } + return result; + } + + public static bool ContainsIgnoreCase(this string value, string other) + { + return value.IndexOf(other, StringComparison.CurrentCultureIgnoreCase) >= 0; + } + + public static string TrimMultipleWs(this string value) + { + if (string.IsNullOrEmpty(value)) + return ""; + int start = 0; + int len = value.Length; + while (value[start] == ' ') + { + start++; + if (start >= len) + return ""; + } + if (start > 0) + start--; + int end = --len; + while (value[end] == ' ') + end--; + if (end < len) + end++; + if (end - start < len) + value = value.Substring(start, end - start + 1); + return value; + } + + /// + /// Converts value to a string in fixed point notation using invariant formating (english style decimal point) + /// + /// Value to be converted + /// String representation of value + public static string ToInvariantString(this float value) + { + return value.ToString("F", NumberFormatInfo.InvariantInfo); + } + } +} \ No newline at end of file diff --git a/VocaluxeLib/IBasic.cs b/VocaluxeLib/IBasic.cs index 2c34490b..b64e5e60 100644 --- a/VocaluxeLib/IBasic.cs +++ b/VocaluxeLib/IBasic.cs @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Drawing; +using System.Xml; using VocaluxeLib.Draw; using VocaluxeLib.Game; using VocaluxeLib.Menu; @@ -29,6 +30,8 @@ namespace VocaluxeLib { public interface IConfig { + EOffOn GetSaveModifiedSongs(); + void SetBackgroundMusicVolume(int newVolume); int GetBackgroundMusicVolume(); @@ -45,13 +48,18 @@ namespace VocaluxeLib int GetCoverSize(); - IEnumerable GetSongFolder(); + IEnumerable GetSongFolders(); ESongSorting GetSongSorting(); EOffOn GetTabs(); EOffOn GetIgnoreArticles(); bool IsMicConfigured(int playerNr); int GetMaxNumMics(); + + /// + /// Get the uniform settings for writing XML files. ALWAYS use this! + /// + XmlWriterSettings GetXMLSettings(); } public interface ISettings @@ -179,6 +187,7 @@ namespace VocaluxeLib double GetRandomDouble(); float GetTimeFromBeats(float beat, float bpm); + float GetBeatFromTime(float time, float bpm, float gap); void AddSong(int songID, EGameMode gameMode); void Reset(); @@ -204,7 +213,8 @@ namespace VocaluxeLib int GetNumSongs(); int GetNumSongsVisible(); int GetNumCategories(); - int NumSongsInCategory(int categoryIndex); + int GetNumSongsInCategory(int categoryIndex); + int GetNumSongsNotSungInCategory(int categoryIndex); bool IsInCategory(); int GetCurrentCategoryIndex(); diff --git a/VocaluxeLib/Menu/CLyric.cs b/VocaluxeLib/Menu/CLyric.cs index 0191be9e..7c1376a5 100644 --- a/VocaluxeLib/Menu/CLyric.cs +++ b/VocaluxeLib/Menu/CLyric.cs @@ -23,15 +23,6 @@ using VocaluxeLib.Songs; namespace VocaluxeLib.Menu { - struct SNote - { - public string Text; - public int StartBeat; - public int EndBeat; - public int Duration; - public ENoteType Type; - } - struct SThemeLyrics { public string Name; @@ -46,7 +37,10 @@ namespace VocaluxeLib.Menu private SThemeLyrics _Theme; private bool _ThemeLoaded; - private readonly List _Notes; + /// + /// Holds a reference to Songline. DO NOT MODIFY + /// + private CSongLine _Line; private CText _Text; private float _X; @@ -109,7 +103,7 @@ namespace VocaluxeLib.Menu _MaxW = 1f; _H = 1f; _Width = 1f; - _Notes = new List(); + _Line = new CSongLine(); _Text = new CText(_PartyModeID); LyricStyle = ELyricStyle.Fill; @@ -201,28 +195,27 @@ namespace VocaluxeLib.Menu public void SetLine(CSongLine line) { - _Notes.Clear(); - + _Line = line; _Width = 0f; foreach (CSongNote note in line.Notes) { - var n = new SNote {Text = note.Text, StartBeat = note.StartBeat, EndBeat = note.EndBeat, Duration = note.Duration, Type = note.NoteType}; - - _Text.Text = note.Text; - _Text.Style = EStyle.Bold; - - if (n.Type == ENoteType.Freestyle) - _Text.Style = EStyle.BoldItalic; - - RectangleF rect = CBase.Fonts.GetTextBounds(_Text); - _Width += rect.Width; - _Notes.Add(n); + _SetText(note); + _Width += _Text.Rect.W; } } + private void _SetText(CSongNote note) + { + _Text.Text = note.Text; + _Text.Style = EStyle.Bold; + + if (note.Type == ENoteType.Freestyle) + _Text.Style = EStyle.BoldItalic; + } + public void Clear() { - _Notes.Clear(); + _Line = new CSongLine(); } public float GetCurrentLyricPosX() @@ -260,15 +253,10 @@ namespace VocaluxeLib.Menu { float x = _X - _Width / 2; - foreach (SNote note in _Notes) + foreach (CSongNote note in _Line.Notes) { _Text.X = x; - _Text.Style = EStyle.Bold; - _Text.Text = note.Text; - RectangleF rect = CBase.Fonts.GetTextBounds(_Text); - - if (note.Type == ENoteType.Freestyle) - _Text.Style = EStyle.BoldItalic; + _SetText(note); if (currentBeat >= note.StartBeat) { @@ -276,9 +264,8 @@ namespace VocaluxeLib.Menu { _Text.Color = _ColorProcessed; - - float diff = note.EndBeat - note.StartBeat; - if (Math.Abs(diff) < float.Epsilon) + int diff = note.EndBeat - note.StartBeat; + if (diff <= 0) _Text.Draw(0f, 1f); else { @@ -299,7 +286,7 @@ namespace VocaluxeLib.Menu _Text.Draw(); } - x += rect.Width; + x += _Text.Rect.W; } } @@ -308,37 +295,27 @@ namespace VocaluxeLib.Menu float x = _X - _Width / 2; // most left position //find last active note - int lastNote = -1; - for (int i = 0; i < _Notes.Count; i++) - { - if (currentBeat >= _Notes[i].StartBeat) - lastNote = i; - } + int lastNote = _Line.FindPreviousNote((int)currentBeat); int zoomNote = -1; int endBeat = -1; float zoomx = 0f; - for (int note = 0; note < _Notes.Count; note++) + for (int note = 0; note < _Line.Notes.Length; note++) { _Text.X = x; - _Text.Style = EStyle.Bold; - _Text.Text = _Notes[note].Text; - RectangleF rect = CBase.Fonts.GetTextBounds(_Text); + _SetText(_Line.Notes[note]); - if (_Notes[note].Type == ENoteType.Freestyle) - _Text.Style = EStyle.BoldItalic; - - if (currentBeat >= _Notes[note].StartBeat) + if (currentBeat >= _Line.Notes[note].StartBeat) { - int endbeat = _Notes[note].EndBeat; - if (note < _Notes.Count - 1) - endbeat = _Notes[note + 1].StartBeat - 1; + int curEndBeat = _Line.Notes[note].EndBeat; + if (note < _Line.Notes.Length - 1) + curEndBeat = _Line.Notes[note + 1].StartBeat - 1; - if (currentBeat <= endbeat) + if (currentBeat <= curEndBeat) { zoomNote = note; - endBeat = endbeat; + endBeat = curEndBeat; zoomx = _Text.X; } else @@ -356,49 +333,37 @@ namespace VocaluxeLib.Menu _Text.Draw(); } - x += rect.Width; + x += _Text.Rect.W; } if (zoomNote > -1) { - if (_Notes[zoomNote].Duration == 0) - return; - _Text.X = zoomx; - _Text.Text = _Notes[zoomNote].Text; - _Text.Color = _ColorProcessed; - _Text.Style = EStyle.Bold; + _SetText(_Line.Notes[zoomNote]); - if (_Notes[zoomNote].Type == ENoteType.Freestyle) - _Text.Style = EStyle.BoldItalic; - - RectangleF rect = CBase.Fonts.GetTextBounds(_Text); - - float diff = endBeat - _Notes[zoomNote].StartBeat; + float diff = endBeat - _Line.Notes[zoomNote].StartBeat; if (diff <= 0f) diff = 1f; - float p = (currentBeat - _Notes[zoomNote].StartBeat) / diff; + float p = (currentBeat - _Line.Notes[zoomNote].StartBeat) / diff; if (p > 1f) p = 1f; p = 1f - p; float ty = _Text.Y; - float tx = _Text.X; float th = _Text.Height; float tz = _Text.Z; + SRectF normalRect = _Text.Rect; _Text.Height += _Text.Height * p * 0.4f; - RectangleF rectz = CBase.Fonts.GetTextBounds(_Text); - _Text.X -= (rectz.Width - rect.Width) / 2f; - _Text.Y -= (rectz.Height - rect.Height) / 2f; + _Text.X -= (_Text.Rect.W - normalRect.W) / 2f; + _Text.Y -= (_Text.Rect.W - normalRect.H) / 2f; _Text.Z -= 0.1f; _Text.Draw(); _Text.Y = ty; - _Text.X = tx; _Text.Height = th; _Text.Z = tz; } @@ -408,15 +373,10 @@ namespace VocaluxeLib.Menu { float x = _X - _Width / 2; // most left position - foreach (SNote note in _Notes) + foreach (CSongNote note in _Line.Notes) { _Text.X = x; - _Text.Style = EStyle.Bold; - _Text.Text = note.Text; - RectangleF rect = CBase.Fonts.GetTextBounds(_Text); - - if (note.Type == ENoteType.Freestyle) - _Text.Style = EStyle.BoldItalic; + _SetText(note); if (currentBeat >= note.StartBeat) { @@ -430,7 +390,7 @@ namespace VocaluxeLib.Menu _Text.Draw(); } - x += rect.Width; + x += _Text.Rect.W; } } @@ -439,29 +399,23 @@ namespace VocaluxeLib.Menu float x = _X - _Width / 2; // most left position //find last active note - int lastNote = -1; - for (int i = 0; i < _Notes.Count; i++) - { - if (currentBeat >= _Notes[i].StartBeat) - lastNote = i; - } + int lastNote = _Line.FindPreviousNote((int)currentBeat); int jumpNote = -1; float jumpx = 0f; - for (int note = 0; note < _Notes.Count; note++) + for (int note = 0; note < _Line.Notes.Length; note++) { _Text.X = x; - _Text.Style = EStyle.Bold; - _Text.Text = _Notes[note].Text; - RectangleF rect = CBase.Fonts.GetTextBounds(_Text); + _SetText(_Line.Notes[note]); - if (_Notes[note].Type == ENoteType.Freestyle) - _Text.Style = EStyle.BoldItalic; - - if (currentBeat >= _Notes[note].StartBeat) + if (currentBeat >= _Line.Notes[note].StartBeat) { - if (currentBeat <= _Notes[note].EndBeat) + int curEndBeat = _Line.Notes[note].EndBeat; + if (note < _Line.Notes.Length - 1) + curEndBeat = _Line.Notes[note + 1].StartBeat - 1; + + if (currentBeat <= curEndBeat) { jumpNote = note; jumpx = _Text.X; @@ -481,27 +435,20 @@ namespace VocaluxeLib.Menu _Text.Draw(); } - x += rect.Width; + x += _Text.Rect.W; } if (jumpNote < 0) return; - if (_Notes[jumpNote].Duration == 0) - return; _Text.X = jumpx; - _Text.Text = _Notes[jumpNote].Text; - _Text.Color = _ColorProcessed; - _Text.Style = EStyle.Bold; + _SetText(_Line.Notes[jumpNote]); - if (_Notes[jumpNote].Type == ENoteType.Freestyle) - _Text.Style = EStyle.BoldItalic; - - int diff = _Notes[jumpNote].EndBeat - _Notes[jumpNote].StartBeat; + int diff = _Line.Notes[jumpNote].EndBeat - _Line.Notes[jumpNote].StartBeat; if (diff <= 0) diff = 1; - float p = 1f - (currentBeat - _Notes[jumpNote].StartBeat) / diff; + float p = 1f - (currentBeat - _Line.Notes[jumpNote].StartBeat) / diff; if (Math.Abs(p) < float.Epsilon) _Text.Draw(); diff --git a/VocaluxeLib/Menu/CMenu.cs b/VocaluxeLib/Menu/CMenu.cs index 2c365121..73e53958 100644 --- a/VocaluxeLib/Menu/CMenu.cs +++ b/VocaluxeLib/Menu/CMenu.cs @@ -196,10 +196,9 @@ namespace VocaluxeLib.Menu if (_ThemePath == "") return; - var settings = new XmlWriterSettings {Indent = true, Encoding = Encoding.UTF8, ConformanceLevel = ConformanceLevel.Document}; string file = Path.Combine(_ThemePath, ThemeName + ".xml"); - using (XmlWriter writer = XmlWriter.Create(file, settings)) + using (XmlWriter writer = XmlWriter.Create(file, CBase.Config.GetXMLSettings())) { writer.WriteStartDocument(); writer.WriteStartElement("root"); diff --git a/VocaluxeLib/Menu/CNameSelection.cs b/VocaluxeLib/Menu/CNameSelection.cs index 47c19633..d162d539 100644 --- a/VocaluxeLib/Menu/CNameSelection.cs +++ b/VocaluxeLib/Menu/CNameSelection.cs @@ -407,9 +407,9 @@ namespace VocaluxeLib.Menu { if ((i + offset * _Tiles.Count) < _VisibleProfiles.Count) { - _Tiles[i].Avatar.Texture = CBase.Profiles.GetProfiles()[_VisibleProfiles[i + offset * _Tiles.Count]].Avatar.Texture; + _Tiles[i].Avatar.Texture = CBase.Profiles.GetAvatar(_VisibleProfiles[i + offset * _Tiles.Count]); _Tiles[i].Avatar.Color = new SColorF(1, 1, 1, 1); - _Tiles[i].Name.Text = CBase.Profiles.GetProfiles()[_VisibleProfiles[i + offset * _Tiles.Count]].PlayerName; + _Tiles[i].Name.Text = CBase.Profiles.GetPlayerName(_VisibleProfiles[i + offset * _Tiles.Count]); ; _Tiles[i].ProfileID = _VisibleProfiles[i + offset * _Tiles.Count]; } else diff --git a/VocaluxeLib/Menu/CPlaylist.cs b/VocaluxeLib/Menu/CPlaylist.cs index 82c5f93a..1610fd52 100644 --- a/VocaluxeLib/Menu/CPlaylist.cs +++ b/VocaluxeLib/Menu/CPlaylist.cs @@ -84,7 +84,7 @@ namespace VocaluxeLib.Menu { private class CPlaylistElementContent { - public EGameMode[] Modes; + public IList Modes; public int SongID; public EGameMode Mode; } @@ -971,11 +971,11 @@ namespace VocaluxeLib.Menu if (!mouseEvent.LBH && DragAndDropSongID != -1) { - var gm = EGameMode.TR_GAMEMODE_NORMAL; CSong song = CBase.Songs.GetSongByID(DragAndDropSongID); if (song != null) { + var gm = EGameMode.TR_GAMEMODE_NORMAL; if (song.IsDuet) gm = EGameMode.TR_GAMEMODE_DUET; @@ -1220,7 +1220,7 @@ namespace VocaluxeLib.Menu string t1 = CBase.Language.Translate(_Theme.Text1.Text).Replace("%a", song.Artist).Replace("%t", song.Title); _PlaylistElements[i].Text1.Text = /*(Offset + i + 1) + ") " + */ t1; //TODO: Add text field for the number _PlaylistElements[i].SelectSlide.Clear(); - for (int g = 0; g < pec.Modes.Length; g++) + for (int g = 0; g < pec.Modes.Count; g++) { _PlaylistElements[i].SelectSlide.AddValue(Enum.GetName(typeof(EGameMode), pec.Modes[g])); if (pec.Modes[g] == pec.Mode) diff --git a/VocaluxeLib/Menu/CText.cs b/VocaluxeLib/Menu/CText.cs index 7c3e19f6..94c2c01c 100644 --- a/VocaluxeLib/Menu/CText.cs +++ b/VocaluxeLib/Menu/CText.cs @@ -422,7 +422,7 @@ namespace VocaluxeLib.Menu writer.WriteElementString("Align", Enum.GetName(typeof(EAlignment), Align)); writer.WriteComment(": Text align vertical (on downsizing): " + CHelper.ListStrings(Enum.GetNames(typeof(EHAlignment)))); - writer.WriteElementString("HAlign", Enum.GetName(typeof(EHAlignment), ResizeAlign)); + writer.WriteElementString("ResizeAlign", Enum.GetName(typeof(EHAlignment), ResizeAlign)); writer.WriteComment("