diff --git a/ClientServerLib/ClientServerLib/CServer.cs b/ClientServerLib/ClientServerLib/CServer.cs index 57bbe01d..23a7e6fc 100644 --- a/ClientServerLib/ClientServerLib/CServer.cs +++ b/ClientServerLib/ClientServerLib/CServer.cs @@ -206,13 +206,12 @@ namespace ServerLib public static string GetLocalAddress() { IPAddress[] ips = Dns.GetHostAddresses(Dns.GetHostName()); - string IPAddress = ""; foreach (IPAddress ip in ips) { if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) - IPAddress = ip.ToString(); + return ip.ToString(); } - return IPAddress; + return ""; } #region server control diff --git a/Vocaluxe/Base/CBackgroundMusic.cs b/Vocaluxe/Base/CBackgroundMusic.cs index d92118d3..48c173a0 100644 --- a/Vocaluxe/Base/CBackgroundMusic.cs +++ b/Vocaluxe/Base/CBackgroundMusic.cs @@ -198,7 +198,7 @@ namespace Vocaluxe.Base timeToPlay = _CurrentPlaylistElement.Finish - CSound.GetPosition(_CurrentMusicStream); bool finished = CSound.IsFinished(_CurrentMusicStream); - if (IsPlaying && (timeToPlay <= CSettings.BackgroundMusicFadeTime || finished)) + if (IsPlaying && ((timeToPlay <= CSettings.BackgroundMusicFadeTime && timeToPlay > 0) || finished)) { if (_RepeatSong) { diff --git a/Vocaluxe/Base/CConfig.cs b/Vocaluxe/Base/CConfig.cs index b350c067..5f23e8c9 100644 --- a/Vocaluxe/Base/CConfig.cs +++ b/Vocaluxe/Base/CConfig.cs @@ -60,6 +60,11 @@ namespace Vocaluxe.Base public static int ScreenW = 1024; public static int ScreenH = 576; + public static int BorderLeft = 0; + public static int BorderRight = 0; + public static int BorderTop = 0; + public static int BorderBottom = 0; + public static EAntiAliasingModes AAMode = EAntiAliasingModes.X0; public static EOffOn VSync = EOffOn.TR_CONFIG_ON; @@ -183,6 +188,12 @@ namespace Vocaluxe.Base xmlReader.TryGetIntValue("//root/Graphics/ScreenW", ref ScreenW); xmlReader.TryGetIntValue("//root/Graphics/ScreenH", ref ScreenH); + + xmlReader.TryGetIntValue("//root/Graphics/BorderLeft", ref BorderLeft); + xmlReader.TryGetIntValue("//root/Graphics/BorderRight", ref BorderRight); + xmlReader.TryGetIntValue("//root/Graphics/BorderTop", ref BorderTop); + xmlReader.TryGetIntValue("//root/Graphics/BorderBottom", ref BorderBottom); + xmlReader.TryGetEnumValue("//root/Graphics/AAMode", ref AAMode); xmlReader.TryGetFloatValue("//root/Graphics/MaxFPS", ref MaxFPS); xmlReader.TryGetEnumValue("//root/Graphics/VSync", ref VSync); @@ -356,6 +367,12 @@ namespace Vocaluxe.Base writer.WriteElementString("ScreenW", ScreenW.ToString()); writer.WriteElementString("ScreenH", ScreenH.ToString()); + writer.WriteComment("Screen borders (pixels)"); + writer.WriteElementString("BorderLeft", BorderLeft.ToString()); + writer.WriteElementString("BorderRight", BorderRight.ToString()); + writer.WriteElementString("BorderTop", BorderTop.ToString()); + writer.WriteElementString("BorderBottom", BorderBottom.ToString()); + writer.WriteComment("AAMode: " + CHelper.ListStrings(Enum.GetNames(typeof(EAntiAliasingModes)))); writer.WriteElementString("AAMode", Enum.GetName(typeof(EAntiAliasingModes), AAMode)); diff --git a/Vocaluxe/Base/CGraphics.cs b/Vocaluxe/Base/CGraphics.cs index 91878e51..03dcbea8 100644 --- a/Vocaluxe/Base/CGraphics.cs +++ b/Vocaluxe/Base/CGraphics.cs @@ -378,6 +378,29 @@ namespace Vocaluxe.Base { CSettings.MouseInactive(); _Cursor.FadeOut(); + + if (keyEvent.ModAlt && keyEvent.ModCtrl && keyEvent.ModShift) + { + switch (keyEvent.Key) + { + case Keys.Left: + CConfig.BorderLeft -= 1; + CConfig.BorderRight -= 1; + CConfig.BorderTop -= 1; + CConfig.BorderBottom -= 1; + break; + case Keys.Right: + CConfig.BorderLeft += 1; + CConfig.BorderRight += 1; + CConfig.BorderTop += 1; + CConfig.BorderBottom += 1; + break; + default: + break; + } + CConfig.SaveConfig(); + break; + } } if (keyEvent.Key == Keys.F11) diff --git a/Vocaluxe/Lib/Draw/CDirect3D.cs b/Vocaluxe/Lib/Draw/CDirect3D.cs index d69d842e..7f3d3a4c 100644 --- a/Vocaluxe/Lib/Draw/CDirect3D.cs +++ b/Vocaluxe/Lib/Draw/CDirect3D.cs @@ -65,6 +65,11 @@ namespace Vocaluxe.Lib.Draw private int _Y; private int _X; + private int _BorderLeft = 0; + private int _BorderRight = 0; + private int _BorderTop = 0; + private int _BorderBottom = 0; + private CTexture _BlankTexture; private readonly Queue _Vertices = new Queue(); @@ -400,20 +405,15 @@ namespace Vocaluxe.Lib.Draw if (_Device.Disposed) return false; Text = CSettings.GetFullVersionText(); - SlimDX.Matrix translate = SlimDX.Matrix.Translation(new Vector3(-(float)CSettings.RenderW / 2, (float)CSettings.RenderH / 2, 0)); - SlimDX.Matrix projection = SlimDX.Matrix.OrthoOffCenterLH(-(float)CSettings.RenderW / 2, (float)CSettings.RenderW / 2, -(float)CSettings.RenderH / 2, - (float)CSettings.RenderH / 2, - CSettings.ZNear, CSettings.ZFar); + _AdjustNewBorders(); + _VertexBuffer = new VertexBuffer(_Device, CSettings.VertexBufferElements * (4 * Marshal.SizeOf(typeof(STexturedColoredVertex))), Usage.WriteOnly | Usage.Dynamic, VertexFormat.Position | VertexFormat.Texture1 | VertexFormat.Diffuse, Pool.Default); if (_Device.SetStreamSource(0, _VertexBuffer, 0, Marshal.SizeOf(typeof(STexturedColoredVertex))).IsFailure) CLog.LogError("Failed to set stream source"); _Device.VertexDeclaration = STexturedColoredVertex.GetDeclaration(_Device); - if (_Device.SetTransform(TransformState.Projection, projection).IsFailure) - CLog.LogError("Failed to set orthogonal matrix"); - if (_Device.SetTransform(TransformState.World, translate).IsFailure) - CLog.LogError("Failed to set translation matrix"); + if (_Device.SetRenderState(RenderState.CullMode, Cull.None).IsFailure) CLog.LogError("Failed to set cull mode"); if (_Device.SetRenderState(RenderState.AlphaBlendEnable, true).IsFailure) @@ -534,6 +534,18 @@ namespace Vocaluxe.Lib.Draw else _LeaveFullScreen(); } + + //Apply border changes + if (_BorderLeft != CConfig.BorderLeft || _BorderRight != CConfig.BorderRight || _BorderTop != CConfig.BorderTop || _BorderBottom != CConfig.BorderBottom) + { + _BorderLeft = CConfig.BorderLeft; + _BorderRight = CConfig.BorderRight; + _BorderTop = CConfig.BorderTop; + _BorderBottom = CConfig.BorderBottom; + + _AdjustNewBorders(); + } + if (CTime.IsRunning()) delay = (int)Math.Floor(CConfig.CalcCycleTime() - CTime.GetMilliseconds()); @@ -559,6 +571,20 @@ namespace Vocaluxe.Lib.Draw CLog.LogError("Failed to reset the device"); } + private void _AdjustNewBorders() + { + SlimDX.Matrix translate = SlimDX.Matrix.Translation(new Vector3(-(float)CSettings.RenderW / 2, (float)CSettings.RenderH / 2, 0)); + SlimDX.Matrix projection = SlimDX.Matrix.OrthoOffCenterLH( + -(float)CSettings.RenderW / 2 - _BorderLeft, (float)CSettings.RenderW / 2 + _BorderRight, + -(float)CSettings.RenderH / 2 - _BorderBottom, (float)CSettings.RenderH / 2 + _BorderTop, + CSettings.ZNear, CSettings.ZFar); + + if (_Device.SetTransform(TransformState.Projection, projection).IsFailure) + CLog.LogError("Failed to set orthogonal matrix"); + if (_Device.SetTransform(TransformState.World, translate).IsFailure) + CLog.LogError("Failed to set translation matrix"); + } + /// /// Unloads all Textures and other objects used by Direct3D for rendering /// diff --git a/Vocaluxe/Lib/Sound/CGstreamerSharpAudio.cs b/Vocaluxe/Lib/Sound/CGstreamerSharpAudio.cs index 6142e6f4..56ab9a53 100644 --- a/Vocaluxe/Lib/Sound/CGstreamerSharpAudio.cs +++ b/Vocaluxe/Lib/Sound/CGstreamerSharpAudio.cs @@ -169,7 +169,7 @@ namespace Vocaluxe.Lib.Sound public bool IsPaused(int stream) { if (!Streams.ContainsKey(stream)) - return true; + return false; return Streams[stream].Paused; } @@ -206,8 +206,8 @@ namespace Vocaluxe.Lib.Sound { private Element _Element; private bool _Loop; - public bool _Closed; - public bool _Finished; + public volatile bool _Closed; + public volatile bool _Finished; private bool _Fading; private bool _CloseStreamAfterFade; @@ -219,6 +219,10 @@ namespace Vocaluxe.Lib.Sound private float _Volume = 100f; public float _MaxVolume = 100f; + + private volatile float _Duration = -1f; + private volatile float _Position = 0f; + private volatile bool _QueryingDuration = false; public CGstreamerSharpAudioStream(string media, bool prescan) { var convert = ElementFactory.Make("audioconvert", "convert"); @@ -250,8 +254,14 @@ namespace Vocaluxe.Lib.Sound _Element["uri"] = new Uri(media).AbsoluteUri; _Element.SetState(State.Paused); - if (prescan) - _Element.Bus.TimedPopFiltered(0xffffffffffffffff, MessageType.AsyncDone); + // Passing CLOCK_TIME_NONE here causes the pipeline to block for a long time so with + // prescan enabled the pipeline will wait 500ms for stream to initialize and then continue + /*if (prescan) + { + var msg = _Element.Bus.TimedPopFiltered(100L * Constants.MSECOND, MessageType.DurationChanged); + if(msg.Handle != IntPtr.Zero) + UpdateDuration(); + }*/ } private void OnMessage(Message msg) @@ -269,7 +279,10 @@ namespace Vocaluxe.Lib.Sound string debug; msg.ParseError(out error, out debug); CLog.LogError("Gstreamer error: message" + error.Message + ", code" + error.Code + " ,debug information" + debug); - break; + break; + case MessageType.DurationChanged: + UpdateDuration(); + break; } msg.Unref(); } @@ -277,12 +290,21 @@ namespace Vocaluxe.Lib.Sound public void Close() { - if (_Element != null) + if (!_Closed) { - _Element.SetState(State.Null); + + _Closed = true; + _Finished = true; + var t = new System.Threading.Thread(TerminateStream); + t.Start(); } - _Closed = true; - _Finished = true; + + } + + private void TerminateStream() + { + if (_Element != null) + ; //_Element.SetState(State.Null); } public void Play(bool loop = false) @@ -356,11 +378,12 @@ namespace Vocaluxe.Lib.Sound { get { - long duration = 0; - if (_Element != null) - if (!_Element.QueryDuration(Format.Time, out duration)) - CLog.LogError("Could not query duration"); - return duration > 0 ? (duration / (long)Constants.SECOND) : 100; + if (_Duration < 0 && !_QueryingDuration) + { + var t = new System.Threading.Thread(UpdateDuration); + t.Start(); + } + return _Duration > 0 ? _Duration : -1; } } @@ -369,10 +392,11 @@ namespace Vocaluxe.Lib.Sound get { long position = 0; - if (_Element != null) - if (!_Element.QueryPosition(Format.Time, out position)) - CLog.LogError("Could not query position"); - return (float)(position / (double)Constants.SECOND); + if (!_Element.QueryPosition(Format.Time, out position)) + CLog.LogError("Could not query position"); + else + _Position = (float)(position / (double)Constants.SECOND); + return _Position; } set { @@ -385,7 +409,7 @@ namespace Vocaluxe.Lib.Sound { get { - return _Element != null ? _Element.CurrentState == State.Paused : true; + return _Element != null ? _Element.TargetState == State.Paused : true; } set { @@ -398,7 +422,7 @@ namespace Vocaluxe.Lib.Sound { get { - return _Element != null ? _Element.CurrentState == State.Playing : false; + return _Element != null ? _Element.TargetState == State.Playing : false; } set { @@ -436,6 +460,18 @@ namespace Vocaluxe.Lib.Sound } } } + + private void UpdateDuration() + { + _QueryingDuration = true; + long duration = -1; + while (duration < 0 && !_Closed && !_Finished && _Element != null) + { + if (_Element.QueryDuration(Format.Time, out duration)) + _Duration = (float)(duration / (long)Constants.SECOND); + } + _QueryingDuration = false; + } } } } diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs index 16ba478a..d7c2e618 100644 --- a/Vocaluxe/Screens/CScreenSing.cs +++ b/Vocaluxe/Screens/CScreenSing.cs @@ -94,6 +94,7 @@ namespace Vocaluxe.Screens private int _CurrentBeat; private int _CurrentStream = -1; + private float _Length = -1f; //private int _NextStream = -1; private const float _Volume = 100f; private int _CurrentVideo = -1; @@ -417,6 +418,7 @@ namespace Vocaluxe.Screens _CurrentBeat = -100; _CurrentTime = 0f; _FinishTime = 0f; + _Length = -1f; _TimeToFirstNote = 0f; _TimeToFirstNoteDuet = 0f; _Pause = false; @@ -1302,6 +1304,9 @@ namespace Vocaluxe.Screens totalTime -= song.Start; float currentTime = _CurrentTime - song.Start; + if (_Length < 0 && totalTime > 0) + _PrepareTimeLine(); + if (totalTime <= 0f) return; @@ -1382,6 +1387,8 @@ namespace Vocaluxe.Screens if (totalTime <= 0f) return; + _Length = totalTime; + foreach (CVoice voice in song.Notes.Voices) { foreach (CSongLine line in voice.Lines.Where(line => line.VisibleInTimeLine)) diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs index faea98cc..cc8d6575 100644 --- a/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs +++ b/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs @@ -58,6 +58,8 @@ namespace VocaluxeLib.Menu.SongMenu private bool _SmallView; + private float _Length = -1f; + public CSongMenuTileBoard(int partyModeID) : base(partyModeID) {} @@ -132,6 +134,9 @@ namespace VocaluxeLib.Menu.SongMenu for (int i = 0; i < _Tiles.Count; i++) _Tiles[i].Selected = _Locked == i + _Offset; } + + if (_Length < 0 && CBase.Sound.GetLength(_PreviewSongStream) > 0 && CBase.Songs.IsInCategory()) + UpdateLength(CBase.Songs.GetVisibleSong(_PreviewId)); } private void _UpdatePreview() @@ -145,6 +150,7 @@ namespace VocaluxeLib.Menu.SongMenu _VideoIcon.Visible = false; _MedleyCalcIcon.Visible = false; _MedleyTagIcon.Visible = false; + _Length = -1f; //Check if nothing is selected (for preview) if (_PreviewId < 0) @@ -173,14 +179,7 @@ namespace VocaluxeLib.Menu.SongMenu _MedleyCalcIcon.Visible = song.Medley.Source == EDataSource.Calculated; _MedleyTagIcon.Visible = song.Medley.Source == EDataSource.Tag; - float time = CBase.Sound.GetLength(_PreviewSongStream); - if (Math.Abs(song.Finish) > 0.001) - time = song.Finish; - - time -= song.Start; - var min = (int)Math.Floor(time / 60f); - var sec = (int)(time - min * 60f); - _SongLength.Text = min.ToString("00") + ":" + sec.ToString("00"); + UpdateLength(song); } else { @@ -197,6 +196,23 @@ namespace VocaluxeLib.Menu.SongMenu } } + private void UpdateLength(CSong song) + { + float time = CBase.Sound.GetLength(_PreviewSongStream); + if (Math.Abs(song.Finish) > 0.001) + time = song.Finish; + + // The audiobackend is not yet ready to return the length + if (time > 0) + { + time -= song.Start; + var min = (int)Math.Floor(time / 60f); + var sec = (int)(time - min * 60f); + _SongLength.Text = min.ToString("00") + ":" + sec.ToString("00"); + _Length = time; + } + } + public override void OnShow() { if (CBase.Songs.GetTabs() == EOffOn.TR_CONFIG_OFF && CBase.Songs.GetNumCategories() > 0 && !CBase.Songs.IsInCategory())