diff --git a/Vocaluxe/Base/CConfig.cs b/Vocaluxe/Base/CConfig.cs index f39398f9..8172d7c6 100644 --- a/Vocaluxe/Base/CConfig.cs +++ b/Vocaluxe/Base/CConfig.cs @@ -45,7 +45,7 @@ namespace Vocaluxe.Base #pragma warning disable 649 // ReSharper disable MemberCanBePrivate.Global public struct SConfigInfo - // ReSharper restore MemberCanBePrivate.Global + // ReSharper restore MemberCanBePrivate.Global { // ReSharper disable NotAccessedField.Global // ReSharper disable NotAccessedField.Local @@ -63,34 +63,54 @@ namespace Vocaluxe.Base public struct SConfigDebug { - [DefaultValue(EDebugLevel.TR_CONFIG_OFF)] public EDebugLevel DebugLevel; - [DefaultValue(EOffOn.TR_CONFIG_OFF)] public EOffOn SaveModifiedSongs; + [DefaultValue(EDebugLevel.TR_CONFIG_OFF)] + public EDebugLevel DebugLevel; + [DefaultValue(EOffOn.TR_CONFIG_OFF)] + public EOffOn SaveModifiedSongs; } public struct SConfigGraphics { #if WIN - [DefaultValue(ERenderer.TR_CONFIG_DIRECT3D)] public ERenderer Renderer; + [DefaultValue(ERenderer.TR_CONFIG_DIRECT3D)] + public ERenderer Renderer; #else [DefaultValue(ERenderer.TR_CONFIG_OPENGL)] public ERenderer Renderer; #endif - [DefaultValue(ETextureQuality.TR_CONFIG_TEXTURE_MEDIUM)] public ETextureQuality TextureQuality; - [XmlRanged(32, 1024), DefaultValue(256)] public int CoverSize; + [DefaultValue(ETextureQuality.TR_CONFIG_TEXTURE_MEDIUM)] + public ETextureQuality TextureQuality; + [XmlRanged(32, 1024), DefaultValue(256)] + public int CoverSize; - [DefaultValue(1024)] public int ScreenW; - [DefaultValue(576)] public int ScreenH; - [DefaultValue(EGeneralAlignment.Middle)] public EGeneralAlignment ScreenAlignment; - [DefaultValue(0)] public int BorderLeft; - [DefaultValue(0)] public int BorderRight; - [DefaultValue(0)] public int BorderTop; - [DefaultValue(0)] public int BorderBottom; - [DefaultValue(EAntiAliasingModes.X0)] public EAntiAliasingModes AAMode; - [DefaultValue(60f)] public float MaxFPS; - [DefaultValue(EOffOn.TR_CONFIG_ON)] public EOffOn VSync; - [DefaultValue(EOffOn.TR_CONFIG_ON)] public EOffOn FullScreen; - [DefaultValue(EOffOn.TR_CONFIG_OFF)] public EOffOn Stretch; - [DefaultValue(0.4f), XmlRanged(0, 3)] public float FadeTime; + [XmlRanged(1, 6), DefaultValue(1)] + public int NumScreens; + [DefaultValue(1024)] + public int ScreenW; + [DefaultValue(576)] + public int ScreenH; + [DefaultValue(EGeneralAlignment.Middle)] + public EGeneralAlignment ScreenAlignment; + [DefaultValue(0)] + public int BorderLeft; + [DefaultValue(0)] + public int BorderRight; + [DefaultValue(0)] + public int BorderTop; + [DefaultValue(0)] + public int BorderBottom; + [DefaultValue(EAntiAliasingModes.X0)] + public EAntiAliasingModes AAMode; + [DefaultValue(60f)] + public float MaxFPS; + [DefaultValue(EOffOn.TR_CONFIG_ON)] + public EOffOn VSync; + [DefaultValue(EOffOn.TR_CONFIG_ON)] + public EOffOn FullScreen; + [DefaultValue(EOffOn.TR_CONFIG_OFF)] + public EOffOn Stretch; + [DefaultValue(0.4f), XmlRanged(0, 3)] + public float FadeTime; } public struct SConfigTheme @@ -109,28 +129,42 @@ namespace Vocaluxe.Base public struct SConfigSound { - [DefaultValue(EPlaybackLib.GstreamerSharp)] public EPlaybackLib PlayBackLib; - [DefaultValue(ERecordLib.PortAudio)] public ERecordLib RecordLib; - [DefaultValue(EBufferSize.B2048)] public EBufferSize AudioBufferSize; - [XmlRanged(-500, 500)] public int AudioLatency; + [DefaultValue(EPlaybackLib.GstreamerSharp)] + public EPlaybackLib PlayBackLib; + [DefaultValue(ERecordLib.PortAudio)] + public ERecordLib RecordLib; + [DefaultValue(EBufferSize.B2048)] + public EBufferSize AudioBufferSize; + [XmlRanged(-500, 500)] + public int AudioLatency; // ReSharper disable MemberHidesStaticFromOuterClass - [DefaultValue(EBackgroundMusicOffOn.TR_CONFIG_ON)] public EBackgroundMusicOffOn BackgroundMusic; - [XmlRanged(0, 100), DefaultValue(30)] public int BackgroundMusicVolume; - [DefaultValue(EBackgroundMusicSource.TR_CONFIG_NO_OWN_MUSIC)] public EBackgroundMusicSource BackgroundMusicSource; - [DefaultValue(EOffOn.TR_CONFIG_ON)] public EOffOn BackgroundMusicUseStart; - [XmlRanged(0, 100), DefaultValue(50)] public int PreviewMusicVolume; - [XmlRanged(0, 100), DefaultValue(80)] public int GameMusicVolume; - [DefaultValue(EOffOn.TR_CONFIG_OFF)] public EOffOn KaraokeEffect; - [XmlRanged(0, 1), DefaultValue(1.0f)] public float KaraokeEffectLevel; + [DefaultValue(EBackgroundMusicOffOn.TR_CONFIG_ON)] + public EBackgroundMusicOffOn BackgroundMusic; + [XmlRanged(0, 100), DefaultValue(30)] + public int BackgroundMusicVolume; + [DefaultValue(EBackgroundMusicSource.TR_CONFIG_NO_OWN_MUSIC)] + public EBackgroundMusicSource BackgroundMusicSource; + [DefaultValue(EOffOn.TR_CONFIG_ON)] + public EOffOn BackgroundMusicUseStart; + [XmlRanged(0, 100), DefaultValue(50)] + public int PreviewMusicVolume; + [XmlRanged(0, 100), DefaultValue(80)] + public int GameMusicVolume; + [DefaultValue(EOffOn.TR_CONFIG_OFF)] + public EOffOn KaraokeEffect; + [XmlRanged(0, 1), DefaultValue(1.0f)] + public float KaraokeEffectLevel; // ReSharper restore MemberHidesStaticFromOuterClass } public struct SConfigGame { - [DefaultValue(CSettings.FallbackLanguage)] public string Language; + [DefaultValue(CSettings.FallbackLanguage)] + public string Language; public string[] SongFolder; // ReSharper disable MemberHidesStaticFromOuterClass - [DefaultValue(ESongMenu.TR_CONFIG_TILE_BOARD)] public ESongMenu SongMenu; + [DefaultValue(ESongMenu.TR_CONFIG_TILE_BOARD)] + public ESongMenu SongMenu; // ReSharper restore MemberHidesStaticFromOuterClass [DefaultValue(ESongSorting.TR_CONFIG_ARTIST)] public ESongSorting SongSorting; [DefaultValue(EOffOn.TR_CONFIG_ON)] public EOffOn IgnoreArticles; @@ -145,27 +179,38 @@ namespace Vocaluxe.Base public struct SConfigVideo { - [DefaultValue(EVideoDecoder.FFmpeg)] public EVideoDecoder VideoDecoder; - [DefaultValue(EOffOn.TR_CONFIG_ON)] public EOffOn VideoBackgrounds; - [DefaultValue(EOffOn.TR_CONFIG_ON)] public EOffOn VideoPreview; - [DefaultValue(EOffOn.TR_CONFIG_ON)] public EOffOn VideosInSongs; - [DefaultValue(EOffOn.TR_CONFIG_OFF)] public EOffOn VideosToBackground; - [DefaultValue(EWebcamLib.AForgeNet)] public EWebcamLib WebcamLib; + [DefaultValue(EVideoDecoder.FFmpeg)] + public EVideoDecoder VideoDecoder; + [DefaultValue(EOffOn.TR_CONFIG_ON)] + public EOffOn VideoBackgrounds; + [DefaultValue(EOffOn.TR_CONFIG_ON)] + public EOffOn VideoPreview; + [DefaultValue(EOffOn.TR_CONFIG_ON)] + public EOffOn VideosInSongs; + [DefaultValue(EOffOn.TR_CONFIG_OFF)] + public EOffOn VideosToBackground; + [DefaultValue(EWebcamLib.AForgeNet)] + public EWebcamLib WebcamLib; public SWebcamConfig? WebcamConfig; } public struct SConfigRecord { public SMicConfig[] MicConfig; - [DefaultValue(200)] public int MicDelay; //[ms] + [DefaultValue(200)] + public int MicDelay; //[ms] } public struct SConfigServer { - [DefaultValue(EOffOn.TR_CONFIG_OFF)] public EOffOn ServerActive; - [DefaultValue(EOffOn.TR_CONFIG_OFF)] public EOffOn ServerEncryption; - [DefaultValue(3000)] public int ServerPort; - [DefaultValue(70)] public int SongCountCoverThreshold; + [DefaultValue(EOffOn.TR_CONFIG_OFF)] + public EOffOn ServerActive; + [DefaultValue(EOffOn.TR_CONFIG_OFF)] + public EOffOn ServerEncryption; + [DefaultValue(3000)] + public int ServerPort; + [DefaultValue(70)] + public int SongCountCoverThreshold; } #pragma warning restore 649 // ReSharper restore UnassignedField.Global @@ -350,6 +395,9 @@ namespace Vocaluxe.Base Config.Game.NumPlayers = 2; Array.Resize(ref Config.Game.Players, CSettings.MaxNumPlayer); + if (!Config.Graphics.NumScreens.IsInRange(1, CSettings.MaxNumScreens)) + Config.Graphics.NumScreens = 1; + bool langExists = CLanguage.SetLanguage(Config.Game.Language); if (langExists == false) @@ -365,16 +413,16 @@ namespace Vocaluxe.Base Config.Server.ServerPort = 3000; Config.Info = new SConfigInfo - { - Version = CSettings.GetFullVersionText(), - Time = DateTime.Now.ToString(), - Platform = Environment.OSVersion.Platform.ToString(), - OSVersion = Environment.OSVersion.ToString(), - ProcessorCount = Environment.ProcessorCount, - Screens = Screen.AllScreens.Length, - PrimaryScreenResolution = Screen.PrimaryScreen.Bounds.Size.ToString(), - Directory = CSettings.ProgramFolder - }; + { + Version = CSettings.GetFullVersionText(), + Time = DateTime.Now.ToString(), + Platform = Environment.OSVersion.Platform.ToString(), + OSVersion = Environment.OSVersion.ToString(), + ProcessorCount = Environment.ProcessorCount, + Screens = Screen.AllScreens.Length, + PrimaryScreenResolution = Screen.PrimaryScreen.Bounds.Size.ToString(), + Directory = CSettings.ProgramFolder + }; } private static readonly List _CommentsGot = new List(); @@ -397,6 +445,8 @@ namespace Vocaluxe.Base return "TextureQuality: " + CHelper.ListStrings(Enum.GetNames(typeof(ETextureQuality))); case "CoverSize": return "CoverSize (pixels): 32, 64, 128, 256, 512, 1024 (default: 128)"; + case "NumScreens": + return "Number of screens to use. 1 - 6 (default: 1)"; case "ScreenW": return "Screen width and height (pixels)"; case "BorderLeft": @@ -536,7 +586,7 @@ namespace Vocaluxe.Base return devices.Any(t => t.PlayerChannel.Contains(player)); for (int p = 0; p < CSettings.MaxNumPlayer; ++p) - if (devices.Any(t => t.PlayerChannel.Contains(p+1))) + if (devices.Any(t => t.PlayerChannel.Contains(p + 1))) { return true; } @@ -557,6 +607,11 @@ namespace Vocaluxe.Base return max; } + public static int GetNumScreens() + { + return Config.Graphics.NumScreens; + } + /// /// Try to assign automatically player 1 and 2 to usb-mics. /// @@ -641,7 +696,7 @@ namespace Vocaluxe.Base switch (parts.Length) { - //Only found a parameter + //Only found a parameter case 1: if (parts[0] != "") { @@ -654,7 +709,7 @@ namespace Vocaluxe.Base break; - //Found parameter and value + //Found parameter and value case 2: if (parts[0] != "") { diff --git a/Vocaluxe/Base/CDraw.cs b/Vocaluxe/Base/CDraw.cs index 7b3b58d1..57f61ff2 100644 --- a/Vocaluxe/Base/CDraw.cs +++ b/Vocaluxe/Base/CDraw.cs @@ -285,9 +285,10 @@ namespace Vocaluxe.Base /// /// /// - public static void DrawRect(SColorF color, SRectF rect) + /// Render on all monitors + public static void DrawRect(SColorF color, SRectF rect, bool allMonitors = true) { - _Draw.DrawRect(color, rect); + _Draw.DrawRect(color, rect, allMonitors); } /// @@ -328,9 +329,10 @@ namespace Vocaluxe.Base /// /// /// True to mirror the texture on the y axis - public static void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, bool mirrored = false) + /// Render on all monitors + public static void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, bool mirrored = false, bool allMonitors = true) { - _Draw.DrawTexture(textureRef, rect, color, mirrored); + _Draw.DrawTexture(textureRef, rect, color, mirrored, allMonitors); } /// @@ -341,9 +343,10 @@ namespace Vocaluxe.Base /// /// Bounds to draw the texture in (rest gets cropped off) /// True to mirror the texture on the y axis - public static void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false) + /// Render on all monitors + public static void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false, bool allMonitors = true) { - _Draw.DrawTexture(textureRef, rect, color, bounds, mirrored); + _Draw.DrawTexture(textureRef, rect, color, bounds, mirrored, allMonitors); } /// @@ -354,9 +357,10 @@ namespace Vocaluxe.Base /// /// Normalized start x-coordinate (0..1) /// Normalized end x-coordinate (0..1) - public static void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, float begin, float end) + /// Render on all monitors + public static void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, float begin, float end, bool allMonitors = true) { - _Draw.DrawTexture(textureRef, rect, color, begin, end); + _Draw.DrawTexture(textureRef, rect, color, begin, end, allMonitors); } /// @@ -383,7 +387,7 @@ namespace Vocaluxe.Base return; SRectF rect = CHelper.FitInBounds(bounds, textureRef.OrigAspect, aspect); - DrawTexture(textureRef, rect, color); + DrawTexture(textureRef, rect, color, bounds); } /// @@ -395,9 +399,9 @@ namespace Vocaluxe.Base /// /// Spacing between the rect and the reflection /// Height of the reflection - public static void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, float space, float height) + public static void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, float space, float height, bool allMonitors = true) { - _Draw.DrawTextureReflection(textureRef, rect, color, bounds, space, height); + _Draw.DrawTextureReflection(textureRef, rect, color, bounds, space, height, allMonitors); } } } \ No newline at end of file diff --git a/Vocaluxe/Base/CMain.cs b/Vocaluxe/Base/CMain.cs index dc0167dc..f1053ce3 100644 --- a/Vocaluxe/Base/CMain.cs +++ b/Vocaluxe/Base/CMain.cs @@ -165,6 +165,11 @@ namespace Vocaluxe.Base { CConfig.SongMenuChanged -= onSongMenuChanged; } + + public int GetNumScreens() + { + return CConfig.GetNumScreens(); + } } class CBsettings : ISettings @@ -224,6 +229,11 @@ namespace Vocaluxe.Base return CSettings.MaxNumPlayer; } + public int GetMaxNumScreens() + { + return CSettings.MaxNumScreens; + } + public float GetDefaultMedleyFadeInTime() { return CSettings.DefaultMedleyFadeInTime; @@ -393,14 +403,14 @@ namespace Vocaluxe.Base CDraw.DrawTexture(texture, rect); } - public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color) + public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, bool allMonitors = true) { - CDraw.DrawTexture(texture, rect, color); + CDraw.DrawTexture(texture, rect, color, false, allMonitors); } - public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false) + public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false, bool allMonitors = true) { - CDraw.DrawTexture(texture, rect, color, bounds, mirrored); + CDraw.DrawTexture(texture, rect, color, bounds, mirrored, allMonitors); } public void DrawTexture(CTextureRef textureRef, SRectF bounds, EAspect aspect) @@ -413,9 +423,9 @@ namespace Vocaluxe.Base CDraw.DrawTexture(textureRef, bounds, aspect, color); } - public void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, float reflectionSpace, float reflectionHeight) + public void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, float reflectionSpace, float reflectionHeight, bool allMonitors = true) { - CDraw.DrawTextureReflection(texture, rect, color, bounds, reflectionSpace, reflectionHeight); + CDraw.DrawTextureReflection(texture, rect, color, bounds, reflectionSpace, reflectionHeight, allMonitors); } public CTextureRef AddTexture(string fileName) @@ -433,9 +443,9 @@ namespace Vocaluxe.Base CDraw.RemoveTexture(ref texture); } - public void DrawRect(SColorF color, SRectF rect) + public void DrawRect(SColorF color, SRectF rect, bool allMonitors = true) { - CDraw.DrawRect(color, rect); + CDraw.DrawRect(color, rect, allMonitors); } public void DrawRectReflection(SColorF color, SRectF rect, float space, float height) @@ -512,9 +522,9 @@ namespace Vocaluxe.Base return CFonts.GetTextBounds(text); } - public void DrawText(string text, CFont font, float x, float y, float z, SColorF color) + public void DrawText(string text, CFont font, float x, float y, float z, SColorF color, bool allMonitors = true) { - CFonts.DrawText(text, font, x, y, z, color); + CFonts.DrawText(text, font, x, y, z, color, allMonitors); } public void DrawTextReflection(string text, CFont font, float x, float y, float z, SColorF color, float reflectionSpace, float reflectionHeight) diff --git a/Vocaluxe/Base/CSettings.cs b/Vocaluxe/Base/CSettings.cs index 917e75bb..8bc61828 100644 --- a/Vocaluxe/Base/CSettings.cs +++ b/Vocaluxe/Base/CSettings.cs @@ -82,6 +82,7 @@ namespace Vocaluxe.Base public const int DatabaseCoverVersion = 1; public const int DatabaseCreditsRessourcesVersion = 1; + public const int MaxNumScreens = 6; public const int RenderW = 1280; public const int RenderH = 720; public static readonly SRectF RenderRect = new SRectF(0, 0, RenderW, RenderH, 0); @@ -209,7 +210,7 @@ namespace Vocaluxe.Base public static float GetRenderAspect() { - return RenderW / (float)RenderH; + return RenderW * CConfig.GetNumScreens() / (float)RenderH; } public static void CreateFolders() diff --git a/Vocaluxe/Base/CUtility.cs b/Vocaluxe/Base/CUtility.cs index ee766dc5..8402169c 100644 --- a/Vocaluxe/Base/CUtility.cs +++ b/Vocaluxe/Base/CUtility.cs @@ -31,14 +31,14 @@ namespace Vocaluxe.Base // ReSharper disable MemberCanBePrivate.Global public static void Reset() - // ReSharper restore MemberCanBePrivate.Global + // ReSharper restore MemberCanBePrivate.Global { _Stopwatch.Reset(); } // ReSharper disable MemberCanBePrivate.Global public static void Start() - // ReSharper restore MemberCanBePrivate.Global + // ReSharper restore MemberCanBePrivate.Global { _Stopwatch.Start(); } @@ -127,7 +127,7 @@ namespace Vocaluxe.Base { _KeysPool.Add(pool); } - catch (Exception) {} + catch (Exception) { } } _Timer.Reset(); @@ -173,7 +173,7 @@ namespace Vocaluxe.Base // ReSharper disable UnusedParameter.Global public void KeyUp(KeyEventArgs e) - // ReSharper restore UnusedParameter.Global + // ReSharper restore UnusedParameter.Global { _CheckModifiers(); _KeyPressed = false; @@ -225,7 +225,9 @@ namespace Vocaluxe.Base private void _Add(int x, int y, bool lb, bool ld, bool rb, int wheel, bool lbh, bool rbh, bool mb, bool mbh) { _CheckModifiers(); - x = (int)(x * (float)CSettings.RenderW / CDraw.GetScreenWidth()); + x = (int)(x * (float)CSettings.RenderW * CConfig.Config.Graphics.NumScreens / CDraw.GetScreenWidth()); + while (x > CSettings.RenderW) + x -= CSettings.RenderW; y = (int)(y * (float)CSettings.RenderH / CDraw.GetScreenHeight()); var pool = new SMouseEvent(ESender.Mouse, _Mod, x, y, lb, ld, rb, -wheel / 120, lbh, rbh, mb, mbh); @@ -290,7 +292,7 @@ namespace Vocaluxe.Base // ReSharper disable UnusedParameter.Global public void MouseUp(MouseEventArgs e) - // ReSharper restore UnusedParameter.Global + // ReSharper restore UnusedParameter.Global { //CheckModifiers(); //Add(_ModALT, _ModSHIFT, _ModCTRL, e.X, e.Y, e.Button == MouseButtons.Left, e.Button == MouseButtons.Right, e.Delta); diff --git a/Vocaluxe/Base/Fonts/CFontStyle.cs b/Vocaluxe/Base/Fonts/CFontStyle.cs index ba59e87b..0958632b 100644 --- a/Vocaluxe/Base/Fonts/CFontStyle.cs +++ b/Vocaluxe/Base/Fonts/CFontStyle.cs @@ -99,12 +99,12 @@ namespace Vocaluxe.Base.Fonts return new Font(_Family, height, _GetSystemFontStyle(), GraphicsUnit.Pixel); } - public void DrawGlyph(char chr, float fontHeight, float x, float y, float z, SColorF color) + public void DrawGlyph(char chr, float fontHeight, float x, float y, float z, SColorF color, bool allMonitors = true) { CTextureRef texture; SRectF rect; GetOrAddGlyph(chr, fontHeight).GetTextureAndRect(fontHeight, x, y, z, out texture, out rect); - CDraw.DrawTexture(texture, rect, color); + CDraw.DrawTexture(texture, rect, color, false, allMonitors); } public void DrawGlyph(char chr, float fontHeight, float x, float y, float z, SColorF color, float begin, float end) diff --git a/Vocaluxe/Base/Fonts/CFonts.cs b/Vocaluxe/Base/Fonts/CFonts.cs index b0ab10d8..5e242e2c 100644 --- a/Vocaluxe/Base/Fonts/CFonts.cs +++ b/Vocaluxe/Base/Fonts/CFonts.cs @@ -74,7 +74,7 @@ namespace Vocaluxe.Base.Fonts /// The texts y-position /// The texts z-position /// The text color - public static void DrawText(string text, CFont font, float x, float y, float z, SColorF color) + public static void DrawText(string text, CFont font, float x, float y, float z, SColorF color, bool allMonitors = true) { if (font.Height <= 0f || text == "") return; @@ -84,7 +84,7 @@ namespace Vocaluxe.Base.Fonts float dx = x; foreach (char chr in text) { - fontStyle.DrawGlyph(chr, font.Height, dx, y, z, color); + fontStyle.DrawGlyph(chr, font.Height, dx, y, z, color, allMonitors); dx += fontStyle.GetWidth(chr, font.Height); } } diff --git a/Vocaluxe/Lib/Draw/CDirect3D.cs b/Vocaluxe/Lib/Draw/CDirect3D.cs index df93e1a8..9960e86f 100644 --- a/Vocaluxe/Lib/Draw/CDirect3D.cs +++ b/Vocaluxe/Lib/Draw/CDirect3D.cs @@ -86,7 +86,7 @@ namespace Vocaluxe.Lib.Draw /// public CDirect3D() { - _Form = new CRenderFormHook {ClientSize = new Size(CConfig.Config.Graphics.ScreenW, CConfig.Config.Graphics.ScreenH)}; + _Form = new CRenderFormHook { ClientSize = new Size(CConfig.Config.Graphics.ScreenW * CConfig.Config.Graphics.NumScreens, CConfig.Config.Graphics.ScreenH) }; try { @@ -110,15 +110,15 @@ namespace Vocaluxe.Lib.Draw _Form.MouseEnter += _OnMouseEnter; _PresentParameters = new PresentParameters - { - Windowed = true, - SwapEffect = SwapEffect.Discard, - BackBufferHeight = CConfig.Config.Graphics.ScreenH, - BackBufferWidth = CConfig.Config.Graphics.ScreenW, - BackBufferFormat = _D3D.Adapters.DefaultAdapter.CurrentDisplayMode.Format, - Multisample = MultisampleType.None, - MultisampleQuality = 0 - }; + { + Windowed = true, + SwapEffect = SwapEffect.Discard, + BackBufferHeight = CConfig.Config.Graphics.ScreenH, + BackBufferWidth = CConfig.Config.Graphics.ScreenW * CConfig.Config.Graphics.NumScreens, + BackBufferFormat = _D3D.Adapters.DefaultAdapter.CurrentDisplayMode.Format, + Multisample = MultisampleType.None, + MultisampleQuality = 0 + }; //Apply antialiasing and check if antialiasing mode is supported @@ -379,7 +379,7 @@ namespace Vocaluxe.Lib.Draw const float dy = (float)CSettings.RenderH / 2; Matrix translate = Matrix.Translation(new Vector3(-dx, dy, 0)); Matrix projection = Matrix.OrthoOffCenterLH( - -dx - _BorderLeft, dx + _BorderRight, + -dx - _BorderLeft, (CSettings.RenderW * CConfig.Config.Graphics.NumScreens) - dx + _BorderRight, -dy - _BorderBottom, dy + _BorderTop, CSettings.ZNear, CSettings.ZFar); @@ -572,9 +572,9 @@ namespace Vocaluxe.Lib.Draw /// /// The color in which the rectangle will be drawn in /// The coordinates in a SRectF struct - public void DrawRect(SColorF color, SRectF rect) + public void DrawRect(SColorF color, SRectF rect, bool allMonitors = true) { - DrawTexture(_BlankTexture, rect, color); + DrawTexture(_BlankTexture, rect, color, false, allMonitors); } /// diff --git a/Vocaluxe/Lib/Draw/CDrawBase.cs b/Vocaluxe/Lib/Draw/CDrawBase.cs index d02dc520..846c03f6 100644 --- a/Vocaluxe/Lib/Draw/CDrawBase.cs +++ b/Vocaluxe/Lib/Draw/CDrawBase.cs @@ -220,7 +220,7 @@ namespace Vocaluxe.Lib.Draw return true; } - public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, bool mirrored = false) + public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, bool mirrored = false, bool allMonitors = true) { if (Math.Abs(color.A) < 0.01) return; @@ -228,10 +228,23 @@ namespace Vocaluxe.Lib.Draw TTextureType texture; if (!_GetTexture(textureRef, out texture)) return; - if (!_CalcDrawCoords(texture, rect, out dc, mirrored)) - return; - - _DrawTexture(texture, dc, color); + if (allMonitors) + { + for (int i = 0; i < CConfig.Config.Graphics.NumScreens; i++) + { + SRectF newrect = rect; + newrect.X += CSettings.RenderW * i; + if (!_CalcDrawCoords(texture, newrect, out dc, mirrored)) + return; + _DrawTexture(texture, dc, color); + } + } + else + { + if (!_CalcDrawCoords(texture, rect, out dc, mirrored)) + return; + _DrawTexture(texture, dc, color); + } } /// @@ -242,7 +255,7 @@ namespace Vocaluxe.Lib.Draw /// A SColorF struct containing a color which the texture will be colored in /// A SRectF struct containing which part of the texture should be drawn /// True if the texture should be mirrored - public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false) + public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false, bool allMonitors = true) { if (Math.Abs(color.A) < 0.01) return; @@ -250,10 +263,26 @@ namespace Vocaluxe.Lib.Draw TTextureType texture; if (!_GetTexture(textureRef, out texture)) return; - if (!_CalcDrawCoords(texture, rect, bounds, out dc)) - return; - _DrawTexture(texture, dc, color); + if (allMonitors) + { + for (int i = 0; i < CConfig.Config.Graphics.NumScreens; i++) + { + SRectF newrect = rect; + SRectF newbounds = bounds; + newrect.X += CSettings.RenderW * i; + newbounds.X += CSettings.RenderW * i; + if (!_CalcDrawCoords(texture, newrect, newbounds, out dc, mirrored)) + return; + _DrawTexture(texture, dc, color); + } + } + else + { + if (!_CalcDrawCoords(texture, rect, bounds, out dc, mirrored)) + return; + _DrawTexture(texture, dc, color); + } } /// @@ -264,7 +293,7 @@ namespace Vocaluxe.Lib.Draw /// A SColorF struct containing a color which the texture will be colored in /// A Value ranging from 0 to 1 containing the beginning of the texture /// A Value ranging from 0 to 1 containing the ending of the texture - public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, float begin, float end) + public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, float begin, float end, bool allMonitors = true) { if (Math.Abs(color.A) < 0.01) return; @@ -272,10 +301,24 @@ namespace Vocaluxe.Lib.Draw TTextureType texture; if (!_GetTexture(textureRef, out texture)) return; - if (!_CalcDrawCoords(texture, rect, out dc, false, begin, end)) - return; - _DrawTexture(texture, dc, color); + if (allMonitors) + { + for (int i = 0; i < CConfig.Config.Graphics.NumScreens; i++) + { + SRectF newrect = rect; + newrect.X += CSettings.RenderW * i; + if (!_CalcDrawCoords(texture, newrect, out dc, false, begin, end)) + return; + _DrawTexture(texture, dc, color); + } + } + else + { + if (!_CalcDrawCoords(texture, rect, out dc, false, begin, end)) + return; + _DrawTexture(texture, dc, color); + } } /// @@ -287,7 +330,7 @@ namespace Vocaluxe.Lib.Draw /// A SRectF struct containing which part of the texture should be drawn /// The space between the texture and the reflection /// The height of the reflection - public void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, float space, float height) + public void DrawTextureReflection(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, float space, float height, bool allMonitors = true) { Debug.Assert(height >= 0); @@ -297,17 +340,35 @@ namespace Vocaluxe.Lib.Draw TTextureType texture; if (!_GetTexture(textureRef, out texture)) return; - if (!_CalcDrawCoords(texture, rect, bounds, out dc, true)) - return; - if (height > rect.H) - height = rect.H; + int loops; + if (allMonitors) + { + loops = CConfig.Config.Graphics.NumScreens; + } + else + { + loops = 1; + } - dc.Wy1 += rect.H + space; // Move from start of rect to end of rect with spacing - dc.Wy2 += space + height; // Move from end of rect - dc.Ty2 += (rect.H - height) / rect.H; // Adjust so not all of the start of the texture is drawn (mirrored--> Ty1>Ty2) - if (dc.Ty2 < dc.Ty1) // Make sure we actually draw something - _DrawTexture(texture, dc, color, true); + for (int i = 0; i < loops; i++) + { + SRectF newrect = rect; + SRectF newbounds = bounds; + newrect.X += CSettings.RenderW * i; + newbounds.X += CSettings.RenderW * i; + if (!_CalcDrawCoords(texture, newrect, newbounds, out dc, true)) + return; + + if (height > newrect.H) + height = newrect.H; + + dc.Wy1 += newrect.H + space; // Move from start of rect to end of rect with spacing + dc.Wy2 += space + height; // Move from end of rect + dc.Ty2 += (newrect.H - height) / newrect.H; // Adjust so not all of the start of the texture is drawn (mirrored--> Ty1>Ty2) + if (dc.Ty2 < dc.Ty1) // Make sure we actually draw something + _DrawTexture(texture, dc, color, true); + } } // Resharper doesn't get that this is used -.- diff --git a/Vocaluxe/Lib/Draw/CDrawWinForm.cs b/Vocaluxe/Lib/Draw/CDrawWinForm.cs index b06d0929..f4de18e3 100644 --- a/Vocaluxe/Lib/Draw/CDrawWinForm.cs +++ b/Vocaluxe/Lib/Draw/CDrawWinForm.cs @@ -259,7 +259,7 @@ namespace Vocaluxe.Lib.Draw { base.Close(); } - catch {} + catch { } Dispose(); } @@ -308,9 +308,9 @@ namespace Vocaluxe.Lib.Draw _Backbuffer.Save(file, ImageFormat.Png); } - public void DrawRect(SColorF color, SRectF rect) {} + public void DrawRect(SColorF color, SRectF rect, bool allMonitors = true) { } - public void DrawRectReflection(SColorF color, SRectF rect, float space, float height) {} + public void DrawRectReflection(SColorF color, SRectF rect, float space, float height) { } public CTextureRef AddTexture(Bitmap bmp) { @@ -418,13 +418,13 @@ namespace Vocaluxe.Lib.Draw _Bitmaps[textureRef.ID] = bmp; } - public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, bool mirrored = false) + public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, bool mirrored = false, bool allMonitors = true) { if (texture != null) DrawTexture(texture, rect, color, rect, mirrored); } - public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false) + public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false, bool allMonitors = true) { if (!_TextureExists(texture)) return; @@ -433,9 +433,9 @@ namespace Vocaluxe.Lib.Draw coloredBitmap.Dispose(); } - public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, float begin, float end) {} + public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, float begin, float end, bool allMonitors = true) { } - public void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, float space, float height) {} + public void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, float space, float height, bool allMonitors = true) { } public int GetTextureCount() { @@ -448,7 +448,7 @@ namespace Vocaluxe.Lib.Draw using (Graphics g = Graphics.FromImage(newBitmap)) { - var cm = new ColorMatrix {Matrix33 = color.A, Matrix00 = color.R, Matrix11 = color.G, Matrix22 = color.B, Matrix44 = 1}; + var cm = new ColorMatrix { Matrix33 = color.A, Matrix00 = color.R, Matrix11 = color.G, Matrix22 = color.B, Matrix44 = 1 }; using (var ia = new ImageAttributes()) { diff --git a/Vocaluxe/Lib/Draw/COpenGL.cs b/Vocaluxe/Lib/Draw/COpenGL.cs index a2d46014..cdb702ab 100644 --- a/Vocaluxe/Lib/Draw/COpenGL.cs +++ b/Vocaluxe/Lib/Draw/COpenGL.cs @@ -100,7 +100,7 @@ namespace Vocaluxe.Lib.Draw public COpenGL() { - _Form = new CFormHook {ClientSize = new Size(CConfig.Config.Graphics.ScreenW, CConfig.Config.Graphics.ScreenH)}; + _Form = new CFormHook { ClientSize = new Size(CConfig.Config.Graphics.ScreenW * CConfig.Config.Graphics.NumScreens, CConfig.Config.Graphics.ScreenH) }; //OpenGL needs that here but D3D needs it in the constructor, so do NOT unify! //Check AA Mode @@ -109,11 +109,11 @@ namespace Vocaluxe.Lib.Draw bool ok = false; try { - #if WIN +#if WIN var gm = new GraphicsMode(32, 24, 0, (int)CConfig.Config.Graphics.AAMode); - #else +#else var gm = new GraphicsMode(24, 24, 0, (int)CConfig.Config.Graphics.AAMode); - #endif +#endif _Control = new GLControl(gm, 2, 1, GraphicsContextFlags.Default); if (_Control.GraphicsMode != null) ok = true; @@ -285,7 +285,7 @@ namespace Vocaluxe.Lib.Draw { GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity(); - GL.Ortho(-CConfig.Config.Graphics.BorderLeft, CConfig.Config.Graphics.BorderRight + CSettings.RenderW, CConfig.Config.Graphics.BorderBottom + CSettings.RenderH, + GL.Ortho(-CConfig.Config.Graphics.BorderLeft, CConfig.Config.Graphics.BorderRight + CSettings.RenderW * CConfig.Config.Graphics.NumScreens, CConfig.Config.Graphics.BorderBottom + CSettings.RenderH, -CConfig.Config.Graphics.BorderTop, CSettings.ZNear, CSettings.ZFar); } @@ -338,27 +338,36 @@ namespace Vocaluxe.Lib.Draw } } - public void DrawRect(SColorF color, SRectF rect) + public void DrawRect(SColorF color, SRectF rect, bool allMonitors = true) { - GL.Enable(EnableCap.Blend); - GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha); - - GL.Begin(PrimitiveType.Quads); - GL.MatrixMode(MatrixMode.Color); - GL.PushMatrix(); - if (Math.Abs(rect.Rotation) > 0.001) + int loops = 1; + if (allMonitors) + loops = CConfig.Config.Graphics.NumScreens; + for (int i = 0; i < loops; i++) { - GL.Translate(0.5f, 0.5f, 0); - GL.Rotate(-rect.Rotation, 0f, 0f, 1f); - GL.Translate(-0.5f, -0.5f, 0); + SRectF newrect = rect; + newrect.X += CSettings.RenderW * i; + + GL.Enable(EnableCap.Blend); + GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha); + + GL.Begin(PrimitiveType.Quads); + GL.MatrixMode(MatrixMode.Color); + GL.PushMatrix(); + if (Math.Abs(newrect.Rotation) > 0.001) + { + GL.Translate(0.5f, 0.5f, 0); + GL.Rotate(-newrect.Rotation, 0f, 0f, 1f); + GL.Translate(-0.5f, -0.5f, 0); + } + GL.Vertex3(newrect.X, newrect.Y, newrect.Z + CGraphics.ZOffset); + GL.Vertex3(newrect.X, newrect.Y + newrect.H, newrect.Z + CGraphics.ZOffset); + GL.Vertex3(newrect.X + newrect.W, newrect.Y + newrect.H, newrect.Z + CGraphics.ZOffset); + GL.Vertex3(newrect.X + newrect.W, newrect.Y, newrect.Z + CGraphics.ZOffset); + GL.End(); + GL.PopMatrix(); + GL.Disable(EnableCap.Blend); } - GL.Vertex3(rect.X, rect.Y, rect.Z + CGraphics.ZOffset); - GL.Vertex3(rect.X, rect.Y + rect.H, rect.Z + CGraphics.ZOffset); - GL.Vertex3(rect.X + rect.W, rect.Y + rect.H, rect.Z + CGraphics.ZOffset); - GL.Vertex3(rect.X + rect.W, rect.Y, rect.Z + CGraphics.ZOffset); - GL.End(); - GL.PopMatrix(); - GL.Disable(EnableCap.Blend); } public void DrawRectReflection(SColorF color, SRectF rect, float space, float height) diff --git a/Vocaluxe/Lib/Draw/IDraw.cs b/Vocaluxe/Lib/Draw/IDraw.cs index 5b362a49..1fc3fd7d 100644 --- a/Vocaluxe/Lib/Draw/IDraw.cs +++ b/Vocaluxe/Lib/Draw/IDraw.cs @@ -49,13 +49,13 @@ namespace Vocaluxe.Lib.Draw void RemoveTexture(ref CTextureRef texture); // Basic Draw Methods - void DrawRect(SColorF color, SRectF rect); + void DrawRect(SColorF color, SRectF rect, bool allMonitors = true); void DrawRectReflection(SColorF color, SRectF rect, float space, float height); - void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, bool mirrored = false); - void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false); - void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, float begin, float end); + void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, bool mirrored = false, bool allMonitors = true); + void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false, bool allMonitors = true); + void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, float begin, float end, bool allMonitors = true); - void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, float space, float height); + void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, float space, float height, bool allMonitors = true); } } \ No newline at end of file diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs index 2996aa4e..4c37016e 100644 --- a/Vocaluxe/Screens/CScreenSing.cs +++ b/Vocaluxe/Screens/CScreenSing.cs @@ -54,8 +54,8 @@ namespace Vocaluxe.Screens private const string _TextDuetName1 = "TextDuetName1"; private const string _TextDuetName2 = "TextDuetName2"; private const string _TextMedleyCountdown = "TextMedleyCountdown"; - private string[,] _TextScores; - private string[,] _TextNames; + private string[,,] _TextScores; + private string[,,] _TextNames; private const string _StaticSongText = "StaticSongText"; private const string _StaticLyrics = "StaticLyrics"; @@ -71,10 +71,10 @@ namespace Vocaluxe.Screens private const string _StaticLyricHelperTop = "StaticLyricHelperTop"; private const string _StaticPauseBG = "StaticPauseBG"; - private string[,] _StaticScores; - private string[,] _StaticAvatars; + private string[,,] _StaticScores; + private string[,,] _StaticAvatars; - private string[,] _ProgressBarsRating; + private string[,,] _ProgressBarsRating; private const string _ButtonCancel = "ButtonCancel"; private const string _ButtonContinue = "ButtonContinue"; @@ -89,6 +89,14 @@ namespace Vocaluxe.Screens private const string _SingBars = "SingBars"; + private string[] _PlayerTextScore; + private string[] _PlayerTextName; + private string[] _PlayerProgressBarRating; + private string[] _PlayerStaticScore; + private string[] _PlayerStaticAvatar; + private List[] _StaticsExtra; + private List[] _TextsExtra; + private bool _DynamicLyricsTop; private bool _DynamicLyricsBottom; @@ -131,7 +139,7 @@ namespace Vocaluxe.Screens { base.Init(); - var texts = new List {_TextSongName, _TextTime, _TextPause, _TextDuetName1, _TextDuetName2, _TextMedleyCountdown}; + var texts = new List { _TextSongName, _TextTime, _TextPause, _TextDuetName1, _TextDuetName2, _TextMedleyCountdown }; _BuildTextStrings(texts); _ThemeTexts = texts.ToArray(); @@ -152,14 +160,20 @@ namespace Vocaluxe.Screens _StaticPauseBG }; _BuildStaticStrings(ref statics); + _ThemeStatics = statics.ToArray(); var progressbars = new List(); _BuildProgressBarStrings(ref progressbars); _ThemeProgressBars = progressbars.ToArray(); - _ThemeButtons = new string[] {_ButtonCancel, _ButtonContinue, _ButtonSkip}; - _ThemeLyrics = new string[] {_LyricMain, _LyricSub, _LyricMainDuet, _LyricSubDuet, _LyricMainTop, _LyricSubTop}; - _ThemeSingNotes = new string[] {_SingBars}; + _CreatePlayerStatics(); + _CreatePlayerStrings(); + _CreateProgressBars(); + _AssignPlayerElements(); + + _ThemeButtons = new string[] { _ButtonCancel, _ButtonContinue, _ButtonSkip }; + _ThemeLyrics = new string[] { _LyricMain, _LyricSub, _LyricMainDuet, _LyricSubDuet, _LyricMainTop, _LyricSubTop }; + _ThemeSingNotes = new string[] { _SingBars }; _TimeRects = new List(); _TimerSongText = new Stopwatch(); @@ -341,16 +355,16 @@ namespace Vocaluxe.Screens if (CConfig.Config.Theme.FadePlayerInfo == EFadePlayerInfo.TR_CONFIG_FADEPLAYERINFO_INFO || CConfig.Config.Theme.FadePlayerInfo == EFadePlayerInfo.TR_CONFIG_FADEPLAYERINFO_ALL) { - _Statics[_StaticAvatars[p, CGame.NumPlayers - 1]].Alpha = alpha[CGame.Players[p].VoiceNr * 2]; - _Texts[_TextNames[p, CGame.NumPlayers - 1]].Alpha = alpha[CGame.Players[p].VoiceNr * 2]; + _Statics[_PlayerStaticAvatar[p]].Alpha = alpha[CGame.Players[p].VoiceNr * 2]; + _Texts[_PlayerTextName[p]].Alpha = alpha[CGame.Players[p].VoiceNr * 2]; } if (CConfig.Config.Theme.FadePlayerInfo == EFadePlayerInfo.TR_CONFIG_FADEPLAYERINFO_ALL) { - _Statics[_StaticScores[p, CGame.NumPlayers - 1]].Alpha = alpha[CGame.Players[p].VoiceNr * 2]; - _Statics[_StaticAvatars[p, CGame.NumPlayers - 1]].Alpha = alpha[CGame.Players[p].VoiceNr * 2]; - _Texts[_TextNames[p, CGame.NumPlayers - 1]].Alpha = alpha[CGame.Players[p].VoiceNr * 2]; - _Texts[_TextScores[p, CGame.NumPlayers - 1]].Alpha = alpha[CGame.Players[p].VoiceNr * 2]; - _ProgressBars[_ProgressBarsRating[p, CGame.NumPlayers - 1]].Alpha = alpha[CGame.Players[p].VoiceNr * 2]; + _Statics[_PlayerStaticScore[p]].Alpha = alpha[CGame.Players[p].VoiceNr * 2]; + _Statics[_PlayerStaticAvatar[p]].Alpha = alpha[CGame.Players[p].VoiceNr * 2]; + _Texts[_PlayerTextName[p]].Alpha = alpha[CGame.Players[p].VoiceNr * 2]; + _Texts[_PlayerTextScore[p]].Alpha = alpha[CGame.Players[p].VoiceNr * 2]; + _ProgressBars[_PlayerProgressBarRating[p]].Alpha = alpha[CGame.Players[p].VoiceNr * 2]; } } @@ -374,7 +388,7 @@ namespace Vocaluxe.Screens for (int p = 0; p < CGame.NumPlayers; p++) { string fmtString = (CGame.Players[p].Points < 10000) ? "0000" : "00000"; - _Texts[_TextScores[p, CGame.NumPlayers - 1]].Text = CGame.Players[p].Points.ToString(fmtString); + _Texts[_PlayerTextScore[p]].Text = CGame.Players[p].Points.ToString(fmtString); } if (_CurrentVideo != null && !_FadeOut && CConfig.Config.Video.VideosInSongs == EOffOn.TR_CONFIG_ON) @@ -390,6 +404,14 @@ namespace Vocaluxe.Screens { base.OnShow(); + _InitiatePlayerStatics(); + _InitiatePlayerStrings(); + _InitiateProgressBars(); + if (_StaticsExtra == null) + _CreateExtraStatics(); + if (_TextsExtra == null) + _CreateExtraTexts(); + _FadeOut = false; _CurrentVideo = null; @@ -405,12 +427,17 @@ namespace Vocaluxe.Screens _TimeRects.Clear(); _SingNotes[_SingBars].Init(0); + _AssignPlayerElements(); foreach (CLyric lyric in _Lyrics) lyric.LyricStyle = CConfig.Config.Theme.LyricStyle; for (int p = 0; p < CGame.NumPlayers; p++) - _Statics[_StaticAvatars[p, CGame.NumPlayers - 1]].Aspect = EAspect.Crop; + { + _Statics[_PlayerStaticAvatar[p]].Aspect = EAspect.Crop; + _Texts[_PlayerTextScore[p]].Color = new SColorF(CBase.Themes.GetPlayerColor(p + 1), _Texts[_PlayerTextScore[p]].Color.A); + } + _SetVisibility(); _UpdateAvatars(); @@ -585,13 +612,13 @@ namespace Vocaluxe.Screens } else { - for (int i = 0; i < CGame.NumPlayers; i++) - CGame.Players [i].VoiceNr = voiceAssignments [i]; + for (int i = 0; i < CGame.NumPlayers; i++) + CGame.Players[i].VoiceNr = voiceAssignments[i]; } } //Attention: This needs to be done after player-assignment! - _SingNotes[_SingBars].Init(CGame.NumPlayers); + _SingNotes[_SingBars].Init(CGame.NumPlayers, CConfig.Config.Graphics.NumScreens); _DynamicLyricsTop = false; _DynamicLyricsBottom = false; @@ -605,7 +632,7 @@ namespace Vocaluxe.Screens } for (int p = 0; p < CGame.NumPlayers; p++) - _ProgressBars[_ProgressBarsRating[p, CGame.NumPlayers - 1]].Reset(); + _ProgressBars[_PlayerProgressBarRating[p]].Reset(); _SetDuetLyricsVisibility(song.IsDuet); _SetNormalLyricsVisibility(); @@ -816,8 +843,8 @@ namespace Vocaluxe.Screens private void _BuildTextStrings(List texts) { - _TextScores = new string[CSettings.MaxNumPlayer,CSettings.MaxNumPlayer]; - _TextNames = new string[CSettings.MaxNumPlayer,CSettings.MaxNumPlayer]; + _TextScores = new string[CSettings.MaxNumScreens, CSettings.MaxNumPlayer, CSettings.MaxNumPlayer]; + _TextNames = new string[CSettings.MaxNumScreens, CSettings.MaxNumPlayer, CSettings.MaxNumPlayer]; for (int numplayer = 0; numplayer < CSettings.MaxNumPlayer; numplayer++) { @@ -826,11 +853,57 @@ namespace Vocaluxe.Screens if (player <= numplayer) { string target = "P" + (player + 1) + "N" + (numplayer + 1); - _TextScores[player, numplayer] = "TextScore" + target; - _TextNames[player, numplayer] = "TextName" + target; + for (int screen = 0; screen < CSettings.MaxNumScreens; screen++) + { + _TextScores[screen, player, numplayer] = "TextScoreS" + (screen + 1) + target; + _TextNames[screen, player, numplayer] = "TextNameS" + (screen + 1) + target; + } + texts.Add("TextScore" + target); + texts.Add("TextName" + target); - texts.Add(_TextScores[player, numplayer]); - texts.Add(_TextNames[player, numplayer]); + } + } + } + } + + private void _CreatePlayerStrings() + { + for (int screen = 0; screen < CSettings.MaxNumScreens; screen++) + { + for (int numplayer = 0; numplayer < CSettings.MaxNumPlayer; numplayer++) + { + for (int player = 0; player < CSettings.MaxNumPlayer; player++) + { + if (player <= numplayer) + { + string target = "P" + (player + 1) + "N" + (numplayer + 1); + _AddText(GetNewText(), "TextScoreS" + (screen + 1) + "P" + (player + 1) + "N" + (numplayer + 1)); + _AddText(GetNewText(), "TextNameS" + (screen + 1) + "P" + (player + 1) + "N" + (numplayer + 1)); + } + } + } + } + } + + private void _InitiatePlayerStrings() + { + for (int screen = 0; screen < CSettings.MaxNumScreens; screen++) + { + for (int numplayer = 0; numplayer < CSettings.MaxNumPlayer; numplayer++) + { + for (int player = 0; player < CSettings.MaxNumPlayer; player++) + { + if (player <= numplayer) + { + string target = "P" + (player + 1) + "N" + (numplayer + 1); + _Texts["TextName" + target].Visible = false; + _Texts["TextNameS" + (screen + 1) + target] = GetNewText(_Texts["TextName" + target]); + _Texts["TextNameS" + (screen + 1) + target].X += screen * CSettings.RenderW; + + _Texts["TextScore" + target].Visible = false; + _Texts["TextScoreS" + (screen + 1) + target] = GetNewText(_Texts["TextScore" + target]); + _Texts["TextScoreS" + (screen + 1) + target].X += screen * CSettings.RenderW; + } } } } @@ -838,8 +911,8 @@ namespace Vocaluxe.Screens private void _BuildStaticStrings(ref List statics) { - _StaticScores = new string[CSettings.MaxNumPlayer, CSettings.MaxNumPlayer]; - _StaticAvatars = new string[CSettings.MaxNumPlayer, CSettings.MaxNumPlayer]; + _StaticScores = new string[CSettings.MaxNumScreens, CSettings.MaxNumPlayer, CSettings.MaxNumPlayer]; + _StaticAvatars = new string[CSettings.MaxNumScreens, CSettings.MaxNumPlayer, CSettings.MaxNumPlayer]; for (int numplayer = 0; numplayer < CSettings.MaxNumPlayer; numplayer++) { @@ -848,11 +921,57 @@ namespace Vocaluxe.Screens if (player <= numplayer) { string target = "P" + (player + 1) + "N" + (numplayer + 1); - _StaticScores[player, numplayer] = "StaticScore" + target; - _StaticAvatars[player, numplayer] = "StaticAvatar" + target; + for (int screen = 0; screen < CSettings.MaxNumScreens; screen++) + { + _StaticScores[screen, player, numplayer] = "StaticScoreS" + (screen + 1) + target; + _StaticAvatars[screen, player, numplayer] = "StaticAvatarS" + (screen + 1) + target; + } + statics.Add("StaticScore" + target); + statics.Add("StaticAvatar" + target); - statics.Add(_StaticScores[player, numplayer]); - statics.Add(_StaticAvatars[player, numplayer]); + } + } + } + } + + private void _CreatePlayerStatics() + { + for (int screen = 0; screen < CSettings.MaxNumScreens; screen++) + { + for (int numplayer = 0; numplayer < CSettings.MaxNumPlayer; numplayer++) + { + for (int player = 0; player < CSettings.MaxNumPlayer; player++) + { + if (player <= numplayer) + { + string target = "P" + (player + 1) + "N" + (numplayer + 1); + _AddStatic(GetNewStatic(), "StaticScoreS" + (screen + 1) + "P" + (player + 1) + "N" + (numplayer + 1)); + _AddStatic(GetNewStatic(), "StaticAvatarS" + (screen + 1) + "P" + (player + 1) + "N" + (numplayer + 1)); + } + } + } + } + } + + private void _InitiatePlayerStatics() + { + for (int screen = 0; screen < CSettings.MaxNumScreens; screen++) + { + for (int numplayer = 0; numplayer < CSettings.MaxNumPlayer; numplayer++) + { + for (int player = 0; player < CSettings.MaxNumPlayer; player++) + { + if (player <= numplayer) + { + string target = "P" + (player + 1) + "N" + (numplayer + 1); + _Statics["StaticAvatar" + target].Visible = false; + _Statics["StaticAvatarS" + (screen + 1) + target] = GetNewStatic(_Statics["StaticAvatar" + target]); + _Statics["StaticAvatarS" + (screen + 1) + target].X += screen * CSettings.RenderW; + + _Statics["StaticScore" + target].Visible = false; + _Statics["StaticScoreS" + (screen + 1) + target] = GetNewStatic(_Statics["StaticScore" + target]); + _Statics["StaticScoreS" + (screen + 1) + target].X += screen * CSettings.RenderW; + } } } } @@ -860,22 +979,124 @@ namespace Vocaluxe.Screens private void _BuildProgressBarStrings(ref List progressbars) { - _ProgressBarsRating = new string[CSettings.MaxNumPlayer, CSettings.MaxNumPlayer]; - - for (int numplayer = 0; numplayer < CSettings.MaxNumPlayer; numplayer++) + _ProgressBarsRating = new string[CSettings.MaxNumScreens, CSettings.MaxNumPlayer, CSettings.MaxNumPlayer]; + for (int screen = 0; screen < CSettings.MaxNumScreens; screen++) { - for (int player = 0; player < CSettings.MaxNumPlayer; player++) + for (int numplayer = 0; numplayer < CSettings.MaxNumPlayer; numplayer++) { - if (player <= numplayer) + for (int player = 0; player < CSettings.MaxNumPlayer; player++) { - string target = "P" + (player + 1) + "N" + (numplayer + 1); - _ProgressBarsRating[player, numplayer] = "ProgressBarRating" + target; - progressbars.Add(_ProgressBarsRating[player, numplayer]); + if (player <= numplayer) + { + string target = "P" + (player + 1) + "N" + (numplayer + 1); + _ProgressBarsRating[screen, player, numplayer] = "ProgressBarRatingS" + (screen + 1) + target; + progressbars.Add("ProgressBarRating" + target); + } } } } } + private void _CreateProgressBars() + { + for (int screen = 0; screen < CSettings.MaxNumScreens; screen++) + { + for (int numplayer = 0; numplayer < CSettings.MaxNumPlayer; numplayer++) + { + for (int player = 0; player < CSettings.MaxNumPlayer; player++) + { + if (player <= numplayer) + { + string target = "P" + (player + 1) + "N" + (numplayer + 1); + _AddProgressBar(GetNewProgressBar(), "ProgressBarRatingS" + (screen + 1) + "P" + (player + 1) + "N" + (numplayer + 1)); + } + } + } + } + } + + private void _InitiateProgressBars() + { + for (int screen = 0; screen < CSettings.MaxNumScreens; screen++) + { + for (int numplayer = 0; numplayer < CSettings.MaxNumPlayer; numplayer++) + { + for (int player = 0; player < CSettings.MaxNumPlayer; player++) + { + if (player <= numplayer) + { + string target = "P" + (player + 1) + "N" + (numplayer + 1); + _ProgressBars["ProgressBarRating" + target].Visible = false; + _ProgressBars["ProgressBarRatingS" + (screen + 1) + target] = GetNewProgressBar(_ProgressBars["ProgressBarRating" + target]); + _ProgressBars["ProgressBarRatingS" + (screen + 1) + target].X += screen * CSettings.RenderW; + } + } + } + } + } + + private void _CreateExtraStatics() + { + _StaticsExtra = new List[CSettings.MaxNumScreens]; + + List extraStatics = new List(); + + foreach (CStatic se in _Statics) + { + if (se.GetThemeName() != null && se.GetThemeName().StartsWith("StaticExtra")) + { + extraStatics.Add(se.GetThemeName()); + _Statics[se.GetThemeName()].Visible = false; + } + } + + for (int screen = 0; screen < CSettings.MaxNumScreens; screen++) + { + _StaticsExtra[screen] = new List(); + foreach (string es in extraStatics) + { + string name = "S" + (screen + 1) + es; + _AddStatic(GetNewStatic(), name); + _Statics[name] = GetNewStatic(_Statics[es]); + _Statics[name].X += screen * CSettings.RenderW; + _Statics[name].AllMonitors = false; + _StaticsExtra[screen].Add(name); + } + + } + } + + private void _CreateExtraTexts() + { + _TextsExtra = new List[CSettings.MaxNumScreens]; + + List extraTexts = new List(); + + foreach (CText te in _Texts) + { + if (te.GetThemeName() != null && te.GetThemeName().StartsWith("TextExtra")) + { + extraTexts.Add(te.GetThemeName()); + _Texts[te.GetThemeName()].Visible = false; + } + } + + for (int screen = 0; screen < CSettings.MaxNumScreens; screen++) + { + _TextsExtra[screen] = new List(); + foreach (string et in extraTexts) + { + string name = "S" + (screen + 1) + et; + _AddText(GetNewText(), name); + _Texts[name] = GetNewText(_Texts[et]); + _Texts[name].X += screen * CSettings.RenderW; + _Texts[name].AllMonitors = false; + _TextsExtra[screen].Add(name); + } + + } + } + private void _SetVisibility() { _Statics[_StaticLyricsDuet].Visible = false; @@ -890,47 +1111,71 @@ namespace Vocaluxe.Screens _Texts[_TextDuetName1].Visible = false; _Texts[_TextDuetName2].Visible = false; - List staticsExtra = new List (); - List textsExtra = new List (); + int screenPlayers = CGame.NumPlayers / CConfig.GetNumScreens(); + int remainingScreenPlayers = CGame.NumPlayers - (screenPlayers * CConfig.GetNumScreens()); - //Everything Static or Text with Extra should be only visible - //If Player-Number matches CGame.NumPlayers - foreach(CStatic st in _Statics) - if(st.GetThemeName().StartsWith("StaticExtra")) - staticsExtra.Add(st.GetThemeName()); - - foreach(CText tx in _Texts) - if(tx.GetThemeName().StartsWith("TextExtra")) - textsExtra.Add(tx.GetThemeName()); - - string curN = "N"+(CGame.NumPlayers); - foreach (string st in staticsExtra) + for (int screen = 0; screen < CSettings.MaxNumScreens; screen++) { - string n = st.Substring(st.Length - 2); - _Statics[st].Visible = n == curN; - } + int currentScreenPlayers = screenPlayers; - foreach (string tx in textsExtra) - { - string n = tx.Substring(tx.Length - 2); - _Texts[tx].Visible = n == curN; - } - - for (int numplayer = 0; numplayer < CSettings.MaxNumPlayer; numplayer++) - { - for (int player = 0; player < CSettings.MaxNumPlayer && player <= numplayer; player++) + if (remainingScreenPlayers > 0) { - bool isVisible = numplayer + 1 == CGame.NumPlayers && player <= CGame.NumPlayers; - _Texts[_TextScores[player, numplayer]].Visible = isVisible; - _Texts[_TextNames[player, numplayer]].Visible = isVisible && - (CConfig.Config.Theme.PlayerInfo == EPlayerInfo.TR_CONFIG_PLAYERINFO_BOTH || - CConfig.Config.Theme.PlayerInfo == EPlayerInfo.TR_CONFIG_PLAYERINFO_NAME); - _Statics[_StaticScores[player, numplayer]].Visible = isVisible; - _Statics[_StaticAvatars[player, numplayer]].Visible = isVisible && - (CConfig.Config.Theme.PlayerInfo == EPlayerInfo.TR_CONFIG_PLAYERINFO_BOTH || - CConfig.Config.Theme.PlayerInfo == EPlayerInfo.TR_CONFIG_PLAYERINFO_AVATAR); - _ProgressBars[_ProgressBarsRating[player, numplayer]].Visible = isVisible; + currentScreenPlayers++; + remainingScreenPlayers--; } + + string curN = "N" + currentScreenPlayers; + string curS = "S" + (screen + 1); + + foreach (string se in _StaticsExtra[screen]) + { + string n = se.Substring(se.Length - 2); + string s = se.Substring(0, 2); + //Make StaticExtra elements with matching player number and active screen visible + if (n == curN && s == curS && screen < CConfig.GetNumScreens()) + _Statics[se].Visible = true; + else + _Statics[se].Visible = false; + } + + foreach (string te in _TextsExtra[screen]) + { + string n = te.Substring(te.Length - 2); + string s = te.Substring(0, 2); + //Make TextExtra elements with matching player number and active screen visible + if (n == curN && s == curS && screen < CConfig.GetNumScreens()) + _Texts[te].Visible = true; + else + _Texts[te].Visible = false; + } + + for (int numplayer = 0; numplayer < CSettings.MaxNumPlayer; numplayer++) + { + for (int player = 0; player < CSettings.MaxNumPlayer && player <= numplayer; player++) + { + _Texts[_TextScores[screen, player, numplayer]].AllMonitors = false; + _Texts[_TextScores[screen, player, numplayer]].Visible = false; + _Texts[_TextNames[screen, player, numplayer]].AllMonitors = false; + _Texts[_TextNames[screen, player, numplayer]].Visible = false; + _Statics[_StaticScores[screen, player, numplayer]].AllMonitors = false; + _Statics[_StaticScores[screen, player, numplayer]].Visible = false; + _Statics[_StaticAvatars[screen, player, numplayer]].AllMonitors = false; + _Statics[_StaticAvatars[screen, player, numplayer]].Visible = false; + _ProgressBars[_ProgressBarsRating[screen, player, numplayer]].AllMonitors = false; + _ProgressBars[_ProgressBarsRating[screen, player, numplayer]].Visible = false; + } + } + } + + for (int player = 0; player < CGame.NumPlayers; player++) + { + _Texts[_PlayerTextScore[player]].Visible = true; + _Texts[_PlayerTextName[player]].Visible = (CConfig.Config.Theme.PlayerInfo == EPlayerInfo.TR_CONFIG_PLAYERINFO_BOTH || + CConfig.Config.Theme.PlayerInfo == EPlayerInfo.TR_CONFIG_PLAYERINFO_NAME); + _Statics[_PlayerStaticScore[player]].Visible = true; + _Statics[_PlayerStaticAvatar[player]].Visible = (CConfig.Config.Theme.PlayerInfo == EPlayerInfo.TR_CONFIG_PLAYERINFO_BOTH || + CConfig.Config.Theme.PlayerInfo == EPlayerInfo.TR_CONFIG_PLAYERINFO_AVATAR); + _ProgressBars[_PlayerProgressBarRating[player]].Visible = true; } _Lyrics[_LyricMain].Alpha = 0f; @@ -1364,7 +1609,7 @@ namespace Vocaluxe.Screens { foreach (CSongLine line in voice.Lines.Where(line => line.VisibleInTimeLine)) { - var trect = new STimeRect {StartBeat = line.FirstNoteBeat, EndBeat = line.EndBeat}; + var trect = new STimeRect { StartBeat = line.FirstNoteBeat, EndBeat = line.EndBeat }; trect.Rect = GetNewStatic(null, new SColorF(1f, 1f, 1f, 1f), new SRectF( @@ -1386,9 +1631,9 @@ namespace Vocaluxe.Screens for (int i = 0; i < CGame.NumPlayers; i++) { if (CProfiles.IsProfileIDValid(CGame.Players[i].ProfileID)) - _Statics[_StaticAvatars[i, CGame.NumPlayers - 1]].Texture = CProfiles.GetAvatarTextureFromProfile(CGame.Players[i].ProfileID); + _Statics[_PlayerStaticAvatar[i]].Texture = CProfiles.GetAvatarTextureFromProfile(CGame.Players[i].ProfileID); else - _Statics[_StaticAvatars[i, CGame.NumPlayers - 1]].Visible = false; + _Statics[_PlayerStaticAvatar[i]].Visible = false; } } @@ -1397,9 +1642,64 @@ namespace Vocaluxe.Screens for (int i = 0; i < CGame.NumPlayers; i++) { if (CProfiles.IsProfileIDValid(CGame.Players[i].ProfileID)) - _Texts[_TextNames[i, CGame.NumPlayers - 1]].Text = CProfiles.GetPlayerName(CGame.Players[i].ProfileID); + _Texts[_PlayerTextName[i]].Text = CProfiles.GetPlayerName(CGame.Players[i].ProfileID); else - _Texts[_TextNames[i, CGame.NumPlayers - 1]].Visible = false; + _Texts[_PlayerTextName[i]].Visible = false; + } + } + private void _AssignPlayerElements() + { + _PlayerTextScore = new String[CGame.NumPlayers]; + _PlayerTextName = new String[CGame.NumPlayers]; + _PlayerStaticAvatar = new String[CGame.NumPlayers]; + _PlayerStaticScore = new String[CGame.NumPlayers]; + _PlayerProgressBarRating = new String[CGame.NumPlayers]; + + int screenPlayers = CGame.NumPlayers / CConfig.GetNumScreens(); + int remainingPlayers = CGame.NumPlayers - (screenPlayers * CConfig.GetNumScreens()); + int player = 0; + + for (int s = 0; s < CConfig.GetNumScreens(); s++) + { + for (int p = 0; p < screenPlayers; p++) + { + if (remainingPlayers > 0) + { + _PlayerTextScore[player] = _TextScores[s, p, screenPlayers]; + _PlayerTextName[player] = _TextNames[s, p, screenPlayers]; + _PlayerProgressBarRating[player] = _ProgressBarsRating[s, p, screenPlayers]; + _PlayerStaticAvatar[player] = _StaticAvatars[s, p, screenPlayers]; + _PlayerStaticScore[player++] = _StaticScores[s, p, screenPlayers]; + if (p == screenPlayers - 1) + { + _PlayerTextScore[player] = _TextScores[s, p + 1, screenPlayers]; + _PlayerTextName[player] = _TextNames[s, p + 1, screenPlayers]; + _PlayerProgressBarRating[player] = _ProgressBarsRating[s, p + 1, screenPlayers]; + _PlayerStaticAvatar[player] = _StaticAvatars[s, p + 1, screenPlayers]; + _PlayerStaticScore[player++] = _StaticScores[s, p + 1, screenPlayers]; + remainingPlayers--; + } + } + else + { + _PlayerTextScore[player] = _TextScores[s, p, screenPlayers - 1]; + _PlayerTextName[player] = _TextNames[s, p, screenPlayers - 1]; + _PlayerProgressBarRating[player] = _ProgressBarsRating[s, p, screenPlayers - 1]; + _PlayerStaticAvatar[player] = _StaticAvatars[s, p, screenPlayers - 1]; + _PlayerStaticScore[player++] = _StaticScores[s, p, screenPlayers - 1]; + } + + } + //Handle when players < screens + if (screenPlayers == 0 && remainingPlayers > 0) + { + _PlayerTextScore[player] = _TextScores[s, 0, 0]; + _PlayerTextName[player] = _TextNames[s, 0, 0]; + _PlayerProgressBarRating[player] = _ProgressBarsRating[s, 0, 0]; + _PlayerStaticAvatar[player] = _StaticAvatars[s, 0, 0]; + _PlayerStaticScore[player++] = _StaticScores[s, 0, 0]; + remainingPlayers--; + } } } @@ -1407,7 +1707,7 @@ namespace Vocaluxe.Screens { for (int i = 0; i < CGame.NumPlayers; i++) { - _ProgressBars[_ProgressBarsRating[i, CGame.NumPlayers - 1]].Progress = (float)CGame.Players[i].Rating; + _ProgressBars[_PlayerProgressBarRating[i]].Progress = (float)CGame.Players[i].Rating; } } } diff --git a/VocaluxeLib/IBasic.cs b/VocaluxeLib/IBasic.cs index 1ec80d1f..26cb64bf 100644 --- a/VocaluxeLib/IBasic.cs +++ b/VocaluxeLib/IBasic.cs @@ -82,6 +82,7 @@ namespace VocaluxeLib int GetNumNoteLines(); int GetMaxNumPlayer(); + int GetMaxNumScreens(); float GetDefaultMedleyFadeInTime(); float GetDefaultMedleyFadeOutTime(); @@ -134,17 +135,17 @@ namespace VocaluxeLib public interface IDrawing { void DrawTexture(CTextureRef texture, SRectF rect); - void DrawTexture(CTextureRef texture, SRectF rect, SColorF color); - void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false); + void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, bool allMonitors = true); + void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false, bool allMonitors = true); void DrawTexture(CTextureRef textureRef, SRectF bounds, EAspect aspect); void DrawTexture(CTextureRef textureRef, SRectF bounds, EAspect aspect, SColorF color); - void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, float reflectionSpace, float reflectionHeight); + void DrawTextureReflection(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, float reflectionSpace, float reflectionHeight, bool allMonitors = true); CTextureRef AddTexture(string fileName); CTextureRef EnqueueTexture(string fileName); void RemoveTexture(ref CTextureRef texture); - void DrawRect(SColorF color, SRectF rect); + void DrawRect(SColorF color, SRectF rect, bool allMonitors = true); void DrawRectReflection(SColorF color, SRectF rect, float space, float height); } @@ -173,7 +174,7 @@ namespace VocaluxeLib { RectangleF GetTextBounds(CText text); - void DrawText(string text, CFont font, float x, float y, float z, SColorF color); + void DrawText(string text, CFont font, float x, float y, float z, SColorF color, bool allMonitors = true); void DrawTextReflection(string text, CFont font, float x, float y, float z, SColorF color, float reflectionSpace, float reflectionHeight); void DrawText(string text, CFont font, float x, float y, float z, SColorF color, float begin, float end); } diff --git a/VocaluxeLib/Menu/CParticle.cs b/VocaluxeLib/Menu/CParticle.cs index 1d7d983b..580380a2 100644 --- a/VocaluxeLib/Menu/CParticle.cs +++ b/VocaluxeLib/Menu/CParticle.cs @@ -265,14 +265,14 @@ namespace VocaluxeLib.Menu _Timer.Start(); } - public void Draw() + public void Draw(bool allMonitors = true) { // ReSharper disable ConvertIfStatementToConditionalTernaryExpression if (!String.IsNullOrEmpty(_TextureName)) // ReSharper restore ConvertIfStatementToConditionalTernaryExpression - CBase.Drawing.DrawTexture(CBase.Themes.GetSkinTexture(_TextureName, _PartyModeID), _Rect, new SColorF(_Color.R, _Color.G, _Color.B, _Color.A * Alpha2 * _Alpha)); + CBase.Drawing.DrawTexture(CBase.Themes.GetSkinTexture(_TextureName, _PartyModeID), _Rect, new SColorF(_Color.R, _Color.G, _Color.B, _Color.A * Alpha2 * _Alpha), allMonitors); else - CBase.Drawing.DrawTexture(_Texture, _Rect, new SColorF(_Color.R, _Color.G, _Color.B, _Color.A * Alpha2 * _Alpha)); + CBase.Drawing.DrawTexture(_Texture, _Rect, new SColorF(_Color.R, _Color.G, _Color.B, _Color.A * Alpha2 * _Alpha), allMonitors); } } } \ No newline at end of file diff --git a/VocaluxeLib/Menu/CParticleEffect.cs b/VocaluxeLib/Menu/CParticleEffect.cs index e7ca4ae0..7f158ce8 100644 --- a/VocaluxeLib/Menu/CParticleEffect.cs +++ b/VocaluxeLib/Menu/CParticleEffect.cs @@ -26,7 +26,8 @@ namespace VocaluxeLib.Menu [XmlType("ParticleEffect")] public struct SThemeParticleEffect { - [XmlAttribute(AttributeName = "Name")] public string Name; + [XmlAttribute(AttributeName = "Name")] + public string Name; public string Skin; public SRectF Rect; @@ -34,6 +35,7 @@ namespace VocaluxeLib.Menu public EParticleType Type; public float Size; public int MaxNumber; + public bool? AllMonitors; } public enum EParticleType @@ -59,6 +61,8 @@ namespace VocaluxeLib.Menu public float Alpha = 1f; + public bool AllMonitors = true; + public string GetThemeName() { return _Theme.Name; @@ -264,7 +268,7 @@ namespace VocaluxeLib.Menu foreach (CParticle star in _Stars) { star.Alpha2 = Alpha; - star.Draw(); + star.Draw(AllMonitors); } } diff --git a/VocaluxeLib/Menu/CProgressBar.cs b/VocaluxeLib/Menu/CProgressBar.cs index 476ca29f..f9413737 100644 --- a/VocaluxeLib/Menu/CProgressBar.cs +++ b/VocaluxeLib/Menu/CProgressBar.cs @@ -48,6 +48,7 @@ namespace VocaluxeLib.Menu public SRectF Rect; [XmlArrayItem("ProgressColor"), XmlArray] public List ProgressColors; public SReflection? Reflection; + public bool? AllMonitors; } public sealed class CProgressBar : CMenuElementBase, IMenuElement, IThemeable @@ -108,6 +109,11 @@ namespace VocaluxeLib.Menu set { _TextureProgressRight = value; } } + private EDirection _Direction; + private EOffOn _AnimateMovement; + private EOffOn _AnimateColoring; + private List _ProgressColors; + public SColorF ColorBackground; public SColorF ColorForeground; @@ -115,6 +121,8 @@ namespace VocaluxeLib.Menu public float ReflectionSpace; public float ReflectionHeight; + public bool AllMonitors = true; + public float Alpha = 1; private float _ProgressTarget; @@ -165,6 +173,10 @@ namespace VocaluxeLib.Menu _TextureProgressLeft = pb.TextureProgressLeft; _TextureProgressMid = pb._TextureProgressMid; _TextureProgressRight = pb._TextureProgressRight; + _AnimateMovement = pb._AnimateMovement; + _AnimateColoring = pb._AnimateColoring; + _Direction = pb._Direction; + _ProgressColors = pb._ProgressColors; ColorBackground = pb.ColorBackground; ColorForeground = pb.ColorForeground; @@ -174,6 +186,8 @@ namespace VocaluxeLib.Menu ReflectionSpace = pb.ReflectionHeight; ReflectionHeight = pb.ReflectionSpace; + AllMonitors = pb.AllMonitors; + Alpha = pb.Alpha; Visible = pb.Visible; @@ -185,6 +199,10 @@ namespace VocaluxeLib.Menu _PartyModeID = partyModeID; _Theme = theme; _Theme.ProgressColors.Sort((x, y) => x.From.CompareTo(y.From)); + _ProgressColors = _Theme.ProgressColors; + _Direction = _Theme.Direction; + _AnimateMovement = _Theme.AnimateMovement; + _AnimateColoring = _Theme.AnimateColoring; _UpdateProgress(); ThemeLoaded = true; @@ -195,7 +213,7 @@ namespace VocaluxeLib.Menu { _Animate = animateInit; - _Theme.ProgressColors[0].Color.Get(_PartyModeID, out _ColorProgressLast); + _ProgressColors[0].Color.Get(_PartyModeID, out _ColorProgressLast); } public void Draw() @@ -216,43 +234,43 @@ namespace VocaluxeLib.Menu SColorF color = new SColorF(ColorBackground.R, ColorBackground.G, ColorBackground.B, ColorBackground.A * Alpha); if (_TextureBackground != null) { - CBase.Drawing.DrawTexture(_TextureBackground, Rect, color); + CBase.Drawing.DrawTexture(_TextureBackground, Rect, color, AllMonitors); if (Reflection) - CBase.Drawing.DrawTextureReflection(_TextureBackground, Rect, color, Rect, ReflectionSpace, ReflectionHeight); + CBase.Drawing.DrawTextureReflection(_TextureBackground, Rect, color, Rect, ReflectionSpace, ReflectionHeight, AllMonitors); } //Draw progress color = new SColorF(_ColorProgressCurrent.R, _ColorProgressCurrent.G, _ColorProgressCurrent.B, _ColorProgressCurrent.A * Alpha); if (_TextureProgressBegin != null) { - CBase.Drawing.DrawTexture(_TextureProgressBegin, _RectProgressBegin, color); + CBase.Drawing.DrawTexture(_TextureProgressBegin, _RectProgressBegin, color, AllMonitors); if (Reflection) - CBase.Drawing.DrawTextureReflection(_TextureProgressBegin, _RectProgressBegin, color, _RectProgressBegin, ReflectionSpace, ReflectionHeight); + CBase.Drawing.DrawTextureReflection(_TextureProgressBegin, _RectProgressBegin, color, _RectProgressBegin, ReflectionSpace, ReflectionHeight, AllMonitors); } if (_TextureProgressMid != null) { - CBase.Drawing.DrawTexture(_TextureProgressMid, _RectProgressMid, color); + CBase.Drawing.DrawTexture(_TextureProgressMid, _RectProgressMid, color, AllMonitors); if (Reflection) - CBase.Drawing.DrawTextureReflection(_TextureProgressMid, _RectProgressMid, color, _RectProgressMid, ReflectionSpace, ReflectionHeight); + CBase.Drawing.DrawTextureReflection(_TextureProgressMid, _RectProgressMid, color, _RectProgressMid, ReflectionSpace, ReflectionHeight, AllMonitors); } else CBase.Drawing.DrawRect(_ColorProgressCurrent, _RectProgressMid); if (_TextureProgressEnd != null) { - CBase.Drawing.DrawTexture(_TextureProgressEnd, _RectProgressEnd, color); + CBase.Drawing.DrawTexture(_TextureProgressEnd, _RectProgressEnd, color, AllMonitors); if (Reflection) - CBase.Drawing.DrawTextureReflection(_TextureProgressEnd, _RectProgressEnd, color, _RectProgressEnd, ReflectionSpace, ReflectionHeight); + CBase.Drawing.DrawTextureReflection(_TextureProgressEnd, _RectProgressEnd, color, _RectProgressEnd, ReflectionSpace, ReflectionHeight, AllMonitors); } //Draw foreground color = new SColorF(ColorForeground.R, ColorForeground.G, ColorForeground.B, ColorForeground.A * Alpha); if (_TextureForeground != null) { - CBase.Drawing.DrawTexture(_TextureForeground, Rect, color); + CBase.Drawing.DrawTexture(_TextureForeground, Rect, color, AllMonitors); if (Reflection) - CBase.Drawing.DrawTextureReflection(_TextureForeground, Rect, color, Rect, ReflectionSpace, ReflectionHeight); + CBase.Drawing.DrawTextureReflection(_TextureForeground, Rect, color, Rect, ReflectionSpace, ReflectionHeight, AllMonitors); } } @@ -316,20 +334,20 @@ namespace VocaluxeLib.Menu private void _CheckAnimation() { //Check if animation needs to be started - if (_Theme.AnimateColoring == EOffOn.TR_CONFIG_ON || _Theme.AnimateMovement == EOffOn.TR_CONFIG_ON) + if (_AnimateColoring == EOffOn.TR_CONFIG_ON || _AnimateMovement == EOffOn.TR_CONFIG_ON) { if (!_AnimTimer.IsRunning) { _AnimTimer.Restart(); //Calc animation duration in ms based on rect size and progress change - if (_Theme.Direction == EDirection.Left || _Theme.Direction == EDirection.Right) - _AnimDuration = Math.Max(100f, (_Theme.Rect.W * 0.015f * 1000) * Math.Abs(_ProgressTarget - _ProgressCurrent)); + if (_Direction == EDirection.Left || _Direction == EDirection.Right) + _AnimDuration = Math.Max(100f, (Rect.W * 0.015f * 1000) * Math.Abs(_ProgressTarget - _ProgressCurrent)); else - _AnimDuration = Math.Max(100f, (_Theme.Rect.H * 0.015f * 1000) * Math.Abs(_ProgressTarget - _ProgressCurrent)); + _AnimDuration = Math.Max(100f, (Rect.H * 0.015f * 1000) * Math.Abs(_ProgressTarget - _ProgressCurrent)); } } //Movement animation - if (_Theme.AnimateMovement == EOffOn.TR_CONFIG_ON) + if (_AnimateMovement == EOffOn.TR_CONFIG_ON) _ProgressCurrent = _ProgressLast + (_AnimTimer.ElapsedMilliseconds / _AnimDuration).Clamp(0, 1) * (_ProgressTarget - _ProgressLast); //Check if animation needs to be stopped @@ -346,11 +364,11 @@ namespace VocaluxeLib.Menu private void _UpdateProgressColor() { - foreach (SThemeProgressBarColor col in _Theme.ProgressColors) + foreach (SThemeProgressBarColor col in _ProgressColors) if (col.From < _ProgressTarget) col.Color.Get(_PartyModeID, out _ColorProgressTarget); - if(_Animate && _Theme.AnimateColoring == EOffOn.TR_CONFIG_ON) + if(_Animate && _AnimateColoring == EOffOn.TR_CONFIG_ON) { float animFactor = (_AnimTimer.ElapsedMilliseconds / _AnimDuration).Clamp(0, 1); @@ -365,7 +383,7 @@ namespace VocaluxeLib.Menu private void _UpdateProgressLeft() { - switch (_Theme.Direction) + switch (_Direction) { case EDirection.Right: _TextureProgressBegin = TextureProgressLeft; @@ -403,7 +421,7 @@ namespace VocaluxeLib.Menu private void _UpdateProgressMid() { - switch (_Theme.Direction) + switch (_Direction) { case EDirection.Right: _RectProgressMid = new SRectF(_RectProgressBegin.X + _RectProgressBegin.W, Rect.Y, (Rect.W - 2 * _RectProgressBegin.W) * _ProgressCurrent, Rect.H, Rect.Z); @@ -427,7 +445,7 @@ namespace VocaluxeLib.Menu private void _UpdateProgressRight() { - switch (_Theme.Direction) + switch (_Direction) { case EDirection.Right: _TextureProgressEnd = _TextureProgressRight; diff --git a/VocaluxeLib/Menu/CStatic.cs b/VocaluxeLib/Menu/CStatic.cs index 66091e98..0834d794 100644 --- a/VocaluxeLib/Menu/CStatic.cs +++ b/VocaluxeLib/Menu/CStatic.cs @@ -24,11 +24,13 @@ namespace VocaluxeLib.Menu [XmlType("Static")] public struct SThemeStatic { - [XmlAttribute(AttributeName = "Name")] public string Name; + [XmlAttribute(AttributeName = "Name")] + public string Name; public string Skin; public SThemeColor Color; public SRectF Rect; public SReflection? Reflection; + public bool? AllMonitors; } public sealed class CStatic : CMenuElementBase, IMenuElement, IThemeable @@ -63,6 +65,8 @@ namespace VocaluxeLib.Menu public float ReflectionSpace; public float ReflectionHeight; + public bool AllMonitors = true; + public float Alpha = 1; public EAspect Aspect = EAspect.Stretch; @@ -91,6 +95,7 @@ namespace VocaluxeLib.Menu Reflection = s.Reflection; ReflectionSpace = s.ReflectionHeight; ReflectionHeight = s.ReflectionSpace; + AllMonitors = s.AllMonitors; Alpha = s.Alpha; Visible = s.Visible; @@ -149,9 +154,9 @@ namespace VocaluxeLib.Menu { if (texture != null) { - CBase.Drawing.DrawTexture(texture, rect, color, bounds); + CBase.Drawing.DrawTexture(texture, rect, color, bounds, false, AllMonitors); if (Reflection) - CBase.Drawing.DrawTextureReflection(texture, rect, color, bounds, ReflectionSpace, ReflectionHeight); + CBase.Drawing.DrawTextureReflection(texture, rect, color, bounds, ReflectionSpace, ReflectionHeight, AllMonitors); } else CBase.Drawing.DrawRect(color, rect); @@ -161,7 +166,7 @@ namespace VocaluxeLib.Menu CBase.Drawing.DrawRect(new SColorF(1f, 1f, 1f, 0.5f), rect); } - public void UnloadSkin() {} + public void UnloadSkin() { } public void LoadSkin() { diff --git a/VocaluxeLib/Menu/CText.cs b/VocaluxeLib/Menu/CText.cs index 5f162da6..fb96624a 100644 --- a/VocaluxeLib/Menu/CText.cs +++ b/VocaluxeLib/Menu/CText.cs @@ -24,21 +24,27 @@ namespace VocaluxeLib.Menu [XmlType("Text")] public struct SThemeText { - [XmlAttribute(AttributeName = "Name")] public string Name; + [XmlAttribute(AttributeName = "Name")] + public string Name; public float X; public float Y; public float Z; - [XmlElement("H")] public float FontHeight; - [XmlElement("MaxW")] public float MaxWidth; + [XmlElement("H")] + public float FontHeight; + [XmlElement("MaxW")] + public float MaxWidth; public SThemeColor Color; public SThemeColor SelColor; //for Buttons public EAlignment Align; public EHAlignment ResizeAlign; - [XmlElement("Style")] public EStyle FontStyle; - [XmlElement("Font")] public string FontFamily; + [XmlElement("Style")] + public EStyle FontStyle; + [XmlElement("Font")] + public string FontFamily; public string Text; public SReflection? Reflection; + public bool? AllMonitors; } public sealed class CText : CMenuElementBase, IMenuElement, IThemeable, IFontObserver @@ -161,6 +167,8 @@ namespace VocaluxeLib.Menu private float _ReflectionSpace; private float _ReflectionHeight; + public bool AllMonitors = true; + private string _Text = String.Empty; public string Text { @@ -248,6 +256,7 @@ namespace VocaluxeLib.Menu SelColor = text.SelColor; _ReflectionSpace = text._ReflectionSpace; _ReflectionHeight = text._ReflectionHeight; + AllMonitors = text.AllMonitors; Text = text.Text; Visible = text.Visible; @@ -309,7 +318,7 @@ namespace VocaluxeLib.Menu SColorF currentColor = (Selected) ? SelColor : Color; var color = new SColorF(currentColor.R, currentColor.G, currentColor.B, currentColor.A * Alpha); - CBase.Fonts.DrawText(_Text, CalculatedFont, Rect.X, Rect.Y, Z, color); + CBase.Fonts.DrawText(_Text, CalculatedFont, Rect.X, Rect.Y, Z, color, AllMonitors); if (_ReflectionHeight > 0) CBase.Fonts.DrawTextReflection(_Text, CalculatedFont, Rect.X, Rect.Y, Z, color, _ReflectionSpace, _ReflectionHeight); @@ -354,7 +363,7 @@ namespace VocaluxeLib.Menu Y -= ry; } - public void UnloadSkin() {} + public void UnloadSkin() { } public void LoadSkin() { diff --git a/VocaluxeLib/Menu/SingNotes/CNoteBars.cs b/VocaluxeLib/Menu/SingNotes/CNoteBars.cs index fcf52e20..5e6c50ee 100644 --- a/VocaluxeLib/Menu/SingNotes/CNoteBars.cs +++ b/VocaluxeLib/Menu/SingNotes/CNoteBars.cs @@ -195,7 +195,7 @@ namespace VocaluxeLib.Menu.SingNotes for (int i = 0; i < CBase.Settings.GetNumNoteLines(); i++) { lineRect.Y = (Rect.Y + Rect.H / CBase.Settings.GetNumNoteLines() * (i + 1)) - (lineRect.H / 2); - CBase.Drawing.DrawRect(color, lineRect); + CBase.Drawing.DrawRect(color, lineRect, false); } } @@ -226,7 +226,7 @@ namespace VocaluxeLib.Menu.SingNotes var color = new SColorF(_Color, _Color.A * Alpha); CTextureRef toneHelper = CBase.Themes.GetSkinTexture(_Theme.SkinToneHelper, _PartyModeID); - CBase.Drawing.DrawTexture(toneHelper, drawRect, color); + CBase.Drawing.DrawTexture(toneHelper, drawRect, color, false); } private void _DrawNote(SRectF rect, SColorF color, CTextureRef noteBegin, CTextureRef noteMiddle, CTextureRef noteEnd, float factor) @@ -247,7 +247,7 @@ namespace VocaluxeLib.Menu.SingNotes //Need 2 of them so use minimum int endsW = (int)Math.Min(noteRect.H * noteBegin.OrigAspect, noteRect.W / 2); - CBase.Drawing.DrawTexture(noteBegin, new SRectF(noteRect.X, noteRect.Y, endsW, noteRect.H, noteRect.Z), color); + CBase.Drawing.DrawTexture(noteBegin, new SRectF(noteRect.X, noteRect.Y, endsW, noteRect.H, noteRect.Z), color, false); SRectF middleRect = new SRectF(noteRect.X + endsW, noteRect.Y, noteRect.W - 2 * endsW, noteRect.H, noteRect.Z); @@ -257,14 +257,14 @@ namespace VocaluxeLib.Menu.SingNotes for (int i = 0; i < midCount; ++i) { - CBase.Drawing.DrawTexture(noteMiddle, new SRectF(middleRect.X + (i * midW), noteRect.Y, midW, noteRect.H, noteRect.Z), color); + CBase.Drawing.DrawTexture(noteMiddle, new SRectF(middleRect.X + (i * midW), noteRect.Y, midW, noteRect.H, noteRect.Z), color, false); } SRectF lastMidRect = new SRectF(middleRect.X + midCount * midW, noteRect.Y, middleRect.W - (midCount * midW), noteRect.H, noteRect.Z); - CBase.Drawing.DrawTexture(noteMiddle, new SRectF(middleRect.X + (midCount * midW), middleRect.Y, midW, middleRect.H, middleRect.Z), color, lastMidRect); + CBase.Drawing.DrawTexture(noteMiddle, new SRectF(middleRect.X + (midCount * midW), middleRect.Y, midW, middleRect.H, middleRect.Z), color, lastMidRect, false, false); - CBase.Drawing.DrawTexture(noteEnd, new SRectF(noteRect.X + noteRect.W - endsW, noteRect.Y, endsW, noteRect.H, noteRect.Z), color); + CBase.Drawing.DrawTexture(noteEnd, new SRectF(noteRect.X + noteRect.W - endsW, noteRect.Y, endsW, noteRect.H, noteRect.Z), color, false); } private void _DrawNoteBase(SRectF rect, SColorF color, float factor) @@ -311,6 +311,7 @@ namespace VocaluxeLib.Menu.SingNotes { var numstars = (int)(noteRect.W * 0.25f); var stars = new CParticleEffect(_PartyModeID, numstars, new SColorF(Color.Yellow), noteRect, _Theme.SkinGoldenStar, 20, EParticleType.Star); + stars.AllMonitors = false; _GoldenStars.Add(stars); } @@ -319,6 +320,7 @@ namespace VocaluxeLib.Menu.SingNotes var rect = new SRectF(noteRect.Right, noteRect.Y, 0f, noteRect.H, noteRect.Z); var flares = new CParticleEffect(_PartyModeID, 15, new SColorF(Color.White), rect, _Theme.SkinGoldenStar, 20, EParticleType.Flare); + flares.AllMonitors = false; _Flares.Add(flares); } @@ -333,12 +335,14 @@ namespace VocaluxeLib.Menu.SingNotes var stars = new CParticleEffect(_PartyModeID, CBase.Game.GetRandom(2) + 1, new SColorF(Color.White), r, _Theme.SkinPerfectNoteStart, 35, EParticleType.PerfNoteStar); + stars.AllMonitors = false; _PerfectNoteEffect.Add(stars); } private void _AddPerfectLine() { var twinkle = new CParticleEffect(_PartyModeID, 200, _Color, Rect, _Theme.SkinGoldenStar, 25, EParticleType.Twinkle); + twinkle.AllMonitors = false; _PerfectLineTwinkle.Add(twinkle); } } diff --git a/VocaluxeLib/Menu/SingNotes/CSingNotes.cs b/VocaluxeLib/Menu/SingNotes/CSingNotes.cs index 12b626db..bedfb95c 100644 --- a/VocaluxeLib/Menu/SingNotes/CSingNotes.cs +++ b/VocaluxeLib/Menu/SingNotes/CSingNotes.cs @@ -26,14 +26,16 @@ namespace VocaluxeLib.Menu.SingNotes [XmlType("Position")] public struct SBarPosition { - [XmlAttribute(AttributeName = "Name")] public string Name; + [XmlAttribute(AttributeName = "Name")] + public string Name; public SRectF Rect; } [XmlType("SingBar")] public struct SThemeSingBar { - [XmlAttribute(AttributeName = "Name")] public string Name; + [XmlAttribute(AttributeName = "Name")] + public string Name; public string SkinLeft; public string SkinMiddle; @@ -51,7 +53,8 @@ namespace VocaluxeLib.Menu.SingNotes public string SkinToneHelper; public string SkinPerfectNoteStart; - [XmlArray("BarPositions")] public SBarPosition[] BarPos; + [XmlArray("BarPositions")] + public SBarPosition[] BarPos; } public class CSingNotes : CMenuElementBase, IMenuElement, IThemeable @@ -78,12 +81,12 @@ namespace VocaluxeLib.Menu.SingNotes /// /// first index = player number; second index = num players seen on screen /// - private SRectF[,] _BarPos { get; set; } + private SRectF[,,] _BarPos { get; set; } public CSingNotes(int partyModeID) { _PartyModeID = partyModeID; - _Theme = new SThemeSingBar {BarPos = new SBarPosition[CHelper.Sum(CBase.Settings.GetMaxNumPlayer())]}; + _Theme = new SThemeSingBar { BarPos = new SBarPosition[CHelper.Sum(CBase.Settings.GetMaxNumPlayer() * CBase.Settings.GetMaxNumScreens())] }; ThemeLoaded = false; } @@ -92,7 +95,7 @@ namespace VocaluxeLib.Menu.SingNotes _PartyModeID = partyModeID; _Theme = theme; - _BarPos = new SRectF[CBase.Settings.GetMaxNumPlayer(),CBase.Settings.GetMaxNumPlayer()]; + _BarPos = new SRectF[CBase.Settings.GetMaxNumScreens(), CBase.Settings.GetMaxNumPlayer(), CBase.Settings.GetMaxNumPlayer()]; ThemeLoaded = true; } @@ -104,11 +107,45 @@ namespace VocaluxeLib.Menu.SingNotes public bool ThemeLoaded { get; private set; } - public void Init(int numPlayers) + public void Init(int numPlayers, int numScreens = 0) { + PlayerNotes.Clear(); - for (int p = 0; p < numPlayers; p++) - PlayerNotes.Add(new CNoteBars(_PartyModeID, p, _BarPos[p, numPlayers - 1], _Theme)); + if (numPlayers > 0 && numScreens > 0) + { + int[] screenAssignment = new int[numPlayers]; + int screenPlayers = numPlayers / numScreens; + int remainingPlayers = numPlayers - (screenPlayers * numScreens); + int player = 0; + + for (int s = 0; s < numScreens; s++) + { + for (int p = 0; p < screenPlayers; p++) + { + if (remainingPlayers > 0) + { + PlayerNotes.Add(new CNoteBars(_PartyModeID, player++, _BarPos[s, p, screenPlayers], _Theme)); + if (p == screenPlayers - 1) + { + PlayerNotes.Add(new CNoteBars(_PartyModeID, player++, _BarPos[s, p + 1, screenPlayers], _Theme)); + remainingPlayers--; + } + } + else + { + PlayerNotes.Add(new CNoteBars(_PartyModeID, player++, _BarPos[s, p, screenPlayers - 1], _Theme)); + } + + } + //Handle when players < screens + if (screenPlayers == 0 && remainingPlayers > 0) + { + PlayerNotes.Add(new CNoteBars(_PartyModeID, player++, _BarPos[s, 0, 0], _Theme)); + remainingPlayers--; + } + } + } + if (numPlayers == 0) _Rect = new SRectF(0, 0, 0, 0, Rect.Z); else @@ -127,7 +164,7 @@ namespace VocaluxeLib.Menu.SingNotes noteBars.Draw(); } - public void UnloadSkin() {} + public void UnloadSkin() { } public void LoadSkin() { @@ -141,8 +178,11 @@ namespace VocaluxeLib.Menu.SingNotes { int n = Int32.Parse(bp.Name.Substring(3, 1)) - 1; int p = Int32.Parse(bp.Name.Substring(1, 1)) - 1; - - _BarPos[p, n] = bp.Rect; + for (int s = 0; s < CBase.Settings.GetMaxNumScreens(); s++) + { + _BarPos[s, p, n] = bp.Rect; + _BarPos[s, p, n].X += s * CBase.Settings.GetRenderW(); + } } } @@ -158,9 +198,9 @@ namespace VocaluxeLib.Menu.SingNotes } #region ThemeEdit - public void MoveElement(int stepX, int stepY) {} + public void MoveElement(int stepX, int stepY) { } - public void ResizeElement(int stepW, int stepH) {} + public void ResizeElement(int stepW, int stepH) { } #endregion ThemeEdit } }