diff --git a/PartyModes/PartyModeChallenge/CPartyScreenChallengeMain.cs b/PartyModes/PartyModeChallenge/CPartyScreenChallengeMain.cs index 5e10bcff..77a5eb88 100644 --- a/PartyModes/PartyModeChallenge/CPartyScreenChallengeMain.cs +++ b/PartyModes/PartyModeChallenge/CPartyScreenChallengeMain.cs @@ -125,6 +125,7 @@ namespace VocaluxeLib.PartyModes.Challenge _AddText(_NextPlayerTexts[_NextPlayerTexts.Count - 1]); _NextPlayerStatics.Add(GetNewStatic(_Statics[_StaticNextPlayer])); _AddStatic(_NextPlayerStatics[_NextPlayerStatics.Count - 1]); + _NextPlayerStatics[_NextPlayerStatics.Count - 1].Aspect = EAspect.Crop; } _Statics[_StaticNextPlayer].Visible = false; } diff --git a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs index 6f7eab3c..a0ec0798 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs @@ -98,6 +98,9 @@ namespace VocaluxeLib.PartyModes.TicTacToe _CreateFields(); _Buttons[_ButtonField].Visible = false; + + _Statics[_StaticAvatarT1].Aspect = EAspect.Crop; + _Statics[_StaticAvatarT2].Aspect = EAspect.Crop; } public override bool HandleInput(SKeyEvent keyEvent) diff --git a/Vocaluxe/Base/CBackgroundMusic.cs b/Vocaluxe/Base/CBackgroundMusic.cs index 65165cf4..f9146f12 100644 --- a/Vocaluxe/Base/CBackgroundMusic.cs +++ b/Vocaluxe/Base/CBackgroundMusic.cs @@ -51,6 +51,7 @@ namespace Vocaluxe.Base private static Task _PreviewStartHelperTask; private static int _PreviewStartWaitCounter; private const int _PreviewStartWaitMaxTries = 10; + private static readonly object _PreviewStartHelperTaskLock = new Object(); public static bool VideoEnabled { @@ -256,10 +257,17 @@ namespace Vocaluxe.Base { if (_PreviewStartHelperTask != null && ( _PreviewPlayer.Length > 0 || _PreviewStartWaitCounter++ >= _PreviewStartWaitMaxTries)) { - _PreviewStartHelperTask.RunSynchronously(TaskScheduler.FromCurrentSynchronizationContext()); - _PreviewStartHelperTask.Dispose(); - _PreviewStartHelperTask = null; - _PreviewStartWaitCounter = 0; + lock (_PreviewStartHelperTaskLock) + { + // Recheck the condition as it cloud have change before we got the lock + if (_PreviewStartHelperTask != null && (_PreviewPlayer.Length > 0 || _PreviewStartWaitCounter++ >= _PreviewStartWaitMaxTries)) + { + _PreviewStartHelperTask.RunSynchronously(TaskScheduler.FromCurrentSynchronizationContext()); + _PreviewStartHelperTask.Dispose(); + _PreviewStartHelperTask = null; + _PreviewStartWaitCounter = 0; + } + } } if (!IsPlaying) @@ -317,28 +325,46 @@ namespace Vocaluxe.Base //Change song position only if song is changed or near to end if (songChanged || _CurPlayer.Position + 30 < _CurPlayer.Length) { - _PreviewStartHelperTask = new Task(() => + lock (_PreviewStartHelperTaskLock) { - float length = _PreviewPlayer.Length; - if (length < 1) - length = 30; // If length is unknow or invalid assume a length of 30s + // Check if the old _PreviewStartHelperTask needs to disposed + if (_PreviewStartHelperTask != null) + { + _PreviewStartHelperTask.Dispose(); + } + _PreviewStartHelperTask = new Task(() => + { + 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(); - }); + _PreviewPlayer.Position = start; + Play(); + }); + } _CurPlayer = _PreviewPlayer; } else { - _PreviewStartHelperTask.Dispose(); - _PreviewStartHelperTask = null; + if (_PreviewStartHelperTask != null) + { + lock (_PreviewStartHelperTaskLock) + { + // Recheck the condition as it cloud have change before we got the lock + if (_PreviewStartHelperTask != null) + { + _PreviewStartHelperTask.Dispose(); + _PreviewStartHelperTask = null; + } + } + } _PreviewPlayer.Position = _CurPlayer.Position; _CurPlayer = _PreviewPlayer; Play(); diff --git a/Vocaluxe/Base/CConfig.cs b/Vocaluxe/Base/CConfig.cs index d80e0024..f3b776a3 100644 --- a/Vocaluxe/Base/CConfig.cs +++ b/Vocaluxe/Base/CConfig.cs @@ -236,13 +236,14 @@ namespace Vocaluxe.Base public static event OnSongMenuChanged SongMenuChanged; //Folders + //We need full path for folders for matching folder path with textfile path when loading public static readonly List SongFolders = new List { #if INSTALLER Path.Combine(CSettings.DataFolder, CSettings.FolderNameSongs), - CSettings.FolderNameSongs + Path.Combine(CSettings.ProgramFolder, FolderNameSongs) #elif WIN - CSettings.FolderNameSongs + Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameSongs) #elif LINUX Path.Combine(CSettings.DataFolder, CSettings.FolderNameSongs) #endif @@ -380,15 +381,7 @@ namespace Vocaluxe.Base else Config = xml.DeserializeString(""); - if (Config.Game.SongFolder.Length > 0 && Config.Game.SongFolder[0] != "") - { - SongFolders.Clear(); - SongFolders.AddRange(Config.Game.SongFolder); - } - else - { - Config.Game.SongFolder = SongFolders.ToArray(); - } + NormalizeSongPaths(); if (Config.Game.MinLineBreakTime < 0) Config.Game.MinLineBreakTime = 0.1f; @@ -680,6 +673,29 @@ namespace Vocaluxe.Base return false; } + /// + /// Set song path if none is find in config and check if every path exists + /// + public static void NormalizeSongPaths() + { + //Check if there are configured songfolders + if (Config.Game.SongFolder.Length > 0 && Config.Game.SongFolder[0] != "") + { + SongFolders.Clear(); + + foreach (string folder in Config.Game.SongFolder) + { + //Check if folder exists + if (Directory.Exists(folder)) + SongFolders.Add(folder); + } + } + + //Test if songfolders are still empty or now empty + if(Config.Game.SongFolder.Length == 0) + Config.Game.SongFolder = SongFolders.ToArray(); + } + /// /// Load command-line-parameters and their values to lists. /// diff --git a/Vocaluxe/Base/CMain.cs b/Vocaluxe/Base/CMain.cs index 41f79bb2..6038c266 100644 --- a/Vocaluxe/Base/CMain.cs +++ b/Vocaluxe/Base/CMain.cs @@ -837,7 +837,14 @@ namespace Vocaluxe.Base public void Close(ref CVideoStream stream) { - CVideo.Close(ref stream); + try + { + CVideo.Close(ref stream); + } + catch (NotSupportedException e) + { + CLog.LogError($"Clould not close the background video: {e.Message}"); + } } public void SetLoop(CVideoStream stream, bool loop = true) @@ -847,12 +854,26 @@ namespace Vocaluxe.Base public void Pause(CVideoStream stream) { - CVideo.Pause(stream); + try + { + CVideo.Pause(stream); + } + catch (NotSupportedException e) + { + CLog.LogError($"Clould not pause the background video: {e.Message}"); + } } public void Resume(CVideoStream stream) { - CVideo.Resume(stream); + try + { + CVideo.Resume(stream); + } + catch (NotSupportedException e) + { + CLog.LogError($"Clould not resume the background video: {e.Message}"); + } } } diff --git a/Vocaluxe/Base/CVideo.cs b/Vocaluxe/Base/CVideo.cs index d9400cc8..d9af124b 100644 --- a/Vocaluxe/Base/CVideo.cs +++ b/Vocaluxe/Base/CVideo.cs @@ -15,6 +15,7 @@ // along with Vocaluxe. If not, see . #endregion +using System; using Vocaluxe.Lib.Video; using VocaluxeLib; @@ -61,6 +62,10 @@ namespace Vocaluxe.Base public static CVideoStream Load(string videoFileName) { + if (_VideoDecoder == null) + { + throw new NotSupportedException("_VideoDecoder is null (already closed?)"); + } return _VideoDecoder.Load(videoFileName); } @@ -73,41 +78,109 @@ namespace Vocaluxe.Base public static float GetLength(CVideoStream stream) { + if (stream == null) + { + throw new ArgumentException("stream is null"); + } + if (_VideoDecoder == null) + { + throw new NotSupportedException("_VideoDecoder is null (already closed?)"); + } + return _VideoDecoder.GetLength(stream); } public static bool GetFrame(CVideoStream stream, float time) { + if (stream == null) + { + throw new ArgumentException("stream is null"); + } + if (_VideoDecoder == null) + { + throw new NotSupportedException("_VideoDecoder is null (already closed?)"); + } + return _VideoDecoder.GetFrame(stream, time); } public static bool Skip(CVideoStream stream, float start, float gap) { + if (stream == null) + { + throw new ArgumentException("stream is null"); + } + if (_VideoDecoder == null) + { + throw new NotSupportedException("_VideoDecoder is null (already closed?)"); + } + return _VideoDecoder.Skip(stream, start, gap); } public static void SetLoop(CVideoStream stream, bool loop) { + if (stream == null) + { + throw new ArgumentException("stream is null"); + } + if (_VideoDecoder == null) + { + throw new NotSupportedException("_VideoDecoder is null (already closed?)"); + } + _VideoDecoder.SetLoop(stream, loop); } public static void Pause(CVideoStream stream) { + if (stream == null) + { + throw new ArgumentException("stream is null"); + } + if (_VideoDecoder == null) + { + throw new NotSupportedException("_VideoDecoder is null (already closed?)"); + } + _VideoDecoder.Pause(stream); } public static void Resume(CVideoStream stream) { + if (stream == null) + { + throw new ArgumentException("stream is null"); + } + if (_VideoDecoder == null) + { + throw new NotSupportedException("_VideoDecoder is null (already closed?)"); + } + _VideoDecoder.Resume(stream); } public static bool Finished(CVideoStream stream) { + if (stream == null) + { + throw new ArgumentException("stream is null"); + } + if (_VideoDecoder == null) + { + throw new NotSupportedException("_VideoDecoder is null (already closed?)"); + } + return _VideoDecoder.Finished(stream); } public static void Update() { + if (_VideoDecoder == null) + { + throw new NotSupportedException("_VideoDecoder is null (already closed?)"); + } + _VideoDecoder.Update(); } #endregion Interface diff --git a/Vocaluxe/Base/CVideoPlayer.cs b/Vocaluxe/Base/CVideoPlayer.cs index 3e0762f6..1f451396 100644 --- a/Vocaluxe/Base/CVideoPlayer.cs +++ b/Vocaluxe/Base/CVideoPlayer.cs @@ -53,6 +53,10 @@ namespace Vocaluxe.Base { _VideoTimer.Reset(); _Finished = false; + if (_VideoStream == null) + { + return; + } //CVideo.VdSkip(_VideoStream, 0f, 0f); _VideoTimer.Start(); CVideo.Resume(_VideoStream); @@ -60,12 +64,19 @@ namespace Vocaluxe.Base public void Pause() { - CVideo.Pause(_VideoStream); + if (_VideoStream != null) + { + CVideo.Pause(_VideoStream); + } _VideoTimer.Stop(); } public void Resume() { + if (_VideoStream == null) + { + return; + } CVideo.Resume(_VideoStream); _VideoTimer.Start(); } @@ -92,7 +103,7 @@ namespace Vocaluxe.Base public void PreLoad() { - if (!_Loaded) + if (!_Loaded || _VideoStream == null) { return; } @@ -111,7 +122,10 @@ namespace Vocaluxe.Base public void Close() { - CVideo.Close(ref _VideoStream); + if (_VideoStream != null) + { + CVideo.Close(ref _VideoStream); + } _Loaded = false; _Finished = false; _VideoTimer.Reset(); diff --git a/Vocaluxe/Lib/Sound/CPortAudioHandle.cs b/Vocaluxe/Lib/Sound/CPortAudioHandle.cs index 217afafa..81c4d9b0 100644 --- a/Vocaluxe/Lib/Sound/CPortAudioHandle.cs +++ b/Vocaluxe/Lib/Sound/CPortAudioHandle.cs @@ -74,12 +74,23 @@ namespace Vocaluxe.Lib.Sound } lock (_Mutex) { + if (_Disposed) + return; Debug.Assert(_RefCount > 0); _RefCount--; if (_RefCount == 0) - PortAudio.Pa_Terminate(); + { + try + { + PortAudio.Pa_Terminate(); + } + catch (Exception ex) + { + CLog.LogError(errorText: $"Error disposing PortAudio: {ex.Message}", e: ex); + } + } + _Disposed = true; } - _Disposed = true; } public void Dispose() @@ -100,11 +111,11 @@ namespace Vocaluxe.Lib.Sound double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags, PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData) { - if (_Disposed) - throw new ObjectDisposedException("PortAudioHandle already disposed"); - lock (_Mutex) { + if (_Disposed) + throw new ObjectDisposedException("PortAudioHandle already disposed"); + PortAudio.PaError res = PortAudio.Pa_OpenStream(out stream, ref inputParameters, ref outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData); if (res == PortAudio.PaError.paNoError) @@ -157,12 +168,19 @@ namespace Vocaluxe.Lib.Sound public void CloseStream(IntPtr stream) { - if (_Disposed) - throw new ObjectDisposedException("PortAudioHandle already disposed"); - lock (_Mutex) { - PortAudio.Pa_CloseStream(stream); + if (_Disposed) + throw new ObjectDisposedException("PortAudioHandle already disposed"); + + try + { + PortAudio.Pa_CloseStream(stream); + } + catch (Exception ex) + { + CLog.LogError(errorText:$"Error closing stream: {ex.Message}", e:ex); + } _Streams.Remove(stream); } } diff --git a/Vocaluxe/Lib/Sound/Record/PortAudio/CPortAudioRecord.cs b/Vocaluxe/Lib/Sound/Record/PortAudio/CPortAudioRecord.cs index 4702e400..cfc8818c 100644 --- a/Vocaluxe/Lib/Sound/Record/PortAudio/CPortAudioRecord.cs +++ b/Vocaluxe/Lib/Sound/Record/PortAudio/CPortAudioRecord.cs @@ -16,6 +16,8 @@ #endregion using System; +using System.Collections.Generic; +using System.Linq; using System.Runtime.InteropServices; using System.Threading; using Vocaluxe.Base; @@ -142,9 +144,13 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio foreach (IntPtr handle in _RecHandle) { - PortAudioSharp.PortAudio.Pa_StopStream(handle); - PortAudioSharp.PortAudio.Pa_CloseStream(handle); + if (handle != IntPtr.Zero) + { + PortAudioSharp.PortAudio.Pa_StopStream(handle); + PortAudioSharp.PortAudio.Pa_CloseStream(handle); + } } + _RecHandle = new IntPtr[_Devices.Count]; return true; } @@ -153,13 +159,17 @@ namespace Vocaluxe.Lib.Sound.Record.PortAudio /// public override void Close() { - if (_RecHandle != null) + if (_RecHandle != null && _RecHandle.Length > 0) { foreach (IntPtr handle in _RecHandle) { if (handle != IntPtr.Zero) + { _PaHandle.CloseStream(handle); + } } + + _RecHandle = new IntPtr[_Devices.Count]; } if (_PaHandle != null) { diff --git a/Vocaluxe/Lib/Video/Acinerella/CDecoderThread.cs b/Vocaluxe/Lib/Video/Acinerella/CDecoderThread.cs index 38275210..3d7229d0 100644 --- a/Vocaluxe/Lib/Video/Acinerella/CDecoderThread.cs +++ b/Vocaluxe/Lib/Video/Acinerella/CDecoderThread.cs @@ -429,7 +429,18 @@ namespace Vocaluxe.Lib.Video.Acinerella private bool _CopyDecodedFrameToBuffer() { bool result; - var decoder = (SACDecoder)Marshal.PtrToStructure(_Videodecoder, typeof(SACDecoder)); + SACDecoder decoder; + + try + { + decoder = (SACDecoder)Marshal.PtrToStructure(_Videodecoder, typeof(SACDecoder)); + } + catch (Exception e) + { + CLog.LogError("Couldn't copy the frame to the managed environment.", false, false, e); + return false; + } + if (decoder.Buffer != IntPtr.Zero) { _LastDecodedTime = (float)decoder.Timecode; diff --git a/Vocaluxe/Program.cs b/Vocaluxe/Program.cs index d18660db..136508fd 100644 --- a/Vocaluxe/Program.cs +++ b/Vocaluxe/Program.cs @@ -285,23 +285,120 @@ namespace Vocaluxe try { CController.Close(); + } + catch (Exception e) + { + CLog.LogError("Error during shutdown! (CController)", false, false, e); + } + + try + { CVocaluxeServer.Close(); + } + catch (Exception e) + { + CLog.LogError("Error during shutdown! (CVocaluxeServer)", false, false, e); + } + + try + { CGraphics.Close(); + } + catch (Exception e) + { + CLog.LogError("Error during shutdown! (CGraphics)", false, false, e); + } + + try + { CThemes.Close(); + } + catch (Exception e) + { + CLog.LogError("Error during shutdown! (CThemes)", false, false, e); + } + + try + { CCover.Close(); + } + catch (Exception e) + { + CLog.LogError("Error during shutdown! (CCover)", false, false, e); + } + + try + { CFonts.Close(); + } + catch (Exception e) + { + CLog.LogError("Error during shutdown! (CFonts)", false, false, e); + } + + try + { CBackgroundMusic.Close(); + } + catch (Exception e) + { + CLog.LogError("Error during shutdown! (CBackgroundMusic)", false, false, e); + } + + try + { CWebcam.Close(); + } + catch (Exception e) + { + CLog.LogError("Error during shutdown! (CWebcam)", false, false, e); + } + + try + { CDataBase.Close(); + } + catch (Exception e) + { + CLog.LogError("Error during shutdown! (CDataBase)", false, false, e); + } + + try + { CVideo.Close(); + } + catch (Exception e) + { + CLog.LogError("Error during shutdown! (CVideo)", false, false, e); + } + + try + { CRecord.Close(); + } + catch (Exception e) + { + CLog.LogError("Error during shutdown! (CRecord)", false, false, e); + } + + try + { CSound.Close(); + } + catch (Exception e) + { + CLog.LogError("Error during shutdown! (CSound)", false, false, e); + } + + try + { CDraw.Close(); } catch (Exception e) { - CLog.LogError("Error during shutdown!", false, false, e); + CLog.LogError("Error during shutdown! (CDraw)", false, false, e); } + GC.Collect(); // Do a GC run here before we close logs to have finalizers run try { diff --git a/Vocaluxe/Screens/CScreenScore.cs b/Vocaluxe/Screens/CScreenScore.cs index 33bc3983..c9b77e4d 100644 --- a/Vocaluxe/Screens/CScreenScore.cs +++ b/Vocaluxe/Screens/CScreenScore.cs @@ -138,6 +138,9 @@ namespace Vocaluxe.Screens _SetVisibility(); _UpdateRatings(); _SlideShowBG.Visible = _UpdateBackground(); + + for (int p = 0; p < CGame.NumPlayers; p++) + _Statics[_StaticAvatar[p, CGame.NumPlayers - 1]].Aspect = EAspect.Crop; } public override bool UpdateGame() diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs index 4c37016e..a7508f67 100644 --- a/Vocaluxe/Screens/CScreenSing.cs +++ b/Vocaluxe/Screens/CScreenSing.cs @@ -220,8 +220,6 @@ namespace Vocaluxe.Screens CConfig.Config.Theme.PlayerInfo = (EPlayerInfo)mode; CConfig.SaveConfig(); _SetVisibility(); - if (CGame.GetSong() != null) - _SetDuetLyricsVisibility(CGame.GetSong().IsDuet); //make sure duet lyrics remain visible break; case Keys.S: @@ -634,7 +632,6 @@ namespace Vocaluxe.Screens for (int p = 0; p < CGame.NumPlayers; p++) _ProgressBars[_PlayerProgressBarRating[p]].Reset(); - _SetDuetLyricsVisibility(song.IsDuet); _SetNormalLyricsVisibility(); _TimerSongText.Reset(); @@ -647,37 +644,36 @@ namespace Vocaluxe.Screens _StartSong(); } - private void _SetDuetLyricsVisibility(bool isDuet) - { - _Statics[_StaticLyricsDuet].Visible = isDuet; - _Lyrics[_LyricMainDuet].Visible = isDuet; - _Lyrics[_LyricSubDuet].Visible = isDuet; - - if (isDuet) - { - _Lyrics[_LyricMainTop].Visible = false; - _Lyrics[_LyricSubTop].Visible = false; - _Statics[_StaticLyricsTop].Visible = false; - } - else - { - bool lyricsOnTop = CConfig.Config.Game.LyricsPosition == ELyricsPosition.TR_CONFIG_LYRICSPOSITION_TOP - || CConfig.Config.Game.LyricsPosition == ELyricsPosition.TR_CONFIG_LYRICSPOSITION_BOTH - || (CConfig.Config.Game.LyricsPosition == ELyricsPosition.TR_CONFIG_LYRICSPOSITION_DYNAMIC && _DynamicLyricsTop); - _Lyrics[_LyricMainTop].Visible = lyricsOnTop; - _Lyrics[_LyricSubTop].Visible = lyricsOnTop; - _Statics[_StaticLyricsTop].Visible = lyricsOnTop; - } - } - private void _SetNormalLyricsVisibility() { - bool visible = CConfig.Config.Game.LyricsPosition == ELyricsPosition.TR_CONFIG_LYRICSPOSITION_BOTTOM + bool bottomLyricsVisible = CConfig.Config.Game.LyricsPosition == ELyricsPosition.TR_CONFIG_LYRICSPOSITION_BOTTOM || CConfig.Config.Game.LyricsPosition == ELyricsPosition.TR_CONFIG_LYRICSPOSITION_BOTH || (CConfig.Config.Game.LyricsPosition == ELyricsPosition.TR_CONFIG_LYRICSPOSITION_DYNAMIC && _DynamicLyricsBottom); - _Lyrics[_LyricMain].Visible = visible; - _Lyrics[_LyricSub].Visible = visible; - _Statics[_StaticLyrics].Visible = visible; + + bool topLyricsVisible = CConfig.Config.Game.LyricsPosition == ELyricsPosition.TR_CONFIG_LYRICSPOSITION_TOP + || CConfig.Config.Game.LyricsPosition == ELyricsPosition.TR_CONFIG_LYRICSPOSITION_BOTH + || (CConfig.Config.Game.LyricsPosition == ELyricsPosition.TR_CONFIG_LYRICSPOSITION_DYNAMIC && _DynamicLyricsTop); + + bool duetLyricsVisible = false; + + if (CGame.GetSong() != null && CGame.GetSong().IsDuet) + { + bottomLyricsVisible = true; + topLyricsVisible = false; + duetLyricsVisible = true; + } + + _Lyrics[_LyricMain].Visible = bottomLyricsVisible; + _Lyrics[_LyricSub].Visible = bottomLyricsVisible; + _Statics[_StaticLyrics].Visible = bottomLyricsVisible; + + _Lyrics[_LyricMainTop].Visible = topLyricsVisible; + _Lyrics[_LyricSubTop].Visible = topLyricsVisible; + _Statics[_StaticLyricsTop].Visible = topLyricsVisible; + + _Lyrics[_LyricMainDuet].Visible = duetLyricsVisible; + _Lyrics[_LyricSubDuet].Visible = duetLyricsVisible; + _Statics[_StaticLyricsDuet].Visible = duetLyricsVisible; } private void _StartSong() diff --git a/VocaluxeLib/Menu/CSelectSlide.cs b/VocaluxeLib/Menu/CSelectSlide.cs index ee1765fc..33e4caa9 100644 --- a/VocaluxeLib/Menu/CSelectSlide.cs +++ b/VocaluxeLib/Menu/CSelectSlide.cs @@ -469,6 +469,7 @@ namespace VocaluxeLib.Menu Text = new CText(0, 0, 0, _TextH, _MaxW, EAlignment.Center, _Theme.TextStyle, _Theme.TextFont, _TextColor, "T", _PartyModeID), Img = new CStatic(_PartyModeID) }; + el.Img.Aspect = EAspect.Crop; _VisibleElements.Add(el); } } diff --git a/VocaluxeLib/Profile/CProfile.cs b/VocaluxeLib/Profile/CProfile.cs index 2e168b97..828c2f1c 100644 --- a/VocaluxeLib/Profile/CProfile.cs +++ b/VocaluxeLib/Profile/CProfile.cs @@ -67,7 +67,7 @@ namespace VocaluxeLib.Profile { Avatar = CBase.Profiles.GetAvatarByFilename(value); if (Avatar == null) - throw new Exception("Avatar '" + value + "' not found"); + CBase.Log.LogError("Avatar '" + value + "' not found"); } }