From b12e4156faa2b15c18d389790afc91f98c934ad1 Mon Sep 17 00:00:00 2001 From: Flamefire Date: Sat, 12 Oct 2013 21:42:03 +0200 Subject: [PATCH] Allow #ENDSHORT tags Detect where Preview and ShortEnd came from Introduce a function to check whether a given GameMode is available for a song --- .../CPartyScreenTicTacToeMain.cs | 4 +- Vocaluxe/Base/CGame.cs | 2 +- Vocaluxe/Base/CLog.cs | 1 - Vocaluxe/GameModes/CGameModes.cs | 4 +- Vocaluxe/Screens/CScreenSong.cs | 33 ++++--- VocaluxeLib/Extensions.cs | 24 ++++++ VocaluxeLib/IBasic.cs | 1 + VocaluxeLib/Menu/CPlaylist.cs | 4 +- .../Menu/SongMenu/CSongMenuFramework.cs | 30 ++++--- .../Menu/SongMenu/CSongMenuTileBoard.cs | 4 +- VocaluxeLib/Songs/CSong.cs | 85 ++++++++++++------- VocaluxeLib/Songs/CSongLine.cs | 4 +- VocaluxeLib/Songs/CSongLoader.cs | 52 +++++++----- VocaluxeLib/Songs/CSongWriter.cs | 16 +++- 14 files changed, 167 insertions(+), 97 deletions(-) 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/Base/CGame.cs b/Vocaluxe/Base/CGame.cs index 7f47fbf5..6eb98838 100644 --- a/Vocaluxe/Base/CGame.cs +++ b/Vocaluxe/Base/CGame.cs @@ -234,7 +234,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; diff --git a/Vocaluxe/Base/CLog.cs b/Vocaluxe/Base/CLog.cs index 350950bb..0dd53fe2 100644 --- a/Vocaluxe/Base/CLog.cs +++ b/Vocaluxe/Base/CLog.cs @@ -118,7 +118,6 @@ namespace Vocaluxe.Base if (e != null) errorText += ": " + e; _ErrorLog.Add(_NumErrors + ") " + errorText + "\r\n"); - _ErrorLog.Add(String.Empty); if (exit) Environment.Exit(Environment.ExitCode); } diff --git a/Vocaluxe/GameModes/CGameModes.cs b/Vocaluxe/GameModes/CGameModes.cs index 460943ea..c49ff93e 100644 --- a/Vocaluxe/GameModes/CGameModes.cs +++ b/Vocaluxe/GameModes/CGameModes.cs @@ -68,9 +68,9 @@ 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}; + 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; } diff --git a/Vocaluxe/Screens/CScreenSong.cs b/Vocaluxe/Screens/CScreenSong.cs index 17586fe5..70834067 100644 --- a/Vocaluxe/Screens/CScreenSong.cs +++ b/Vocaluxe/Screens/CScreenSong.cs @@ -844,7 +844,7 @@ 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(); @@ -1165,6 +1165,15 @@ namespace Vocaluxe.Screens } } + private void _CheckAndAddGameMode(EGameMode gameMode) + { + if (CSongs.VisibleSongs[_SongMenus[_SongMenu].GetSelectedSong()].IsGameModeAvailable(gameMode)) + { + _SelectSlides[_SelectSlideOptionsMode].AddValue(Enum.GetName(typeof(EGameMode), gameMode)); + _AvailableGameModes.Add(gameMode); + } + } + private void _ShowSongOptionsSong() { var lastMode = EGameMode.TR_GAMEMODE_NORMAL; @@ -1172,23 +1181,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/VocaluxeLib/Extensions.cs b/VocaluxeLib/Extensions.cs index 8f2be91e..a035f869 100644 --- a/VocaluxeLib/Extensions.cs +++ b/VocaluxeLib/Extensions.cs @@ -73,5 +73,29 @@ namespace VocaluxeLib { 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; + } } } \ No newline at end of file diff --git a/VocaluxeLib/IBasic.cs b/VocaluxeLib/IBasic.cs index 6543482a..efdb45df 100644 --- a/VocaluxeLib/IBasic.cs +++ b/VocaluxeLib/IBasic.cs @@ -181,6 +181,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(); diff --git a/VocaluxeLib/Menu/CPlaylist.cs b/VocaluxeLib/Menu/CPlaylist.cs index 82c5f93a..1eecc9f2 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; } @@ -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/SongMenu/CSongMenuFramework.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs index c1e6ea5b..7a717f7d 100644 --- a/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs +++ b/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs @@ -22,6 +22,7 @@ using System.IO; using System.Xml; using VocaluxeLib.Draw; using VocaluxeLib.PartyModes; +using VocaluxeLib.Songs; namespace VocaluxeLib.Menu.SongMenu { @@ -101,7 +102,7 @@ namespace VocaluxeLib.Menu.SongMenu private readonly Stopwatch _Timer = new Stopwatch(); private readonly Stopwatch _VideoFadeTimer = new Stopwatch(); private readonly List _Streams = new List(); - private int _Actsong = -1; + private int _ActSongId = -1; private int _Actsongstream = -1; protected CTexture _Vidtex; @@ -186,7 +187,7 @@ namespace VocaluxeLib.Menu.SongMenu protected int _ActSong { - get { return _Actsong; } + get { return _ActSongId; } } public SRectF Rect @@ -206,7 +207,7 @@ namespace VocaluxeLib.Menu.SongMenu public virtual int GetActualSelection() { - return _Actsong; + return _ActSongId; } private bool _Selected; @@ -434,7 +435,7 @@ namespace VocaluxeLib.Menu.SongMenu if (!_Initialized) return; - if (_Actsong != _PreviewSelected) + if (_ActSongId != _PreviewSelected) _SelectSong(_PreviewSelected); if (_Streams.Count <= 0 || _Video == -1) @@ -607,7 +608,7 @@ namespace VocaluxeLib.Menu.SongMenu protected void _SelectSong(int nr) { - if (CBase.Songs.IsInCategory() && (CBase.Songs.GetNumSongsVisible() > 0) && (nr >= 0) && ((_Actsong != nr) || (_Streams.Count == 0))) + if (CBase.Songs.IsInCategory() && (CBase.Songs.GetNumSongsVisible() > 0) && (nr >= 0) && ((_ActSongId != nr) || (_Streams.Count == 0))) { _Streams.ForEach(soundStream => CBase.Sound.FadeAndStop(soundStream, 0f, 1f)); _Streams.Clear(); @@ -617,18 +618,19 @@ namespace VocaluxeLib.Menu.SongMenu CBase.Drawing.RemoveTexture(ref _Vidtex); - _Actsong = nr; - if (_Actsong >= CBase.Songs.GetNumSongsVisible()) - _Actsong = 0; + _ActSongId = nr; + if (_ActSongId >= CBase.Songs.GetNumSongsVisible()) + _ActSongId = 0; - int stream = CBase.Sound.Load(Path.Combine(CBase.Songs.GetVisibleSong(_Actsong).Folder, CBase.Songs.GetVisibleSong(_Actsong).MP3FileName), true); + CSong actSong = CBase.Songs.GetVisibleSong(_ActSongId); + int stream = CBase.Sound.Load(Path.Combine(actSong.Folder, actSong.MP3FileName), true); CBase.Sound.SetStreamVolumeMax(stream, _MaxVolume); CBase.Sound.SetStreamVolume(stream, 0f); - float startposition = CBase.Songs.GetVisibleSong(_Actsong).PreviewStart; + float startposition = actSong.Preview.StartTime; - if (Math.Abs(startposition) < 0.001) + if (actSong.Preview.Source == EDataSource.None) startposition = CBase.Sound.GetLength(stream) / 4f; if (startposition >= 0.5f) @@ -640,12 +642,12 @@ namespace VocaluxeLib.Menu.SongMenu _Streams.Add(stream); _Actsongstream = stream; - if (CBase.Songs.GetVisibleSong(_Actsong).VideoFileName != "" && CBase.Config.GetVideoPreview() == EOffOn.TR_CONFIG_ON) + if (actSong.VideoFileName != "" && CBase.Config.GetVideoPreview() == EOffOn.TR_CONFIG_ON) { - _Video = CBase.Video.Load(Path.Combine(CBase.Songs.GetVisibleSong(_Actsong).Folder, CBase.Songs.GetVisibleSong(_Actsong).VideoFileName)); + _Video = CBase.Video.Load(Path.Combine(actSong.Folder, actSong.VideoFileName)); if (_Video == -1) return; - CBase.Video.Skip(_Video, startposition, CBase.Songs.GetVisibleSong(_Actsong).VideoGap); + CBase.Video.Skip(_Video, startposition, actSong.VideoGap); _VideoFadeTimer.Stop(); _VideoFadeTimer.Reset(); _VideoFadeTimer.Start(); diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs index a0ba7fe1..dc18e486 100644 --- a/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs +++ b/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs @@ -413,8 +413,8 @@ namespace VocaluxeLib.Menu.SongMenu _Title.Text = song.Title; _DuetIcon.Visible = song.IsDuet; _VideoIcon.Visible = song.VideoFileName != ""; - _MedleyCalcIcon.Visible = song.Medley.Source == EMedleySource.Calculated; - _MedleyTagIcon.Visible = song.Medley.Source == EMedleySource.Tag; + _MedleyCalcIcon.Visible = song.Medley.Source == EDataSource.Calculated; + _MedleyTagIcon.Visible = song.Medley.Source == EDataSource.Tag; float time = CBase.Sound.GetLength(_SongStream); if (Math.Abs(song.Finish) > 0.001) diff --git a/VocaluxeLib/Songs/CSong.cs b/VocaluxeLib/Songs/CSong.cs index ac528889..45f5af1f 100644 --- a/VocaluxeLib/Songs/CSong.cs +++ b/VocaluxeLib/Songs/CSong.cs @@ -44,12 +44,11 @@ namespace VocaluxeLib.Songs Artist = 2, MP3 = 4, BPM = 8, - PreviewStart = 16, - MedleyStartBeat = 32, - MedleyEndBeat = 64 + MedleyStartBeat = 16, + MedleyEndBeat = 32 } - public enum EMedleySource + public enum EDataSource { None = 0, Calculated, @@ -58,13 +57,25 @@ namespace VocaluxeLib.Songs public struct SMedley { - public EMedleySource Source; + public EDataSource Source; public int StartBeat; public int EndBeat; public float FadeInTime; public float FadeOutTime; } + public struct SShortEnd + { + public EDataSource Source; + public int EndBeat; + } + + public struct SPreview + { + public EDataSource Source; + public float StartTime; + } + public partial class CSong { private CTexture _CoverTextureSmall; @@ -73,12 +84,12 @@ namespace VocaluxeLib.Songs public SMedley Medley; private bool _CalculateMedley = true; - public float PreviewStart; + public SPreview Preview; - public int ShortEnd; + public SShortEnd ShortEnd; public Encoding Encoding = Encoding.Default; - public bool ManualEncoding = false; + public bool ManualEncoding; public string Folder = String.Empty; public string FolderName = String.Empty; public string FileName = String.Empty; @@ -167,19 +178,30 @@ namespace VocaluxeLib.Songs // Notes public readonly CNotes Notes = new CNotes(); - public EGameMode[] AvailableGameModes + public IList AvailableGameModes { get { var gms = new List {IsDuet ? EGameMode.TR_GAMEMODE_DUET : EGameMode.TR_GAMEMODE_NORMAL}; - if (Medley.Source != EMedleySource.None) + if (Medley.Source != EDataSource.None) gms.Add(EGameMode.TR_GAMEMODE_MEDLEY); - gms.Add(EGameMode.TR_GAMEMODE_SHORTSONG); + if (ShortEnd.Source != EDataSource.None) + gms.Add(EGameMode.TR_GAMEMODE_SHORTSONG); - return gms.ToArray(); + return gms; } } + /// + /// Returns true if the requested game mode is available + /// + /// + /// true if the requested game mode is available + public bool IsGameModeAvailable(EGameMode gameMode) + { + return AvailableGameModes.Any(gm => gm == gameMode); + } + //No point creating a song without a text file --> Use factory method LoadSong private CSong() {} @@ -191,7 +213,7 @@ namespace VocaluxeLib.Songs Medley = song.Medley; _CalculateMedley = song._CalculateMedley; - PreviewStart = song.PreviewStart; + Preview = song.Preview; ShortEnd = song.ShortEnd; @@ -380,13 +402,10 @@ namespace VocaluxeLib.Songs { if (IsDuet) { - Medley.Source = EMedleySource.None; + Medley.Source = EDataSource.None; return; } - if (Medley.Source == EMedleySource.Tag) - return; - if (!_CalculateMedley) return; @@ -410,41 +429,44 @@ namespace VocaluxeLib.Songs Medley.StartBeat = voice.Lines[series[longest].Start].FirstNoteBeat; Medley.EndBeat = voice.Lines[series[longest].End].LastNoteBeat; - bool foundEnd = CBase.Game.GetTimeFromBeats(Medley.StartBeat, BPM) + CBase.Settings.GetMedleyMinDuration() > - CBase.Game.GetTimeFromBeats(Medley.EndBeat, BPM); + bool foundEnd = CBase.Game.GetTimeFromBeats(Medley.EndBeat, BPM) - CBase.Game.GetTimeFromBeats(Medley.StartBeat, BPM) < CBase.Settings.GetMedleyMinDuration(); - // set end if duration > MedleyMinDuration + // set end if duration < MedleyMinDuration if (!foundEnd) { - for (int i = series[longest].Start + 1; i < voice.NumLines - 1; i++) + for (int i = series[longest].End + 1; i < voice.NumLines - 1; i++) { - if (CBase.Game.GetTimeFromBeats(Medley.StartBeat, BPM) + CBase.Settings.GetMedleyMinDuration() > - CBase.Game.GetTimeFromBeats(voice.Lines[i].LastNoteBeat, BPM)) + if (CBase.Game.GetTimeFromBeats(voice.Lines[i].LastNoteBeat, BPM) - CBase.Game.GetTimeFromBeats(Medley.StartBeat, BPM) < + CBase.Settings.GetMedleyMinDuration()) { foundEnd = true; Medley.EndBeat = voice.Lines[i].LastNoteBeat; + break; } } } if (foundEnd) { - Medley.Source = EMedleySource.Calculated; + Medley.Source = EDataSource.Calculated; Medley.FadeInTime = CBase.Settings.GetDefaultMedleyFadeInTime(); Medley.FadeOutTime = CBase.Settings.GetDefaultMedleyFadeOutTime(); } } - if (Math.Abs(PreviewStart) < 0.001) + if (Preview.Source == EDataSource.None) { - if (Medley.Source == EMedleySource.Calculated) - PreviewStart = CBase.Game.GetTimeFromBeats(Medley.StartBeat, BPM); + if (Medley.Source != EDataSource.None) + Preview.StartTime = CBase.Game.GetTimeFromBeats(Medley.StartBeat, BPM); } } private void _FindShortEnd() { + if (ShortEnd.Source != EDataSource.None) + return; + List series = _GetSeries(); if (series == null) return; @@ -461,10 +483,10 @@ namespace VocaluxeLib.Songs { if (stop < (voice.Lines[series[i].Start].FirstNoteBeat + ((voice.Lines[series[i].End].LastNoteBeat - voice.Lines[series[i].Start].FirstNoteBeat) / 2))) { - ShortEnd = voice.Lines[series[i].Start - 1].LastNote.EndBeat; + ShortEnd.EndBeat = voice.Lines[series[i].Start - 1].LastNote.EndBeat; return; } - ShortEnd = voice.Lines[series[i].End].LastNote.EndBeat; + ShortEnd.EndBeat = voice.Lines[series[i].End].LastNote.EndBeat; return; } } @@ -474,12 +496,13 @@ namespace VocaluxeLib.Songs { if (line.FirstNoteBeat < stop && line.LastNoteBeat > stop) { - ShortEnd = line.LastNoteBeat; + ShortEnd.EndBeat = line.LastNoteBeat; return; } } - ShortEnd = stop; + ShortEnd.EndBeat = stop; + ShortEnd.Source = EDataSource.Calculated; } } } \ No newline at end of file diff --git a/VocaluxeLib/Songs/CSongLine.cs b/VocaluxeLib/Songs/CSongLine.cs index dd6787f6..4dffe501 100644 --- a/VocaluxeLib/Songs/CSongLine.cs +++ b/VocaluxeLib/Songs/CSongLine.cs @@ -82,12 +82,12 @@ namespace VocaluxeLib.Songs //Check for overlapping notes if (insPos >= 0) //Check note before { - if (_Notes[insPos].EndBeat > note.StartBeat) + if (_Notes[insPos].EndBeat >= note.StartBeat) return false; } if (insPos < _Notes.Count - 1) //Check note after { - if (_Notes[insPos + 1].StartBeat < note.EndBeat) + if (_Notes[insPos + 1].StartBeat <= note.EndBeat) return false; } _Notes.Insert(insPos + 1, note); diff --git a/VocaluxeLib/Songs/CSongLoader.cs b/VocaluxeLib/Songs/CSongLoader.cs index 0720be1a..a3b2735a 100644 --- a/VocaluxeLib/Songs/CSongLoader.cs +++ b/VocaluxeLib/Songs/CSongLoader.cs @@ -77,7 +77,7 @@ namespace VocaluxeLib.Songs _LogMsg(msg, false, withLineNr); } - public bool ReadHeader(bool ignoreSetEncoding = false) + public bool ReadHeader(bool useSetEncoding = false) { string filePath = Path.Combine(_Song.Folder, _Song.FileName); @@ -89,13 +89,17 @@ namespace VocaluxeLib.Songs _Song.UnknownTags.Clear(); _Song._Comment = ""; _Song.ManualEncoding = false; + _Song.Medley.Source = EDataSource.None; + _Song._CalculateMedley = false; + _Song.Preview.Source = EDataSource.None; + _Song.ShortEnd.Source = EDataSource.None; var headerFlags = new EHeaderFlags(); StreamReader sr = null; _LineNr = 0; try { - sr = new StreamReader(filePath, _Song.Encoding, true); + sr = useSetEncoding ? new StreamReader(filePath, _Song.Encoding, true) : new StreamReader(filePath, true); while (!sr.EndOfStream) { string line = sr.ReadLine(); @@ -134,7 +138,7 @@ namespace VocaluxeLib.Songs _Song.ManualEncoding = true; if (!newEncoding.Equals(sr.CurrentEncoding)) { - if (ignoreSetEncoding) + if (useSetEncoding) { _LogWarning("Duplicate encoding ignored"); continue; @@ -268,17 +272,17 @@ namespace VocaluxeLib.Songs _LogWarning("Invalid end"); break; case "PREVIEWSTART": - if (CHelper.TryParse(value, out _Song.PreviewStart) && _Song.PreviewStart >= 0f) - headerFlags |= EHeaderFlags.PreviewStart; + if (CHelper.TryParse(value, out _Song.Preview.StartTime) && _Song.Preview.StartTime >= 0f) + _Song.Preview.Source = EDataSource.Tag; else _LogWarning("Invalid previewstart"); break; case "PREVIEW": - if (CHelper.TryParse(value, out _Song.PreviewStart) && _Song.PreviewStart >= 0f) + if (CHelper.TryParse(value, out _Song.Preview.StartTime) && _Song.Preview.StartTime >= 0f) { //This is stored in ms not like PREVIEWSTART! - _Song.PreviewStart /= 1000f; - headerFlags |= EHeaderFlags.PreviewStart; + _Song.Preview.StartTime /= 1000f; + _Song.Preview.Source = EDataSource.Tag; } else _LogWarning("Invalid previewstart"); @@ -295,6 +299,19 @@ namespace VocaluxeLib.Songs else _LogWarning("Invalid medleyendbeat"); break; + case "ENDSHORT": + if ((headerFlags & EHeaderFlags.BPM) != 0) + { + int endTime; + if (int.TryParse(value, out endTime) || endTime < 0) + { + _Song.ShortEnd.EndBeat = (int)CBase.Game.GetBeatFromTime(endTime / 1000f, _Song.BPM, _Song.Gap); + _Song.ShortEnd.Source = EDataSource.Tag; + } + else + _LogWarning("Invalid medleyendbeat"); + } + break; case "CALCMEDLEY": if (value.ToUpper() == "OFF") _Song._CalculateMedley = false; @@ -373,15 +390,15 @@ namespace VocaluxeLib.Songs } } - if ((headerFlags & EHeaderFlags.PreviewStart) == 0 || _Song.PreviewStart < 0) + if (_Song.Preview.Source == EDataSource.None) { //PreviewStart is not set or <=0 - _Song.PreviewStart = (headerFlags & EHeaderFlags.MedleyStartBeat) != 0 ? CBase.Game.GetTimeFromBeats(_Song.Medley.StartBeat, _Song.BPM) : 0f; + _Song.Preview.StartTime = (headerFlags & EHeaderFlags.MedleyStartBeat) != 0 ? CBase.Game.GetTimeFromBeats(_Song.Medley.StartBeat, _Song.BPM) : 0f; } if ((headerFlags & EHeaderFlags.MedleyStartBeat) != 0 && (headerFlags & EHeaderFlags.MedleyEndBeat) != 0) { - _Song.Medley.Source = EMedleySource.Tag; + _Song.Medley.Source = EDataSource.Tag; _Song.Medley.FadeInTime = CBase.Settings.GetDefaultMedleyFadeInTime(); _Song.Medley.FadeOutTime = CBase.Settings.GetDefaultMedleyFadeOutTime(); } @@ -394,6 +411,7 @@ namespace VocaluxeLib.Songs _LogError("Error reading txt header" + e.Message, false); return false; } + _Song.Encoding = sr.CurrentEncoding; sr.Dispose(); _Song._CheckFiles(); @@ -485,7 +503,7 @@ namespace VocaluxeLib.Songs StreamReader sr = null; try { - sr = new StreamReader(filePath, _Song.Encoding); + sr = new StreamReader(filePath, _Song.Encoding, true); _Song.Notes.Reset(); @@ -544,8 +562,8 @@ namespace VocaluxeLib.Songs sr.Dispose(); return false; } - string text = noteData[3]; - if (text.Trim() == "") + string text = noteData[3].TrimMultipleWs(); + if (text == "") { _LogWarning("Ignored note without text"); changesMade.NoTextNoteCt++; @@ -579,7 +597,6 @@ namespace VocaluxeLib.Songs if (_Song.Relative) beat += currentBeat; - bool ignored = false; foreach (int curPlayer in player.GetSetBits()) { @@ -697,10 +714,7 @@ namespace VocaluxeLib.Songs string msg = "Automatic changes have been made to " + filePath + " Please check result!\r\n" + changesMade; CBase.Log.LogError("Warning:" + msg); if (CBase.Config.GetSaveModifiedSongs() == EOffOn.TR_CONFIG_ON) - { - string name = Path.GetFileNameWithoutExtension(_Song.FileName); - _Song.Save(Path.Combine(_Song.Folder, name + ".fix.txt")); - } + _Song.Save(filePath + ".fix"); } return true; } diff --git a/VocaluxeLib/Songs/CSongWriter.cs b/VocaluxeLib/Songs/CSongWriter.cs index 73c2ecc5..89d628d6 100644 --- a/VocaluxeLib/Songs/CSongWriter.cs +++ b/VocaluxeLib/Songs/CSongWriter.cs @@ -34,6 +34,12 @@ namespace VocaluxeLib.Songs _WriteHeaderEntry(id, value.ToString()); } + private void _WriteHeaderEntry(string id, int value, int def = 0) + { + if (value != def) + _WriteHeaderEntry(id, value.ToString()); + } + private void _WriteHeaderEntrys(string id, ICollection value) { if (value == null || value.Count <= 0) @@ -76,12 +82,15 @@ namespace VocaluxeLib.Songs _WriteHeaderEntry("RELATIVE", _Song.Relative); _WriteHeaderEntry("BPM", _Song.BPM / _BPMFactor); _WriteHeaderEntry("GAP", _Song.Gap * 1000f); - _WriteHeaderEntry("PREVIEWSTART", _Song.PreviewStart); + if (_Song.Preview.Source == EDataSource.Tag) + _WriteHeaderEntry("PREVIEWSTART", _Song.Preview.StartTime); _WriteHeaderEntry("START", _Song.Start); _WriteHeaderEntry("END", _Song.Finish * 1000f); - if (!_Song._CalculateMedley) + if (_Song.ShortEnd.Source == EDataSource.Tag) + _WriteHeaderEntry("ENDSHORT", (int)(CBase.Game.GetTimeFromBeats(_Song.ShortEnd.EndBeat, _Song.BPM) + _Song.Gap) * 1000); + if (_Song.Medley.Source == EDataSource.None) _WriteHeaderEntry("CALCMEDLEY", "OFF"); - if (_Song.Medley.Source == EMedleySource.Tag) + if (_Song.Medley.Source == EDataSource.Tag) { _WriteHeaderEntry("MEDLEYSTARTBEAT", _Song.Medley.StartBeat); _WriteHeaderEntry("MEDLEYENDBEAT", _Song.Medley.EndBeat); @@ -139,6 +148,7 @@ namespace VocaluxeLib.Songs } } } + tw.WriteLine("E"); } public bool SaveFile(string filePath)