diff --git a/Output/Graphics/Credits_BGVideo.mp4 b/Output/Graphics/Credits_BGVideo.mp4 new file mode 100644 index 00000000..29b25529 Binary files /dev/null and b/Output/Graphics/Credits_BGVideo.mp4 differ diff --git a/Vocaluxe/Base/CSettings.cs b/Vocaluxe/Base/CSettings.cs index e222f071..82b9ddfe 100644 --- a/Vocaluxe/Base/CSettings.cs +++ b/Vocaluxe/Base/CSettings.cs @@ -109,6 +109,7 @@ namespace Vocaluxe.Base public const string FileNameLogo = "Logo.png"; public const string FileNameFonts = "Fonts.xml"; public const string FileNameCreditsLogo = "CreditsLogo.png"; + public const string FileNameCreditsVideo = "Credits_BGVideo.mp4"; public const string FileNameOldHighscoreDB = "Ultrastar.db"; public const string FileNameCoverDB = "CoverDB.sqlite"; diff --git a/Vocaluxe/Screens/CScreenCredits.cs b/Vocaluxe/Screens/CScreenCredits.cs index b7f9bb8e..a87a7645 100644 --- a/Vocaluxe/Screens/CScreenCredits.cs +++ b/Vocaluxe/Screens/CScreenCredits.cs @@ -10,7 +10,7 @@ // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with Vocaluxe. If not, see . #endregion @@ -44,10 +44,13 @@ namespace Vocaluxe.Screens private List _ScrollingElements; private Dictionary _ElementStartYPositions; - private float _previousElapsedMilliseconds; + private float _previousVideoElapsedMilliseconds; + private float _previousAnimationElapsedMilliseconds; private CTextureRef _TexLogo; + private CVideoStream _BackgroundVideo; + private float _BackgroundVideoTime; public override EMusicType CurrentMusicType { @@ -71,8 +74,8 @@ namespace Vocaluxe.Screens if (File.Exists(path)) { - _TexLogo = CDraw.AddTexture(path); - ressourceOK &= _TexLogo != null; + _TexLogo = CDraw.AddTexture(path); + ressourceOK &= _TexLogo != null; } else { @@ -80,33 +83,26 @@ namespace Vocaluxe.Screens } if (!ressourceOK) { - CLog.Fatal("Could not load all resources!"); + CLog.Fatal("Could not load all resources!"); + // Prevent further execution + return; } - // Initialize background theme - SThemeBackground _BGTheme = new SThemeBackground - { - Type = EBackgroundTypes.Color, - Color = new SThemeColor { Name = "Black", R = 0f, G = 0f, B = 0f, A = 1f } - }; - - // Create and add background - CBackground bg = new CBackground(_BGTheme, -1); - bg.LoadSkin(); - _AddBackground(bg); - // Position Y for the first scrolling element float scrollY = CSettings.RenderH - 1f; // Create logo - _Logo = GetNewStatic(_TexLogo, new SColorF(1, 1, 1, 1), - new SRectF((float)(CSettings.RenderW - _TexLogo.OrigSize.Width) / 2, scrollY, _TexLogo.OrigSize.Width, _TexLogo.OrigSize.Height, -2)); - _Logo.Visible = false; - _AddStatic(_Logo); - _ScrollingElements.Add(_Logo); - _ElementStartYPositions[_Logo] = scrollY; - - scrollY += _Logo.Rect.H + 20f; // Update scrollY after logo + if (_TexLogo != null) + { + _Logo = GetNewStatic(_TexLogo, new SColorF(1, 1, 1, 1), + new SRectF((float)(CSettings.RenderW - _TexLogo.OrigSize.Width) / 2, scrollY, _TexLogo.OrigSize.Width, _TexLogo.OrigSize.Height, -2)); + _Logo.Visible = false; + _AddStatic(_Logo); + _ScrollingElements.Add(_Logo); + _ElementStartYPositions[_Logo] = scrollY; + + scrollY += _Logo.Rect.H + 20f; // Update scrollY after logo + } // Helper variables for font sizes int bigHeadlineSize = 45; @@ -221,7 +217,7 @@ namespace Vocaluxe.Screens case Keys.Escape: case Keys.Back: case Keys.Enter: - CGraphics.FadeTo(EScreen.Main); + _LeaveScreen(); break; } } @@ -232,15 +228,35 @@ namespace Vocaluxe.Screens public override bool HandleMouse(SMouseEvent mouseEvent) { if (mouseEvent.LB || mouseEvent.RB) - CGraphics.FadeTo(EScreen.Main); + _LeaveScreen(); return true; } public override bool UpdateGame() { - if (!_Animation() && CGraphics.NextScreen != CGraphics.GetScreen(EScreen.Main)) - CGraphics.FadeTo(EScreen.Main); - return true; + if (_BackgroundVideo != null) + { + float deltaTime = (_ScrollTimer.ElapsedMilliseconds - _previousVideoElapsedMilliseconds) / 1000f; + _previousVideoElapsedMilliseconds = _ScrollTimer.ElapsedMilliseconds; + + _BackgroundVideoTime += deltaTime; + + float videoLength = CVideo.GetLength(_BackgroundVideo); + + // Keep time within video length to avoid seeking backward + if (_BackgroundVideoTime >= videoLength) + { + _BackgroundVideoTime -= videoLength; + } + + CVideo.GetFrame(_BackgroundVideo, _BackgroundVideoTime); + } + + if (!_Animation() && CGraphics.NextScreen != CGraphics.GetScreen(EScreen.Main)) + _LeaveScreen(); + + return true; + } public override void OnShow() @@ -262,8 +278,25 @@ namespace Vocaluxe.Screens } } } + + _previousVideoElapsedMilliseconds = 0f; + + string path = Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameGraphics, CSettings.FileNameCreditsVideo); + if (File.Exists(path)) + { + // Load the video if not already loaded + if (_BackgroundVideo == null) + { + _BackgroundVideo = CVideo.Load(path); + CVideo.SetLoop(_BackgroundVideo, true); // Set the video to loop + } + + } + else + { + CLog.Error("Background video not found: " + path); + } - // Set all elements to visible immediately foreach (dynamic element in _ScrollingElements) { element.Visible = true; @@ -272,17 +305,46 @@ namespace Vocaluxe.Screens // Start the scroll timer immediately _ScrollTimer.Reset(); _ScrollTimer.Start(); - _previousElapsedMilliseconds = 0; + _previousAnimationElapsedMilliseconds = 0; + _BackgroundVideoTime = 0f; + + foreach (dynamic element in _ScrollingElements) + { + element.Visible = true; + } } + public override void Draw() + { + if (_Active && _BackgroundVideo != null && _BackgroundVideo.Texture != null) + { + CTextureRef background = _BackgroundVideo.Texture; + SRectF bounds = CSettings.RenderRect; + SRectF rect = CHelper.FitInBounds(bounds, background.OrigAspect, EAspect.Crop); + CDraw.DrawTexture(background, rect, background.Color, bounds); + } + + base.Draw(); + } + + private void _LeaveScreen() + { + CGraphics.FadeTo(EScreen.Options); + + if (_BackgroundVideo != null) + { + CVideo.Close(ref _BackgroundVideo); + _BackgroundVideo = null; + } + } private bool _Animation() { if (!_ScrollTimer.IsRunning) return false; - float deltaTime = (_ScrollTimer.ElapsedMilliseconds - _previousElapsedMilliseconds) / 1000f; // Convert milliseconds to seconds - _previousElapsedMilliseconds = _ScrollTimer.ElapsedMilliseconds; + float deltaTime = (_ScrollTimer.ElapsedMilliseconds - _previousAnimationElapsedMilliseconds) / 1000f; // Convert milliseconds to seconds + _previousAnimationElapsedMilliseconds = _ScrollTimer.ElapsedMilliseconds; float scrollSpeed = 60f;