From 342123dc4eed33145916dfe7e7a3bc7a89eb65aa Mon Sep 17 00:00:00 2001 From: lukeIam <2lukeiam@gmail.com> Date: Wed, 31 Jan 2018 20:34:11 +0100 Subject: [PATCH 01/39] Removed useless metapackage vocaluxe.dependencies (cherry picked from commit 20d13d9f0660b44db4614ae6e9dd6c17a3456980) # Conflicts: # Vocaluxe/packages.config --- Vocaluxe/Vocaluxe.csproj | 2 -- Vocaluxe/packages.config | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index 248e7a46..a2f05409 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -547,7 +547,6 @@ - @@ -561,5 +560,4 @@ - \ No newline at end of file diff --git a/Vocaluxe/packages.config b/Vocaluxe/packages.config index 437d7321..b3c6953a 100644 --- a/Vocaluxe/packages.config +++ b/Vocaluxe/packages.config @@ -1,6 +1,6 @@  - + From 61dcfc3aeb86b959320232db633373f10e395fe8 Mon Sep 17 00:00:00 2001 From: lukeIam <2lukeiam@gmail.com> Date: Wed, 31 Jan 2018 20:42:25 +0100 Subject: [PATCH 02/39] Upgrade PortAudio to version pa_stable_v190600_20161030 (cherry picked from commit 16f9ef2c8861ce22b7e09aeae342f701739ce149) --- Vocaluxe/Vocaluxe.csproj | 7 ++++--- Vocaluxe/packages.config | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index a2f05409..7a145115 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -31,7 +31,8 @@ 1.0.0.%2a false true - 3d91144f + + x86 @@ -542,11 +543,11 @@ - + @@ -555,9 +556,9 @@ - + \ No newline at end of file diff --git a/Vocaluxe/packages.config b/Vocaluxe/packages.config index b3c6953a..493ebca1 100644 --- a/Vocaluxe/packages.config +++ b/Vocaluxe/packages.config @@ -9,7 +9,7 @@ - + From cd5ab37afd395bd55a0ffefd666b6821842ec1cf Mon Sep 17 00:00:00 2001 From: lukeIam <2lukeiam@gmail.com> Date: Tue, 27 Feb 2018 19:34:15 +0100 Subject: [PATCH 03/39] Use TLS 1.2 for downloading GStreamer (cherry picked from commit 617cf70bf8d7dc35abab1bf0c786d607809d2843) --- Vocaluxe/Vocaluxe.csproj | 4 ++-- Vocaluxe/packages.config | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj index 7a145115..d7931ec1 100644 --- a/Vocaluxe/Vocaluxe.csproj +++ b/Vocaluxe/Vocaluxe.csproj @@ -546,7 +546,7 @@ - + @@ -559,6 +559,6 @@ - + \ No newline at end of file diff --git a/Vocaluxe/packages.config b/Vocaluxe/packages.config index 493ebca1..0dbfb55c 100644 --- a/Vocaluxe/packages.config +++ b/Vocaluxe/packages.config @@ -5,7 +5,7 @@ - + From efead3615cd34b23baaf7ca3d7fb9a07068a6633 Mon Sep 17 00:00:00 2001 From: Gary Kertopermono Date: Mon, 8 Apr 2019 15:16:00 +0200 Subject: [PATCH 04/39] Added basic support for rap notes and golden rap notes --- Vocaluxe/Base/CGame.cs | 9 ++++++--- VocaluxeLib/Enums.cs | 4 +++- VocaluxeLib/Songs/CSongLoader.cs | 4 ++++ VocaluxeLib/Songs/CSongNote.cs | 2 ++ VocaluxeLib/Songs/CSongWriter.cs | 6 ++++++ 5 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Vocaluxe/Base/CGame.cs b/Vocaluxe/Base/CGame.cs index a90b062a..444d5208 100644 --- a/Vocaluxe/Base/CGame.cs +++ b/Vocaluxe/Base/CGame.cs @@ -302,6 +302,9 @@ namespace Vocaluxe.Base if(p == 0) tonePlayer = tone; #endif + if (notes[note].Type == ENoteType.Rap || notes[note].Type == ENoteType.RapGolden) + tonePlayer = tone; + Players[p].NoteDiff = Math.Abs(tone - tonePlayer); bool hit = Players[p].NoteDiff <= (2 - (int)CProfiles.GetDifficulty(Players[p].ProfileID)); @@ -311,7 +314,7 @@ namespace Vocaluxe.Base //CRecord.RecordSetTone(p, Tone); double points = (CSettings.MaxScore - CSettings.LinebonusScore) * (double)notes[note].PointsForBeat / song.Notes.GetVoice(Players[p].VoiceNr).Points; - if (notes[note].Type == ENoteType.Golden) + if (notes[note].Type == ENoteType.Golden || notes[note].Type == ENoteType.RapGolden) Players[p].PointsGoldenNotes += points; Players[p].Points += points; @@ -411,7 +414,7 @@ namespace Vocaluxe.Base { if (note.StartBeat < nextStart) { - if (note.Hit && note.HitNote.Type == ENoteType.Golden) + if (note.Hit && (note.HitNote.Type == ENoteType.Golden || note.HitNote.Type == ENoteType.RapGolden)) Players[p].PointsGoldenNotes += note.Points; Players[p].Points += note.Points; } @@ -421,7 +424,7 @@ namespace Vocaluxe.Base } while (line.NoteCount > n && n >= 0) { - if (line.Notes[n].Hit && line.Notes[n].HitNote.Type == ENoteType.Golden) + if (line.Notes[n].Hit && (line.Notes[n].HitNote.Type == ENoteType.Golden || line.Notes[n].HitNote.Type == ENoteType.RapGolden)) Players[p].PointsGoldenNotes -= line.Notes[n].Points; Players[p].Points -= line.Notes[n].Points; line.DeleteNote(n); diff --git a/VocaluxeLib/Enums.cs b/VocaluxeLib/Enums.cs index 8ba2a416..746e04c7 100644 --- a/VocaluxeLib/Enums.cs +++ b/VocaluxeLib/Enums.cs @@ -364,7 +364,9 @@ namespace VocaluxeLib { Normal, Golden, - Freestyle + Freestyle, + Rap, + RapGolden } public enum EMusicType diff --git a/VocaluxeLib/Songs/CSongLoader.cs b/VocaluxeLib/Songs/CSongLoader.cs index 99702bc8..650971cb 100644 --- a/VocaluxeLib/Songs/CSongLoader.cs +++ b/VocaluxeLib/Songs/CSongLoader.cs @@ -616,6 +616,10 @@ namespace VocaluxeLib.Songs noteType = ENoteType.Golden; else if (tag.Equals('F')) noteType = ENoteType.Freestyle; + else if (tag.Equals('R')) + noteType = ENoteType.Rap; + else if (tag.Equals('G')) + noteType = ENoteType.RapGolden; else noteType = ENoteType.Normal; diff --git a/VocaluxeLib/Songs/CSongNote.cs b/VocaluxeLib/Songs/CSongNote.cs index 3079c61e..f0ce3d73 100644 --- a/VocaluxeLib/Songs/CSongNote.cs +++ b/VocaluxeLib/Songs/CSongNote.cs @@ -49,8 +49,10 @@ namespace VocaluxeLib.Songs switch (Type) { case ENoteType.Normal: + case ENoteType.Rap: return 1; case ENoteType.Golden: + case ENoteType.RapGolden: return 2; case ENoteType.Freestyle: return 0; diff --git a/VocaluxeLib/Songs/CSongWriter.cs b/VocaluxeLib/Songs/CSongWriter.cs index bdae39c4..957905e3 100644 --- a/VocaluxeLib/Songs/CSongWriter.cs +++ b/VocaluxeLib/Songs/CSongWriter.cs @@ -187,6 +187,12 @@ namespace VocaluxeLib.Songs case ENoteType.Freestyle: tag = "F"; break; + case ENoteType.Rap: + tag = "R"; + break; + case ENoteType.RapGolden: + tag = "G"; + break; default: throw new NotImplementedException("Note type " + note.Type); } From 26655b84dc108fc7a36f9e68896643035bd3d9db Mon Sep 17 00:00:00 2001 From: Gary Kertopermono Date: Tue, 9 Apr 2019 17:32:42 +0200 Subject: [PATCH 05/39] Rap notes are now properly interpreted --- VocaluxeLib/Menu/SingNotes/CNoteBars.cs | 21 ++++++++++++++------- VocaluxeLib/Songs/CSongLoader.cs | 2 ++ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/VocaluxeLib/Menu/SingNotes/CNoteBars.cs b/VocaluxeLib/Menu/SingNotes/CNoteBars.cs index 5e6c50ee..023cab92 100644 --- a/VocaluxeLib/Menu/SingNotes/CNoteBars.cs +++ b/VocaluxeLib/Menu/SingNotes/CNoteBars.cs @@ -84,8 +84,8 @@ namespace VocaluxeLib.Menu.SingNotes _Flares.Clear(); _PerfectNoteEffect.Clear(); - foreach (CSongNote note in _Lines[_CurrentLine].Notes.Where(note => note.Type == ENoteType.Golden)) - _AddGoldenNote(_GetNoteRect(note)); + foreach (CSongNote note in _Lines[_CurrentLine].Notes.Where(note => (note.Type == ENoteType.Golden || note.Type == ENoteType.RapGolden))) + _AddGoldenNote(_GetNoteRect(note, note.Type == ENoteType.Rap || note.Type == ENoteType.RapGolden)); } public void Draw() @@ -107,7 +107,7 @@ namespace VocaluxeLib.Menu.SingNotes { if (note.Type != ENoteType.Freestyle) { - SRectF rect = _GetNoteRect(note); + SRectF rect = _GetNoteRect(note, note.Type == ENoteType.Rap || note.Type == ENoteType.RapGolden); _DrawNoteBG(rect, color); _DrawNoteBase(rect, new SColorF(_NoteBaseColor, _NoteBaseColor.A * Alpha), 1f); @@ -130,7 +130,7 @@ namespace VocaluxeLib.Menu.SingNotes _DrawNoteFill(rect, color, factor); - if (note.EndBeat >= CBase.Game.GetRecordedBeat() && note.Hit && note.HitNote.Type == ENoteType.Golden) + if (note.EndBeat >= CBase.Game.GetRecordedBeat() && note.Hit && (note.HitNote.Type == ENoteType.Golden || note.HitNote.Type == ENoteType.RapGolden)) { SRectF re = rect; re.W = (CBase.Game.GetMidRecordedBeat() - note.StartBeat) / beats * Rect.W; @@ -171,18 +171,25 @@ namespace VocaluxeLib.Menu.SingNotes perfnote.Draw(); } - private SRectF _GetNoteRect(CBaseNote note) + private SRectF _GetNoteRect(CBaseNote note, bool isRapNote = false) { CSongLine line = _Lines[_CurrentLine]; float beats = line.LastNoteBeat - line.FirstNoteBeat + 1; float width = note.Duration * Rect.W / beats; + float y = Rect.Y + (CBase.Settings.GetNumNoteLines() - 1 - (note.Tone - line.BaseLine) / 2f) * _NoteLineHeight - _AddNoteHeight / 2; + float height = _NoteLineHeight + _AddNoteHeight; + + if (isRapNote) { + y = Rect.Y; + height = Rect.H; + } var noteRect = new SRectF( Rect.X + (note.StartBeat - line.FirstNoteBeat) * Rect.W / beats, - Rect.Y + (CBase.Settings.GetNumNoteLines() - 1 - (note.Tone - line.BaseLine) / 2f) * _NoteLineHeight - _AddNoteHeight / 2, + y, width, - _NoteLineHeight + _AddNoteHeight, + height, Rect.Z ); return noteRect; diff --git a/VocaluxeLib/Songs/CSongLoader.cs b/VocaluxeLib/Songs/CSongLoader.cs index 650971cb..48a2d324 100644 --- a/VocaluxeLib/Songs/CSongLoader.cs +++ b/VocaluxeLib/Songs/CSongLoader.cs @@ -566,6 +566,8 @@ namespace VocaluxeLib.Songs break; case ':': case '*': + case 'R': + case 'G': case 'F': string[] noteData = line.Split(splitChars, 4); if (noteData.Length < 4) From 4c76c88074e1078004ff206804247a4b81a5cf0a Mon Sep 17 00:00:00 2001 From: Stefan Date: Wed, 15 Jan 2020 23:44:49 +0100 Subject: [PATCH 06/39] Fix release-0.4.1: Config.Video.VideoPreview is ignored (fixes #391) --- VocaluxeLib/Menu/SongMenu/CSongMenuList.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuList.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuList.cs index 8bbd810a..59741a1d 100644 --- a/VocaluxeLib/Menu/SongMenu/CSongMenuList.cs +++ b/VocaluxeLib/Menu/SongMenu/CSongMenuList.cs @@ -541,7 +541,9 @@ namespace VocaluxeLib.Menu.SongMenu } _TextBG.Draw(); - CTextureRef vidtex = CBase.BackgroundMusic.IsPlayingPreview() ? CBase.BackgroundMusic.GetVideoTexture() : null; + CTextureRef vidtex = null; + if (CBase.Config.GetVideoPreview() == EOffOn.TR_CONFIG_ON) + vidtex = (CBase.BackgroundMusic.IsPlayingPreview() ? CBase.BackgroundMusic.GetVideoTexture() : null); if (vidtex != null) { @@ -683,4 +685,4 @@ namespace VocaluxeLib.Menu.SongMenu base.LoadSkin(); } } -} \ No newline at end of file +} From e2dcbc2ecf86b54a61610344a292a2aa2795c474 Mon Sep 17 00:00:00 2001 From: Stefan Date: Wed, 15 Jan 2020 23:46:01 +0100 Subject: [PATCH 07/39] Fix release-0.4.1: Config.Video.VideoPreview is ignored (fixes #391) --- VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs index f74e81f9..7457ac52 100644 --- a/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs +++ b/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs @@ -515,7 +515,9 @@ namespace VocaluxeLib.Menu.SongMenu _TextBG.Draw(); - CTextureRef vidtex = CBase.BackgroundMusic.IsPlayingPreview() ? CBase.BackgroundMusic.GetVideoTexture() : null; + CTextureRef vidtex = null; + if (CBase.Config.GetVideoPreview() == EOffOn.TR_CONFIG_ON) + vidtex = (CBase.BackgroundMusic.IsPlayingPreview() ? CBase.BackgroundMusic.GetVideoTexture() : null); if (vidtex != null) { @@ -638,4 +640,4 @@ namespace VocaluxeLib.Menu.SongMenu Init(); } } -} \ No newline at end of file +} From 9e8952157ad8c922274a05ae27537130a83d9042 Mon Sep 17 00:00:00 2001 From: Stefan Date: Thu, 16 Jan 2020 07:15:23 +0100 Subject: [PATCH 08/39] Fix release-0.4.1: JumpTo not working correctly on folder sort (fix #449) --- Vocaluxe/Screens/CScreenSong.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Vocaluxe/Screens/CScreenSong.cs b/Vocaluxe/Screens/CScreenSong.cs index ad8c73d0..0b1fe528 100644 --- a/Vocaluxe/Screens/CScreenSong.cs +++ b/Vocaluxe/Screens/CScreenSong.cs @@ -1067,7 +1067,7 @@ namespace Vocaluxe.Screens case ESongSorting.TR_CONFIG_FOLDER: if (curSelected >= 0 && curSelected < ct - 1 && songs[curSelected].Folder.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase)) start = curSelected + 1; - visibleID = _FindIndex(songs, start, element => element.Folder.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase)); + visibleID = _FindIndex(songs, start, element => element.FolderName.StartsWith(letter.ToString(), StringComparison.OrdinalIgnoreCase)); break; } if (visibleID > -1) @@ -1380,4 +1380,4 @@ namespace Vocaluxe.Screens } #endregion Playlist Actions } -} \ No newline at end of file +} From cfc6bfa7384cff1d27af79ea458e5d59093d92ed Mon Sep 17 00:00:00 2001 From: Stefan Date: Tue, 4 Feb 2020 08:46:48 +0100 Subject: [PATCH 09/39] Relative song paths will now be converted to absolute song paths Same fix from GaryCXJk for release-0.4.1 --- Vocaluxe/Base/CConfig.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Vocaluxe/Base/CConfig.cs b/Vocaluxe/Base/CConfig.cs index 1b7fde8e..48d9805a 100644 --- a/Vocaluxe/Base/CConfig.cs +++ b/Vocaluxe/Base/CConfig.cs @@ -633,7 +633,7 @@ namespace Vocaluxe.Base { //Check if folder exists if (Directory.Exists(folder)) - SongFolders.Add(folder); + SongFolders.Add(Path.GetFullPath(folder)); } } @@ -803,4 +803,4 @@ namespace Vocaluxe.Base } } } -} \ No newline at end of file +} From 546ccf4748d7ec610d149d777bb78f851402a1c7 Mon Sep 17 00:00:00 2001 From: Stefan Date: Fri, 7 Feb 2020 21:17:36 +0100 Subject: [PATCH 10/39] Scroll offset was ignored while singing a single playlist song (fix #487 for release-0.4.1) --- VocaluxeLib/Menu/CPlaylist.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/VocaluxeLib/Menu/CPlaylist.cs b/VocaluxeLib/Menu/CPlaylist.cs index 96a411cb..89b32d7d 100644 --- a/VocaluxeLib/Menu/CPlaylist.cs +++ b/VocaluxeLib/Menu/CPlaylist.cs @@ -554,7 +554,7 @@ namespace VocaluxeLib.Menu break; case Keys.Enter: - _StartPlaylistSong(_CurrentPlaylistElement); + _StartPlaylistSong(_CurrentPlaylistElement + _Offset); break; case Keys.Add: //move the selected song up @@ -880,7 +880,7 @@ namespace VocaluxeLib.Menu //Start selected song with double click if (mouseEvent.LD && _CurrentPlaylistElement != -1) - _StartPlaylistSong(_CurrentPlaylistElement); + _StartPlaylistSong(_CurrentPlaylistElement + _Offset); //Change order with holding LB if (mouseEvent.LBH && _CurrentPlaylistElement != -1 && _PlaylistElementContents.Count > 0 && DragAndDropSongID == -1) @@ -1259,4 +1259,4 @@ namespace VocaluxeLib.Menu } #endregion ThemeEdit } -} \ No newline at end of file +} From 919ab803d141672f24492d73db6706873411efac Mon Sep 17 00:00:00 2001 From: Stefan Date: Sun, 9 Feb 2020 20:02:59 +0100 Subject: [PATCH 11/39] Fix alpha calculation for last sub line (release-0.4.1) Sub line was displayed wrong, if the last lyric line has a bigger distance to the second last line. Alpha calculation for sub lines stopped one line to early and might be visible even if it shouldn't be. --- Vocaluxe/Screens/CScreenSing.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs index 4fdc3e76..0002ce6d 100644 --- a/Vocaluxe/Screens/CScreenSing.cs +++ b/Vocaluxe/Screens/CScreenSing.cs @@ -1114,7 +1114,7 @@ namespace Vocaluxe.Screens } // sub - if (currentLineSub < lines.Length - 2) + if ((currentLineSub + 1) < lines.Length) { float diff = CGame.GetTimeFromBeats(lines[currentLineSub + 1].FirstNoteBeat, song.BPM) - currentTime; @@ -1371,4 +1371,4 @@ namespace Vocaluxe.Screens } } } -} \ No newline at end of file +} From 5e481878f5499543ecd7ba41567cc80026cc1f00 Mon Sep 17 00:00:00 2001 From: Stefan Date: Tue, 11 Feb 2020 06:32:26 +0100 Subject: [PATCH 12/39] Update Readme.txt --- Output/Readme.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Output/Readme.txt b/Output/Readme.txt index 2cdffb4b..0c30e51d 100644 --- a/Output/Readme.txt +++ b/Output/Readme.txt @@ -1,4 +1,4 @@ -Vocaluxe 0.4 README +Vocaluxe 0.4.1 README ---------------------------- ================================= @@ -168,7 +168,6 @@ Vocaluxe Homepage: https://vocaluxe.org Bug Tracker: https://github.com/Vocaluxe/Vocaluxe/issues Translations: https://www.transifex.com/projects/p/vocaluxe/ GitHub Wiki: https://github.com/Vocaluxe/Vocaluxe/wiki -Support Forum (German): http://www.ultra-star.de Song-DataBase (USDB): http://usdb.animux.de/ From a6c576613882af8a1e3d5d7fd40612f2ff2a0938 Mon Sep 17 00:00:00 2001 From: lukeIam <2lukeiam@gmail.com> Date: Mon, 9 Mar 2020 18:24:20 +0100 Subject: [PATCH 13/39] Fix: replace invalid github tokens in 0.4.1 branch --- appveyor.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index a33b7eda..cc708f64 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -9,7 +9,7 @@ platform: clone_depth: 15 environment: GitHubKey: - secure: JSlN/em0JdspVn8jwaQ4IjugY6OQi0au4Qq0rhctJmcfGMaEGnUAOmDFULI48REW + secure: sGetWh2XUYs95VBT+QYNPtDW9Rh2/JBuxNNYXytpn7mMudUMcjSKDGErkCTum+ZE install: - ps: | $Env:CurrentCommitSha = "$(git rev-parse --verify HEAD)" @@ -88,7 +88,7 @@ deploy: release: $(APPVEYOR_REPO_TAG_NAME) description: $(APPVEYOR_REPO_COMMIT) auth_token: - secure: JSlN/em0JdspVn8jwaQ4IjugY6OQi0au4Qq0rhctJmcfGMaEGnUAOmDFULI48REW + secure: sGetWh2XUYs95VBT+QYNPtDW9Rh2/JBuxNNYXytpn7mMudUMcjSKDGErkCTum+ZE artifact: ReleaseZip prerelease: $(IS_BETA_RELEASE) on: @@ -100,7 +100,7 @@ deploy: release: Latest Nightly build description: $(APPVEYOR_REPO_COMMIT) auth_token: - secure: JSlN/em0JdspVn8jwaQ4IjugY6OQi0au4Qq0rhctJmcfGMaEGnUAOmDFULI48REW + secure: sGetWh2XUYs95VBT+QYNPtDW9Rh2/JBuxNNYXytpn7mMudUMcjSKDGErkCTum+ZE artifact: ReleaseZip prerelease: true on: From 821a85ab17bcdb5a760c758292b02aace51a5e33 Mon Sep 17 00:00:00 2001 From: Gary Kertopermono Date: Sun, 5 Apr 2020 18:03:27 +0200 Subject: [PATCH 14/39] Made it easier to check for golden and rap notes --- VocaluxeLib/Menu/SingNotes/CNoteBars.cs | 11 ++++++----- VocaluxeLib/Songs/CBaseNote.cs | 14 ++++++++++++++ VocaluxeLib/Songs/CSongNote.cs | 9 +++++++++ VocaluxeLib/Songs/CSungNote.cs | 6 ++++++ 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/VocaluxeLib/Menu/SingNotes/CNoteBars.cs b/VocaluxeLib/Menu/SingNotes/CNoteBars.cs index 023cab92..d8ee4c06 100644 --- a/VocaluxeLib/Menu/SingNotes/CNoteBars.cs +++ b/VocaluxeLib/Menu/SingNotes/CNoteBars.cs @@ -84,8 +84,8 @@ namespace VocaluxeLib.Menu.SingNotes _Flares.Clear(); _PerfectNoteEffect.Clear(); - foreach (CSongNote note in _Lines[_CurrentLine].Notes.Where(note => (note.Type == ENoteType.Golden || note.Type == ENoteType.RapGolden))) - _AddGoldenNote(_GetNoteRect(note, note.Type == ENoteType.Rap || note.Type == ENoteType.RapGolden)); + foreach (CSongNote note in _Lines[_CurrentLine].Notes.Where(note => (note.IsGoldenNote))) + _AddGoldenNote(_GetNoteRect(note)); } public void Draw() @@ -107,7 +107,7 @@ namespace VocaluxeLib.Menu.SingNotes { if (note.Type != ENoteType.Freestyle) { - SRectF rect = _GetNoteRect(note, note.Type == ENoteType.Rap || note.Type == ENoteType.RapGolden); + SRectF rect = _GetNoteRect(note); _DrawNoteBG(rect, color); _DrawNoteBase(rect, new SColorF(_NoteBaseColor, _NoteBaseColor.A * Alpha), 1f); @@ -130,7 +130,7 @@ namespace VocaluxeLib.Menu.SingNotes _DrawNoteFill(rect, color, factor); - if (note.EndBeat >= CBase.Game.GetRecordedBeat() && note.Hit && (note.HitNote.Type == ENoteType.Golden || note.HitNote.Type == ENoteType.RapGolden)) + if (note.EndBeat >= CBase.Game.GetRecordedBeat() && note.Hit && note.IsGoldenNote) { SRectF re = rect; re.W = (CBase.Game.GetMidRecordedBeat() - note.StartBeat) / beats * Rect.W; @@ -171,10 +171,11 @@ namespace VocaluxeLib.Menu.SingNotes perfnote.Draw(); } - private SRectF _GetNoteRect(CBaseNote note, bool isRapNote = false) + private SRectF _GetNoteRect(CBaseNote note) { CSongLine line = _Lines[_CurrentLine]; float beats = line.LastNoteBeat - line.FirstNoteBeat + 1; + bool isRapNote = note.IsRapNote; float width = note.Duration * Rect.W / beats; float y = Rect.Y + (CBase.Settings.GetNumNoteLines() - 1 - (note.Tone - line.BaseLine) / 2f) * _NoteLineHeight - _AddNoteHeight / 2; diff --git a/VocaluxeLib/Songs/CBaseNote.cs b/VocaluxeLib/Songs/CBaseNote.cs index 271283c3..d28750c2 100644 --- a/VocaluxeLib/Songs/CBaseNote.cs +++ b/VocaluxeLib/Songs/CBaseNote.cs @@ -82,6 +82,20 @@ namespace VocaluxeLib.Songs } public abstract int PointsForBeat { get; } + + public bool IsRapNote + { + get { return IsNoteType(ENoteType.Rap, ENoteType.RapGolden); } + } + + public bool IsGoldenNote + { + get { return IsNoteType(ENoteType.Golden, ENoteType.RapGolden); } + } #endregion Properties + + #region Methods + public abstract bool IsNoteType(params ENoteType[] noteTypes); + #endregion Methods } } \ No newline at end of file diff --git a/VocaluxeLib/Songs/CSongNote.cs b/VocaluxeLib/Songs/CSongNote.cs index f0ce3d73..1a96b8e7 100644 --- a/VocaluxeLib/Songs/CSongNote.cs +++ b/VocaluxeLib/Songs/CSongNote.cs @@ -15,6 +15,8 @@ // along with Vocaluxe. If not, see . #endregion +using System.Linq; + namespace VocaluxeLib.Songs { /// @@ -37,6 +39,13 @@ namespace VocaluxeLib.Songs } #endregion Constructors + #region Methods + public override bool IsNoteType(params ENoteType[] noteTypes) + { + return noteTypes.Contains(Type); + } + #endregion Method + #region Properties public ENoteType Type { get; set; } diff --git a/VocaluxeLib/Songs/CSungNote.cs b/VocaluxeLib/Songs/CSungNote.cs index 3fd3b9a1..d010722c 100644 --- a/VocaluxeLib/Songs/CSungNote.cs +++ b/VocaluxeLib/Songs/CSungNote.cs @@ -15,6 +15,8 @@ // along with Vocaluxe. If not, see . #endregion +using System.Linq; + namespace VocaluxeLib.Songs { /// @@ -74,6 +76,10 @@ namespace VocaluxeLib.Songs Perfect = result; } + public override bool IsNoteType(params ENoteType[] noteTypes) + { + return HitNote != null && noteTypes.Contains(HitNote.Type); + } #endregion Methods public override int PointsForBeat From 0328100db8b8ff8b5c1751fe7426f72b4f6090b8 Mon Sep 17 00:00:00 2001 From: Gary Kertopermono Date: Sun, 5 Apr 2020 20:49:06 +0200 Subject: [PATCH 15/39] Added icon for raps --- Output/Themes/Genius/01_Standard.xml | 1 + Output/Themes/Genius/02_Ice_Blue.xml | 1 + Output/Themes/Genius/03_Crimson_Red.xml | 1 + Output/Themes/Genius/RapIcon.png | Bin 0 -> 5740 bytes 4 files changed, 3 insertions(+) create mode 100644 Output/Themes/Genius/RapIcon.png diff --git a/Output/Themes/Genius/01_Standard.xml b/Output/Themes/Genius/01_Standard.xml index 8147bbdf..eef172ef 100644 --- a/Output/Themes/Genius/01_Standard.xml +++ b/Output/Themes/Genius/01_Standard.xml @@ -340,6 +340,7 @@ SearchBar.png PlaylistBG.png DuetIcon.png + RapIcon.png VideoIcon.png MedleyCalcIcon.png MedleyTagIcon.png diff --git a/Output/Themes/Genius/02_Ice_Blue.xml b/Output/Themes/Genius/02_Ice_Blue.xml index 0e9d9806..dbd343c1 100644 --- a/Output/Themes/Genius/02_Ice_Blue.xml +++ b/Output/Themes/Genius/02_Ice_Blue.xml @@ -340,6 +340,7 @@ SearchBar.png PlaylistBG.png DuetIcon.png + RapIcon.png VideoIcon.png MedleyCalcIcon.png MedleyTagIcon.png diff --git a/Output/Themes/Genius/03_Crimson_Red.xml b/Output/Themes/Genius/03_Crimson_Red.xml index aa3f4cfb..039c7501 100644 --- a/Output/Themes/Genius/03_Crimson_Red.xml +++ b/Output/Themes/Genius/03_Crimson_Red.xml @@ -340,6 +340,7 @@ SearchBar.png PlaylistBG.png DuetIcon.png + RapIcon.png VideoIcon.png MedleyCalcIcon.png MedleyTagIcon.png diff --git a/Output/Themes/Genius/RapIcon.png b/Output/Themes/Genius/RapIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..097fa55e653aacc9e0c8c04c4de5a4ead65e49b3 GIT binary patch literal 5740 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 Date: Tue, 15 Jun 2021 15:01:09 +0200 Subject: [PATCH 16/39] Added the rap icon --- Output/Themes/Genius/Screens/ScreenSong.xml | 37 +++++++++++++++---- .../Menu/SongMenu/CSongMenuFramework.cs | 3 ++ VocaluxeLib/Menu/SongMenu/CSongMenuList.cs | 7 +++- .../Menu/SongMenu/CSongMenuTileBoard.cs | 7 +++- VocaluxeLib/Songs/CSong.cs | 1 + VocaluxeLib/Songs/CSongLoader.cs | 6 +++ 6 files changed, 52 insertions(+), 9 deletions(-) diff --git a/Output/Themes/Genius/Screens/ScreenSong.xml b/Output/Themes/Genius/Screens/ScreenSong.xml index 1b74ad72..851d7232 100644 --- a/Output/Themes/Genius/Screens/ScreenSong.xml +++ b/Output/Themes/Genius/Screens/ScreenSong.xml @@ -752,6 +752,7 @@ CoverTile DuetIcon + RapIcon VideoIcon MedleyCalcIcon MedleyTagIcon @@ -850,7 +851,18 @@ DuetIcon - 200 + 160 + 530 + 40 + 40 + -1 + + + + DuetIcon + + + 240 530 40 40 @@ -861,7 +873,7 @@ VideoIcon - 120 + 80 530 40 40 @@ -872,7 +884,7 @@ MedleyCalcIcon - 280 + 320 530 40 40 @@ -977,7 +989,18 @@ DuetIcon - 200 + 160 + 530 + 40 + 40 + -1 + + + + RapIcon + + + 240 530 40 40 @@ -988,7 +1011,7 @@ VideoIcon - 120 + 80 530 40 40 @@ -999,7 +1022,7 @@ MedleyCalcIcon - 280 + 320 530 40 40 @@ -1010,7 +1033,7 @@ MedleyTagIcon - 280 + 240 530 40 40 diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs index 02cfac02..752215e0 100644 --- a/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs +++ b/VocaluxeLib/Menu/SongMenu/CSongMenuFramework.cs @@ -30,6 +30,7 @@ namespace VocaluxeLib.Menu.SongMenu public string CoverBackground; public string CoverBigBackground; public string DuetIcon; + public string RapIcon; public string VideoIcon; public string MedleyCalcIcon; public string MedleyTagIcon; @@ -67,6 +68,7 @@ namespace VocaluxeLib.Menu.SongMenu public SThemeStatic StaticCoverBig; public SThemeStatic StaticTextBG; public SThemeStatic StaticDuetIcon; + public SThemeStatic StaticRapIcon; public SThemeStatic StaticVideoIcon; public SThemeStatic StaticMedleyCalcIcon; public SThemeStatic StaticMedleyTagIcon; @@ -115,6 +117,7 @@ namespace VocaluxeLib.Menu.SongMenu public SThemeStatic StaticCoverBig; public SThemeStatic StaticTextBG; public SThemeStatic StaticDuetIcon; + public SThemeStatic StaticRapIcon; public SThemeStatic StaticVideoIcon; public SThemeStatic StaticMedleyCalcIcon; public SThemeStatic StaticMedleyTagIcon; diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuList.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuList.cs index 61b9a73c..c420b829 100644 --- a/VocaluxeLib/Menu/SongMenu/CSongMenuList.cs +++ b/VocaluxeLib/Menu/SongMenu/CSongMenuList.cs @@ -33,6 +33,7 @@ namespace VocaluxeLib.Menu.SongMenu private readonly CStatic _CoverBig; private readonly CStatic _TextBG; private readonly CStatic _DuetIcon; + private readonly CStatic _RapIcon; private readonly CStatic _VideoIcon; private readonly CStatic _MedleyCalcIcon; private readonly CStatic _MedleyTagIcon; @@ -121,10 +122,11 @@ namespace VocaluxeLib.Menu.SongMenu _CoverBig = new CStatic(_Theme.SongMenuList.StaticCoverBig, _PartyModeID); _TextBG = new CStatic(_Theme.SongMenuList.StaticTextBG, _PartyModeID); _DuetIcon = new CStatic(_Theme.SongMenuList.StaticDuetIcon, _PartyModeID); + _RapIcon = new CStatic(_Theme.SongMenuList.StaticRapIcon, _PartyModeID); _VideoIcon = new CStatic(_Theme.SongMenuList.StaticVideoIcon, _PartyModeID); _MedleyCalcIcon = new CStatic(_Theme.SongMenuList.StaticMedleyCalcIcon, _PartyModeID); _MedleyTagIcon = new CStatic(_Theme.SongMenuList.StaticMedleyTagIcon, _PartyModeID); - _SubElements.AddRange(new IMenuElement[] {_Artist, _Title, _SongLength, _DuetIcon, _VideoIcon, _MedleyCalcIcon, _MedleyTagIcon}); + _SubElements.AddRange(new IMenuElement[] {_Artist, _Title, _SongLength, _DuetIcon, _RapIcon, _VideoIcon, _MedleyCalcIcon, _MedleyTagIcon}); } private void _ReadSubTheme() @@ -134,6 +136,7 @@ namespace VocaluxeLib.Menu.SongMenu _Theme.SongMenuList.TextTitle = (SThemeText)_Title.GetTheme(); _Theme.SongMenuList.StaticCoverBig = (SThemeStatic)_CoverBig.GetTheme(); _Theme.SongMenuList.StaticDuetIcon = (SThemeStatic)_DuetIcon.GetTheme(); + _Theme.SongMenuList.StaticRapIcon = (SThemeStatic)_RapIcon.GetTheme(); _Theme.SongMenuList.StaticMedleyCalcIcon = (SThemeStatic)_MedleyCalcIcon.GetTheme(); _Theme.SongMenuList.StaticMedleyTagIcon = (SThemeStatic)_MedleyTagIcon.GetTheme(); _Theme.SongMenuList.StaticTextBG = (SThemeStatic)_TextBG.GetTheme(); @@ -218,6 +221,7 @@ namespace VocaluxeLib.Menu.SongMenu _Title.Text = String.Empty; _SongLength.Text = String.Empty; _DuetIcon.Visible = false; + _RapIcon.Visible = false; _VideoIcon.Visible = false; _MedleyCalcIcon.Visible = false; _MedleyTagIcon.Visible = false; @@ -246,6 +250,7 @@ namespace VocaluxeLib.Menu.SongMenu _Artist.Text = song.Artist; _Title.Text = song.Title; _DuetIcon.Visible = song.IsDuet; + _RapIcon.Visible = song.IsRap; _VideoIcon.Visible = song.VideoFileName != ""; _MedleyCalcIcon.Visible = song.Medley.Source == EDataSource.Calculated; _MedleyTagIcon.Visible = song.Medley.Source == EDataSource.Tag; diff --git a/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs b/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs index 478c918b..ac281cec 100644 --- a/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs +++ b/VocaluxeLib/Menu/SongMenu/CSongMenuTileBoard.cs @@ -32,6 +32,7 @@ namespace VocaluxeLib.Menu.SongMenu private CStatic _CoverBig; private CStatic _TextBG; private CStatic _DuetIcon; + private CStatic _RapIcon; private CStatic _VideoIcon; private CStatic _MedleyCalcIcon; private CStatic _MedleyTagIcon; @@ -116,10 +117,11 @@ namespace VocaluxeLib.Menu.SongMenu _CoverBig = new CStatic(_Theme.SongMenuTileBoard.StaticCoverBig, _PartyModeID); _TextBG = new CStatic(_Theme.SongMenuTileBoard.StaticTextBG, _PartyModeID); _DuetIcon = new CStatic(_Theme.SongMenuTileBoard.StaticDuetIcon, _PartyModeID); + _RapIcon = new CStatic(_Theme.SongMenuTileBoard.StaticRapIcon, _PartyModeID); _VideoIcon = new CStatic(_Theme.SongMenuTileBoard.StaticVideoIcon, _PartyModeID); _MedleyCalcIcon = new CStatic(_Theme.SongMenuTileBoard.StaticMedleyCalcIcon, _PartyModeID); _MedleyTagIcon = new CStatic(_Theme.SongMenuTileBoard.StaticMedleyTagIcon, _PartyModeID); - _SubElements.AddRange(new IMenuElement[] {_Artist, _Title, _SongLength, _DuetIcon, _VideoIcon, _MedleyCalcIcon, _MedleyTagIcon}); + _SubElements.AddRange(new IMenuElement[] {_Artist, _Title, _SongLength, _DuetIcon, _RapIcon, _VideoIcon, _MedleyCalcIcon, _MedleyTagIcon}); } private void _UpdateTileSelection() @@ -138,6 +140,7 @@ namespace VocaluxeLib.Menu.SongMenu _Theme.SongMenuTileBoard.TextTitle = (SThemeText)_Title.GetTheme(); _Theme.SongMenuTileBoard.StaticCoverBig = (SThemeStatic)_CoverBig.GetTheme(); _Theme.SongMenuTileBoard.StaticDuetIcon = (SThemeStatic)_DuetIcon.GetTheme(); + _Theme.SongMenuTileBoard.StaticRapIcon = (SThemeStatic)_RapIcon.GetTheme(); _Theme.SongMenuTileBoard.StaticMedleyCalcIcon = (SThemeStatic)_MedleyCalcIcon.GetTheme(); _Theme.SongMenuTileBoard.StaticMedleyTagIcon = (SThemeStatic)_MedleyTagIcon.GetTheme(); _Theme.SongMenuTileBoard.StaticTextBG = (SThemeStatic)_TextBG.GetTheme(); @@ -209,6 +212,7 @@ namespace VocaluxeLib.Menu.SongMenu _Title.Text = String.Empty; _SongLength.Text = String.Empty; _DuetIcon.Visible = false; + _RapIcon.Visible = false; _VideoIcon.Visible = false; _MedleyCalcIcon.Visible = false; _MedleyTagIcon.Visible = false; @@ -237,6 +241,7 @@ namespace VocaluxeLib.Menu.SongMenu _Artist.Text = song.Artist; _Title.Text = song.Title; _DuetIcon.Visible = song.IsDuet; + _RapIcon.Visible = song.IsRap; _VideoIcon.Visible = song.VideoFileName != ""; _MedleyCalcIcon.Visible = song.Medley.Source == EDataSource.Calculated; _MedleyTagIcon.Visible = song.Medley.Source == EDataSource.Tag; diff --git a/VocaluxeLib/Songs/CSong.cs b/VocaluxeLib/Songs/CSong.cs index e6ddaf4d..67e91585 100644 --- a/VocaluxeLib/Songs/CSong.cs +++ b/VocaluxeLib/Songs/CSong.cs @@ -165,6 +165,7 @@ namespace VocaluxeLib.Songs { get { return Notes.VoiceCount > 1; } } + public bool IsRap = false; public readonly List Editions = new List(); public readonly List Genres = new List(); diff --git a/VocaluxeLib/Songs/CSongLoader.cs b/VocaluxeLib/Songs/CSongLoader.cs index 48a2d324..7f8664ed 100644 --- a/VocaluxeLib/Songs/CSongLoader.cs +++ b/VocaluxeLib/Songs/CSongLoader.cs @@ -619,9 +619,15 @@ namespace VocaluxeLib.Songs else if (tag.Equals('F')) noteType = ENoteType.Freestyle; else if (tag.Equals('R')) + { noteType = ENoteType.Rap; + _Song.IsRap = true; + } else if (tag.Equals('G')) + { noteType = ENoteType.RapGolden; + _Song.IsRap = true; + } else noteType = ENoteType.Normal; From c5f4946a2c7f2fe470f138b7ccc0fd4faa7953d3 Mon Sep 17 00:00:00 2001 From: Gary Kertopermono Date: Tue, 15 Jun 2021 15:09:19 +0200 Subject: [PATCH 17/39] Fixed a typo in ScreenSong.xml --- Output/Themes/Genius/Screens/ScreenSong.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Output/Themes/Genius/Screens/ScreenSong.xml b/Output/Themes/Genius/Screens/ScreenSong.xml index 851d7232..60975972 100644 --- a/Output/Themes/Genius/Screens/ScreenSong.xml +++ b/Output/Themes/Genius/Screens/ScreenSong.xml @@ -752,7 +752,7 @@ CoverTile DuetIcon - RapIcon + RapIcon VideoIcon MedleyCalcIcon MedleyTagIcon @@ -1006,7 +1006,7 @@ 40 -1 - + VideoIcon From 7a54269693a5fb076c8b3e9ad16563af24257ddb Mon Sep 17 00:00:00 2001 From: Gary Kertopermono Date: Tue, 15 Jun 2021 15:11:36 +0200 Subject: [PATCH 18/39] Fixed mistakes, re-aligned medley icons --- Output/Themes/Genius/Screens/ScreenSong.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Output/Themes/Genius/Screens/ScreenSong.xml b/Output/Themes/Genius/Screens/ScreenSong.xml index 60975972..b2d2020b 100644 --- a/Output/Themes/Genius/Screens/ScreenSong.xml +++ b/Output/Themes/Genius/Screens/ScreenSong.xml @@ -858,8 +858,8 @@ -1 - - DuetIcon + + RapIcon 240 @@ -868,7 +868,7 @@ 40 -1 - + VideoIcon @@ -895,7 +895,7 @@ MedleyTagIcon - 280 + 320 530 40 40 @@ -1033,7 +1033,7 @@ MedleyTagIcon - 240 + 320 530 40 40 From 34f641727a5f864a03954f43d29cfd8cecc159fc Mon Sep 17 00:00:00 2001 From: Gary Kertopermono Date: Fri, 18 Jun 2021 10:17:31 +0200 Subject: [PATCH 19/39] Added rap note placeholder graphics --- Output/Themes/Genius/RapNotesBGLeft.png | Bin 0 -> 5853 bytes Output/Themes/Genius/RapNotesBGMid.png | Bin 0 -> 1782 bytes Output/Themes/Genius/RapNotesBGRight.png | Bin 0 -> 5964 bytes Output/Themes/Genius/RapNotesFillLeft.png | Bin 0 -> 8795 bytes Output/Themes/Genius/RapNotesFillMid.png | Bin 0 -> 4502 bytes Output/Themes/Genius/RapNotesFillRight.png | Bin 0 -> 9186 bytes Output/Themes/Genius/RapNotesLeft.png | Bin 0 -> 10817 bytes Output/Themes/Genius/RapNotesMid.png | Bin 0 -> 13180 bytes Output/Themes/Genius/RapNotesRight.png | Bin 0 -> 11418 bytes Output/Themes/Genius/Screens/ScreenSing.xml | 9 +++++++++ 10 files changed, 9 insertions(+) create mode 100644 Output/Themes/Genius/RapNotesBGLeft.png create mode 100644 Output/Themes/Genius/RapNotesBGMid.png create mode 100644 Output/Themes/Genius/RapNotesBGRight.png create mode 100644 Output/Themes/Genius/RapNotesFillLeft.png create mode 100644 Output/Themes/Genius/RapNotesFillMid.png create mode 100644 Output/Themes/Genius/RapNotesFillRight.png create mode 100644 Output/Themes/Genius/RapNotesLeft.png create mode 100644 Output/Themes/Genius/RapNotesMid.png create mode 100644 Output/Themes/Genius/RapNotesRight.png diff --git a/Output/Themes/Genius/RapNotesBGLeft.png b/Output/Themes/Genius/RapNotesBGLeft.png new file mode 100644 index 0000000000000000000000000000000000000000..0c321303fb7d0db812cc2215e8556a2dfe95ab30 GIT binary patch literal 5853 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

i|^*lvq41Q*0)sHiyPDIen zMQc2-T3~9_9DHFUwx;#n@u#T-)ES3}&nPU%I{u_edErjH!5Hx-K%ue5t5JDnA<46HDvxod}DR`$*anPzsq;|;G< zJL9ayi4=pLoRRK(59Z~7O`204+Kc+y?%#1L_VR8DEUO_33jhx^lCb>ZFU-<2JsgIZ z>!evndqAJ_1^u1(B(^3s9t2F&RTIwkjhq-{RX@hrB=!na_`tdkFu~(_-L(UxAKVnv zb}{Tyw+=|8Ht}{yBc{K#IGZ_h6?9afGbe>>2rPo>W6l}SA64CAlyd8Ei+j8QJL zsb;##UhSSMfP68Nt31R}VCKU!rO4+O0wTzEq$R)~dw{H8GwI-StTS1ZfeQu4!j1cz z72WrC8P6wst*bP|+wBxsETm=9F`_}19Cd=GgH}lx;H2Fp>@nz#2HG5^Ct`2aCeFHS zPa-Xp1}1KQQ58xT*XYxxNf-%u+ZhB^Mfx>oh=2Bx;F%ESdx57N%I&s~a3f!JMu?!e-2c$pFFSb++O2E*bC^*Zx2u7>@4>?u8FW*8SlxF+g+UU zk6B;XnQCf#^)n>Vb^2S^+!(!&d~$Hr*7wun)XB!vkI$3NCMbTIb1=yF73yG_)-u)C zK?yi_$~Y;apiP%Y@KEvbOHLSk8`>4Q<%s z;bE6`H@b18J98waf6Pz%D}Oxiz9?V#BALSwa+1rK7xO~M=P)K=i&M4=T~%TflZU1g zie_=?ZkeTY>B;5u!>rmvv1UbL&h?QZ>;~^7@olj_?(TV{i_h2OMp^m!#%o=hCxev%sR`~=Q(7}YxHZ|tqz-u<4D|!TKnrEr~RMxdPzyK8dILtxV#=}gQ8Fe3}HO6QxZxj4DkEx}m>$G9AmGg7Fi4$hir*X+=!JUb~13c2HcqOT(203~EgM5Q#PSz;wl*5is;cGNUU z)J^QkIN1O-o*O1ox`_xb7^P%3%o8yo$Z`T7ifkuB3>&2xfo3BV!-|X`GAz-&NSw`7 z3gSq*znKf4;$+db4UwkH<#Mnb4(jFv%?g4*Ga)(@qOb*J&1kk%p){+v6(Nl**;EZ% z)iuJ2DCPBOJ5FMxjS@;mF1Hp~vzm>eiM$g8qiFp|v$SV<372 zS^BgoV?GMKEoa=jYbSCHF&gn9Q^ll6Q)ykEE+Ng%rsE|35>!-0jKm7DsDKca=fXUN zn2172NLDBz9Ol`m6v@ZJu~wXo{8Rl*G8~IW1%?T+Y$le>@R^JdVI%!J`6SQsE#ItW z*^(xsR&EvNZu)Z9^c7Pkl5E`^)%B^?6bu)2Teph3L8MX+>oMZ)F;!FavUQI`Q={rM zGS$bC(r@Y|qTXjw-2g*DmSP2&k5X)&WvH+m$y50P!%WZ2Bwf`q!9K ztig2{EjVJBk>se%b5w!hWr}4{loA+)qXdo-LQF`Kxln|pF+|!KopqzsQsMb@#I?o1 zhqcv08r~-pFV0-g;R|>lec5z!v~upsm&q4h$(u6|AL_g^pLzMI#F5v!pFNjYEf4L_ z-e?(rJo3ik$?gu~vroIK0B-OB0oP0Tk4Qg1dghDMY(j&l8l)KJ>sI7yJmY353 zes}3(w(4!s^W^acVw|uHSltBX119`R71!s654|s7N*4^G)qU50&|bh){JZT3&yH1H X;Ga#*^Ork#z*jailzw~Xo`t^v?IhIJ literal 0 HcmV?d00001 diff --git a/Output/Themes/Genius/RapNotesBGRight.png b/Output/Themes/Genius/RapNotesBGRight.png new file mode 100644 index 0000000000000000000000000000000000000000..4d3b82384984da675374ef0316b3368279a3ac58 GIT binary patch literal 5964 zcmcgwc{tQ--@j+fAWN1QveZzHb3^NrdEZV#XM2j2I!yjHN{($5Q9$U~Hi% zM2mH_BC;fkicSheLu4P`>73K^KJRrs*YoH5`{#Gx-{1H1`R>2#zV0;VLpGv9azX$A zQ9D~p7v7r*00ao~^Hy}i7u)! z0DP%IZXR?G$Ad-`TBtVpyN-5DXgCiIfU#LjIGGYcr6YZ*0YPCV%ADqQWn_?_iSkjL zBgQe@f*KfPdn$tJdg_oH11R~=<%>fqZkwAzj%#!>+fQ; zGV(7KdWebg-%fcrIwLJ;5mY2jTOUQy(KAFE;I(ydctc&R7E%|ZqmRbm(K=WZM#l() zH^S&3|9O;o)*}4;ja)3P|FOl}nJ5R+>ET9bbaZsIcC?;0Eg}G|gU9317+tikE{dmt zii{1TlVea}k^6oySW+V?5kcYfAX*smJ0sbb7DYEv=6U*e2%+JQj{hPKi~J{1yp*A1 z$l+)mZ45dz^m|-?X-CpssQ>H6f7Fh2iw&ouU8s??s0a$L9{&4&fO)z5?}olB^1Lx} ziU{Hrg?!wSMu`fghSBXTO_X_GwEcqojIaj&2Ksm^73GW5Gel7_SU(h*O7TPC_4EvN z^vPIX13iNuJpT!AVXdQ&H@CvzF&JGP9V-K(m7$dt9;<`3Ha8?1>KOjO+J!~Z$zc@g z58FXJ+kay%t^X_5$RdJDrqd$aXtd)$y1+S*MyEvv(!!Az7T>FGfK)pg6y`^Zj#U3% zroW@Mq(%gtr21J$&_a=a<=H6cKltEJAshHp4E0euzB(9`9tG=*^7Y5yP&i*bKOHO% zr{kyVulx_*@89zGcc1bkyg0&txMQS;Ayf1zhB%Zz#*l*2(V^<2@EAWF3Xj9!buqeR z3QiZRjOMwB{@yzO)=ED_y#D;Y{MTUcHvbweY8Y>xB6x#i*Iwcbz%Fk)OQKuM=RnoDN89!=Uk?s(0Xx6B~oZ>+Q~fep}^s^v`JO*JWI(G zv4^XPk7S6JhlgaH-)nv>PR^Ds?K07$7zFTNu|E>^Z8qV{y=Z@FskmpePiAk0e7kn! zg^6CTVJ2+s27D6+fCykh00sblzy?5;_j>@O{|DhqI}aId^8n}KTN@_>vAgJXlbmsR zZqWeeeB#Pvw53@_QJ4v^C7PLyt(=>_NWB?SKc}?rQ!~qPrxI?GPX*m&CYGvYz_sWL7OLFs;)Y| zTg%l5%ilz=zUtEkuLEIk`+#}TjJHB`QNKbm<43;%RX2;b~FusfHAb314(}smbtZ1^)R(S z3H)+I{M4u*EuAd@fpv5!+)_yhk6Id&D0wfyej+4?+}r9hADdO)ZlNNZt!VAEKIv)n z>CpYm9pJKD$wk*Tsk`oi^rwX(^;|g;7Ww)>9r2obc+nUIu;YaPM9boRz#{FZEqC5vG5cdHG-|KXx1m$UTH`ac=KGkqnnRz_ApJ4q!&_rXr=~j5|6PVp)ra z$LqL%D0-^2&QmJXXEjS0isaX#fTkL&%?trI1R8<~-Q1cEC?2_Ayy0~HV#omc!WOuH zPYbRf1a;oH@|;mRv{|DhxX4<0zR(;LcSzV`x$W0-_zgR6Ij;IZ&ZRX?bI(3NbFpsM zekBC(L(sC|yct2YM%=16#tT2zpV8R>h_f_f*5-ukxkISS= z70;x&sl+ogKO#uaq%a;p$0JDuEZJKGiZd}4Nhw`Z-K@UB`-ZUwiUDqP`%~L01ABLI zPo<6sFyBhVR~d+3CG==A^R?KKYx;i7&ZqaiS!?(SyxhMY+g{o1$tcLXb4l>ae5`by>^8I$x3I3P~z|IQznJH>x>5HD_xcu5p& zyUJ&~dgV7{!NqUqt0H4m%(t9D`r}TXPVg`^)BN5~LCGv8QGTtIVmXD3!6_Depex>Q zi<8D=xAt5}_3y1LJF}^0L!R^!AygahSHh*va_(4e$1Ty6m!gg^hgC$XMRJxM2%V?j zk%u+2lB*%il$33s*dy7Di!1#D_jcS--h7HBn6BFlj(m${V(PCEyEz5QtDWkfJo%f# zJ|WujY86^5A=TE-52kTwJ^@wn$JH^8s60jiB$tE*bs}UKceMyp>WtdUQmwZ4bx9gjwPUwfiE6(LSJg0 zXV3w`YxLRAYI$eP#_QE)>m{l_j94EYmXy6aI>Hq9U|HNQ5bp9eTn=<@iE@{8id~%A zkGOkUzp3TmXV|4w*451rX1`#=UXO_>jpC?}F&WEK?QzRyWh=&iWDZNT(X`k0dz_toBD13pN?>lEpJ8&;xY;j7#W$pFppKT+;Ma-XIP}$s_ zp_8dYgb&^aDi|eSb3@f}9t^Ls1Vn=|PQiaEQLXHZvDIW%h0LJmC&{)G4ss;=WPITY zUi>kfAe%uM0m@?jdt%xOI8Vn_Yq0j3X@z%HK&~u1KW!08?y=@%lctJZ$s;GACw7{S zkH~NP94JqA1Z;|&um~I(m}BTbAXt~PQ;Je1u)>>4aT#vX`{N`O3r;iy@%JN09tRH( z3XYCX+DaF?J=o0(&X?Eo(o1q+9CrJ&X2Dc%H}jncSvW#g$`K>@q^x>>svx}{ zg5MBS@kgG$Jzpk;lD0*WYt(aH*f~njgyYV_(7tLvlyKlitTZOe*g~zmScU+*l*CG6 z=O|kTym&`WB2Mr0Jm?%OtQz-a)QW@>4<=xYo3ZFKEXaJj9== zlE;*R;Rr8fgwutDMeOtXbJ}i@!$i#jG}YO{{Aj_J9Eaw5HZQ#CX-Ut|$f+j*w8MNu zZjcSXbUDO)kBfa1TWG5id)gVU1^T9sE5E2^M&H&oyM1+s{pE_^=j`ZMv)UOA*7Cg* zWcc9+P(S9`bTD$zu-9l}#*3frBA%OX^HzVscG>uWhZ?@-)#JBSe1*58fEJ`fl1Fc9 zPxY#5u53JSa`Y#MWhuZ4YZ$3zN`bpyHf+xQV-M*?kJID^8>n{5?di{D2Gm%7 zt$kX`LtQ?7DQ3(nI(PXpRJ&CM7(z%|js~~}Gb7ibeSn#xE`2#z^di5kVh?5v4%l7k z%LB31Cu|<`3bzPhM)o~6Nk$Z~Gnkadb|1sDeDw|-l24V8I`5pPP=S-~!%1^$Vl$}Q z5HL(_WXb~OH(2Zrd1FDKAl5h>pLpy2O8=Lvk~cm;eFA0^b_?^H3JB`ZPMYur6SHJ^ z-?`yr?KzqPbkPT}7vN1N;=OM@;W{d{+H$z6AUuM(kej5kF6K8r-vomKl8xtE8%NFn z-0?L3e7*Up7J2Y;FE0dgT$=WNM1YR8Vv;-d%5n;@=7GPn1bb3#cXWxd;$ka zhpxCR<1#nBh5W1PO5s?wiy5V=;qo=?`#SuLndv*;6(2r2%Qhme^l(BI37w&fAaI#2 zG%UKeOEv@HnhL#OyJk8bb}OO7aF}*mgn6tf5?9)ORd=G#&ar@Xu9eV+%@St&+=PHP zySrBk(-0R%aSKO%`7`dPfHT8Dkg;792wwz^JXToddpT}-y<>A4T@z*|HQ0*|QW-9I z$I_46!~JD5XwCc6(ucJ+7<7xVdAt`?mamOU91H%UrN}KDA{|cH3A>IxxVBvp0%hOe z#?j`loKI*@-(saFs!!d~nyxwQ{%o9s@a!Q;a1k};E!|Vd4~DEHx;>_*9`>e;~IHj``LJL-YZiplIy~>oj`}$Ot7`t z(Y1nKS0a_vdSw$sLV=*FRJ<59L`y;n88{~QEt(&hJh*u;Aw#70f}qynX6&C19q-Gp zU^^(^W>X@Uypk^G6AT80YQ`cb(q?DI278W`!p09Ae$bdaJoo+xLA5OTwd?ryMhKiO zS$9+@K6IXM&Hr8X=_`_fP~rN9f)w*BVBLO6;C44C-=(5;(nE4{aQe<5Y`0^l9?h=kyb>8Zj%%0Ej*#D|`fFTTKRp zbHjvzM?}*Ril9YE&`C^gyTO!!`RCzloC8Vg2ljDPoeZ*?^7ToIYd2cn&8*KUZ?$M4 z)7sowTt4y!fdm{^6O`7A?m(FnA}uc_l{B1I_-&rvJ^?enxiZDQSNR$CE;R2wp5 zxO>hm+KrxzYKZ^U#&M#mWX)A$VRf)3GcPuh<+OVUjRFPRXDzuap^D(`t%wjlPUyQ! zup+njkxiFxdlhd!HR)Y_V=J$Vf@AXzP83X61wjnpjp!Gvi_7ZdW~t2w(|b$wqA3?5 zt@(x;PC4}My@{xOHuhXX&Arm{=?tGIMiXH#7 zWB%uRmnNl63bLolTZ&Swp&vgqBs;Xu?gG6~WUdF&5FqOa*BfG0MyIscWA`^@y9UiK z-h6&0bSo*?3Q5}-zQ&k~Hz_%*{o&83#G`_3*l~1P8$Idl)4=y1gWz$8R%;Q7m#i5x z)o*yETJv$?uAShdCE6`L2h1LzLh$Gwf4=$a)zgh1yogncu}_?YO#_PEI6jt|-XCtE zC8mD{zDHogl9)X)H4juBr~hyXPPnm}lD&d1=r;Y$f-m>R`>9r!vyI(0pFfA-eV`T& zZ7SYJt+s!<-?mp2c`WKmC*%ClJ*>>hyk^DHwagc5gD$i=BeSA6!M7?dL5vHCoL`tH zwS9tIZ1M;5MqA5Yv@X8CTc*%=Lj*G5IneBHDDJOsVL zK4_%wr(aL@d{!MeJHe?F5)={+yzCod*QS3F27YDo7!r&WIwT^LvfFyb@|68hO`a>mqlIHa~@sUaS-QL1CV8`2bpn;0&c5 zlR-MpB<8w@uVm&x+3Et^xSP%Bg1Q_514Fg9kuSbXuGq9E>zfua6hLi6+wJP7Mvm7X zLI-iDyz0lgf^=0;@0)fhy+(uT970MKzbAPq5;5J`7JSwX73k12==KHYnl`d8egndO zAf)1hkuw>NirtSQ<((@JfvH3lU5%jGyv!5;ID>$C?RIUr*Pvh_`?=fO^5>0VmPa`; zAUv^nVc&<%!MuBNl+-xu1CI0}?PqjU==3kGIlj!%C%YcdT#&aQS=SS1Yt*_YnRa5 zIB3ts?fj+~^}f>6aR>+t0dv2T#jvjTvD}taJeE2GNu8L4I7b#&dXjp^7-gmEqgRl# z&rCr>w`~oa*jDg$y=H(R#TD2ENC9|I&GOoqVpfb*ZJo~yySBQ^bD-wM@J`StZT^*2 zK^oV|3+{Se?nW!ld+iW?0oZnM(cEpzE~(DAs}g@~?j7J1ZrMR>dAwB4U&x_NWm=(ON}|R%<0nZK9|ZtEIK+pjNk8N=xljsnJ?h zt7eN@MeG@V>GM3__kBOV&-;1v&$;hA*B<9w*SSu-xv2pQBR?Ym04zp^I1Ad91OOla zPDfjX?1jIkUHFLlHbhHr7h<5J9|6$8dpi-3MxKs02o?lKe6Vi^K?49FF>Y2iL>m)h zb!Tr+8OOgcGC`g`G;9FS&<^r(bap2YkxqmgZeE(G)w(7W(haYPvQ{#|nE2=sT-^+B z`w=W}n_4;Fc6V08qqMb<8bRtb0-gk-BQnU-!^>YiNE7uhy6Uv`-(y)6@?RiCcTLp4 zg|aa*N9uX|5s*qU%F@nq3aUsIH5oZ2HC1`VGe~)ioU$xNO;%1(8Y8EUQB%jrA^-D3 z(YX2HUDPdb=l;Wsw$ntp5{W+Qva*4Jfii&#GTweSWaZS<)MPR8vhwoMGze+`U@xL$ zkhGV-$UhWt1b=5gHy@&#w-@p+MMo#^0HP*}Ch5Ob@bob;`7gp={{Jx)&1AAcjy|$- zG8kD;&%b*83)-J(LHKVm{#R&!t6(33tOdc}JHXGG<_{NxE-K1u1cJ1al7gx<0i%eQb|g6CrPUM^ROOT% z6`fQRRQ{p!zv1iY>+9$!>#C|@F!FM8`YJm5s`~nBigJqQbX9d!RuNXhkY_KeC zUJMk@G%;luB@luyyfchf(Qkgw&eFn|Wib9keq!cc9Jk&3&@u_+%CyG*tvrP=)1K_y z%$3~S%#Ha$$KPMGa}?%6Csz+NU)9m0Vn}X@qwK%MF;Gkwf~=?q^fQBu75?YOJ>emH zm`F_T;gx|A2Q(B@x=mJsx}HgSDvS+_X8E-1p+{PT2%N()yTZ-Sl0KEUJHrvu^XlX~ z>Sb*RWO(n>=1CovAs0KWasH>r+y2QX!MN!NN9aLD+zmKFcD{B(zZKxR+~WLNxRLqls^9YJ|etLqsh6GBs)7D9VL*#`(rvX1Ehta=)e(HTvnw` zZ>|9eyu0N?6=>IaBnH0g2o{1dWW=T11g0+e2UZK&aZ$<*dnr2kUd1~i(GnELbTTwD zZK|%};e!yqspn#m#?tw}xqv$kTNO}v#j-&H(hIx0W5h=h0bRYsrP~GEOa+S4%5H95 zA1!KY2HO|fV>?Mga3a^#rCIwWP0|$+?C=ylOfwFwnhawAmcGHDF#FcUOFFFl@Wq6q z*qi7=ewe-DaKGDD(O{Vf7c=CrXcYm5*fgBDKV$;6r9{69)g9=wf<&$w0J7!L2w_*s zYo+C4QCKgiaWwgj)7pDHwHa+V5Vuvl*?#dsXbvt#SZDsUy)-nkq9NdtNa#h_O#L`P=8sc%N_($9l z>eoV{>9~&VE+%lJBm?mvoB$rXy;Pc0Y+bgJr*NZtEGa2z#M9HWfp@B7FeIf-y{-NY zKMc+kI{r}b;nqRa(I=s!a`)vQ@0kwv_xI(d=A6FdI)O5)C-eqI2DMa*&kf9jt?p{y z1vN^l;S7=bBnA#Kv|z}ew;QrGGimp4-@Yy5;pUd<6=@6-^aJkWfU*a=2rEF-gQ8a* z%6!|eE$P&p^p$t>lFa+F3&h$S&^U|F3`D)i1&oDJbht=m1M91`OK;wUtkle1t-R55 z#JxRzih2H%fKWF?a1Tf-N(IzEe_o2CaPZIC53kGh#*fzp+Q*bq=>$r9ZXE8GLp-WU zCkzWnOK+{XB4wYf)Yu|>;k8~1^fcu?e!O=dV$ZG^kE8B0iv>;Fs`{<1T`6h$;RF^TZ$n?@X3)@a(@SqR?{D|8GKPca zrS^vh54M-<4zt|f*iMd(jdg*pfBxm^&VM`mMMHQpy>R|NvU5$qI(Po zi+4?K{jVliPAZQn`TlBwU7qb?2@<9-*zj($PvM_{O**E4@uB@`b0AZ&jx7FxG3$3> z3%K#4VCuo6>$lxZA|j4&!X2a5*21T(Q%I!rE|=50uwK4k1LobA+CEXMn|r<-*nw4u z{uD3O8myd!6S3#jOJ78Sf zO5s>9!|1wZX`T)Bi)_M&UM^h^Huy05`JrU%R~Hh&R;-5OE5xEsm`CQ%P|WNqt%*685E?3A5g$(@HY zXQ>TRl_P#F`HtjHN{(@>5gULV( zN$yMdLe|m#P}9V2mv{KaEveowL6K%*n(kX?K*L#@w)X)cv3XzaC>*`kF6<^Szx>l( zBp-HkDo9}om~`8Mb=)AAAxTfh+E_xzbQ}cOnh?7-+hvt!@?hFMA^<3uNPGvVn{5aC z2|fC5pbtFI3JceJ{OQjx&pJ8*iu7l#WBL;#b5Uj`6X(}FrZ&#k44`%f5Kvv6ks*d! z!-t?-%RiJR?`>~z?*`{?RvzWfZP-$ZO;$dMk-i=h<#mJ*!`#aaUo?+@cRjgLYFqi+ z(S3KcfM*xCu1V%u-x>fy7utGNmCcFJvh&`#$kE(Izl|=HK&`FsmZPOfS@PB+1k?gKX4RK7 zA9tvf&E*`MMeO&Vl9{Sh@yo8Tzc^GT+L5ddk6}EWm*8!k$Ut6=I6e>!3ky4LDWp7z zo5~1dqqu)uoGyZP+Gv|wfsoG_ArMHzeQxPz3)hpxsfs`5xPtA#jad+TYi6WEn)U0+ z9j1MD4X3Y<<(@BesZ1VL`%Zt}0v~veYcOd&2&*2gsXvkV9;)FP|G0?sY)}YyR5KU8 zH~VPFk#eKfP+PXA>?-9Gl4Mw8EjBqMdK_EjKi3`X|NE=0-jL8!Z1H;CPazIOlR#Tgf6Lcs33^SrlnQdpeilx2()T6>@DH{rE;;d(xdQVfsLHVU7 zd0Gt%6<=hocI}2vecj2_I%t2{XrG;`S6OBtcPRZW8&;sv05;?d!Bqm*Y0DE02cv`8 z8eDEdmg5j(S;6X`g8>|C2AOpGUE3helIua=F>6$wYs5ZD^WYGk-m{^mOLNR$aa$+C zhhvd__4Y0-xRQvWH`j(7mV|n2v>i(FZp~mzW;gC>(m*(O!1yJ)NNR+7j;Wn*E7zCE z3v(wfALV>{&kx%y=fYMWLWHI~4{}4-J7Vk8WY6M8!8x#|pD(oGAl&N!Ce$%1`SQ=) zkdX?)By79T))i|uJIQ_6=XllQ`=p^{N*tv!N~^VBWvg!X;ni9(vs{h58`LBs>s!mW zlxN}7;LZIAF3R|JP0`neor$`46?9jt!d<#G$x^$DjPn=iA}bp0#n!9eZ*OnU)CX_8 z3E&Q&kGXF=lN^*TujmBuW&o&%44hzXq`6#)>)$(nPvt9b$Jt4>(N}Me9yAQ^W4l**N&3v#Nd4CgL5Glr{K9vbV1<_0Q5$-B&(pWpHEVn0twRB2ZzraVM+& zCm){nRNSg3s*lrk>eVu#%f+1WHwI+7zB`s^XP?0i9v5>)NNUY>N|n_QpFY0ql^4hv zmh#7{_zv*14tVgGT;)AjV#{PVlP6Bil_Lq08prHg2yt3kp9gYE?3)^IjD7I!=iM{- z^V||wGKs)yQ{-zJJm?(UrL5o7lZB7TlKV5)#O%C=Pii~XkdPd@#UFrCzu%cRx*-o( zFZy*id}-)%zd{Uz=-ZLZ4zMs#KgMU1HH2Y-U zUI>)mEcd{JtOWd7TwHYCh-ga`tm3<$+yR@f2ww>iH_aYyGddmT7UeOte8r^N4dP z>ucTJ-Co=8hb-SE&Kd|ou&{s>)X5XTS(5YDybDL(=4DZe=7TJ|p9TL`&}22^3B8qu z-0zNXb82Z6uk+^wx7kQpUAq3FyFlj#FLi^_^~!P^paCxTw?D0^KK^bO4k#h=V@pAB7ckwLq%i3g zdU$U8@gN|BeDsBdZGelDtXR6R8P$*v?*0TY z^wIu>n97JO+h-u5cj6aS`1$$wJ5`1_gT@Mlv5I67leshFN19>#n?~xX)oyF-z-e$o zlz=v^RPZX3Z+>(da_2{uiob8KA8w& z{=s${uuv6qriK@y_i6Re1i?~=JEY8^_noUV2|1Wte-k7Ww%K?5Qx$2uFF$KT;(_W; zpLiw;q{XejbOydngdZ$BD=vy_#uT(VTLXMBOq_uYJyy7Y9H?ipy5F`c~fd5jRdjIsPFh4yR zFYk6wmras%Ue4h2@xf;2Fe-kts}SLuDrDXVd!2UTs++o!PLj!S~&7*)N#P_CtPGvT0iHt)}{GJG^Nbq4X67;VrMrO`fG;lBdCEQA|ggk)bA|iDt8lF4X!e9mO=_#;9Sd@H*$m7 z+8_)}p;wrn;YdkAI$-_M&bG!+7&-O}Z=xOf#}qmfHt%WixE7%5${p`1a0tpmxiX zuFL1!Ya`RHVyLiZ@gTgVu1e;PKkQ|!hV&tg!1(=W-7NNpMbQr#0TnI`Bf^WZfd7zT zlK0tis)69h@z1+LX?>rZEebgu;>_8Ym1`N%ijk#7a7i@9n7(7ZmB$``LQvxaeKGbP z_nrAf)HATDN^iR)qLqwzp#w^B)rqURD-^yP%c`|Ib%FWJMNm65<{S)l50s*NZmP<# z6_l^)f~<@Z-H zFGtc$LY);l-ff%Q*bDVn&$;te6MXx1%5C6{R6!tn3?CGw^AgK=6IlYDnc^_hSo6>3 z7R&Mxnd0Db_zqOe{yN75eV!!@bptHXh?(&1jUMge6`>=_-Q(T$FS7mbKEX>_FqH|| z>Xqp&<2w?!VfPbQQ%~A)YQ2r2|9a+WPOq*A?^Vk-9?aX^M~-yJ>lDx z$C^Qusj|0HNR@lYC;SzXQv$Xgc34br*ufU0=4y+iS3Z%2766k?Lh8hMNd1T|sk$ge z)S4{CG32j-m=(}zh=yIwgmdJ zXXKq*|EkZ;-BHWertgDVAzP+V1-}{TKo#Iqj2}gt@35Q{j97j@G|@5ZC;bkK=ZZg% z&UeH%xX@ipVoqDoLqgOMXw%jjBMr*@^JK4(=|mON^nGBOaX!YfD!*4+p@6_1W6Qu? z1Xj-gf?DWfhsqlF7pJzDM}@TfX5h_h*r$fL16CVytqa{2HmV>Bo0^n^A`2&8SO}%v z3Dx$$Tbg-l-rkh>tko(BI%VVJPd|8OHf86-l}F-_t(V!`AR>oYdTjD4y*%UEuyZnX zxn?eRbZ;VLRY^2GUQQ7c6YqqK!!WRyt5#)~=s3zasds1d9kJ-R87iN;mpCl^JB}}@ zyAIvLeC)DaIp-6S_}IUEG~emN?O>x=Ky_2?x7|T14E#2?wZivY>kSWDVH#m+X}M8! zsd(kj!h-OD0UTkQA)TH4)ih}&#QMxVkU9?j@y-oBby5aq8k>@j;Qd|N?D+I*Buw#)cEi|->}xEz*T(QP*S%w_ zLO3Y!>}Lh~0V~T`;0-!xCe>h@W%^dXiOP8Y=;(#0X5lF1i(o4cm}q%tn{psoqqDK- z8kn;I8LPpw|0g>8z5l4UQBb`pyneCZyTJQg}Hel%}U}dZZEy9aRE)~`5ZU1rG zK}i^7#KR^oT@q9urj&{_22%{D3;;e98qL5K2UV5G4xnX__sZ(3_ovKew?7*fm7|SF z3@L3mYz))}w_Z~ptBxv>IB(RrD>8TgCzw>AVPxgoEq{Tol=|{r^AGFcR}u85eYV3= zeAUL_z>nnq!~zE71+c7qj6Pt^ZWr`3HiuP%Le>k?tb6}H0Dd*}P5}^ni_P{qdpAMJ zLCCGgGWr9Tum?D<2y1SQWcrZCm_j(*T`MfTT0PN#??`)T`O28@GnthmrSL*I(4{b- zJTu4s3#}^v?OkR>T>{mH(Mkx}R<~c{wD$X42Y%h%X-!d#?1ox{2dlr%clAKfGdx3* zWUK+jVv-P>1_O5R%R}iWZ^Nnkk$W3+J+9u~Ld{KtSH@8S?+-Pm85!FIK#nE20%h>- zX`t5_sCLGZI7ziJi6>PiYJ=8(&C;^{)JNN9%q7U@eFjQHZt&PgKg9An8t=5G`G-IJeo570cL|t^h7B4RCCQAoJhTi(=hQ(#M+Y z(9&*)Tlxx7&)ZwJ#tnmikie7)23bFZJElMVK`ZMdpzKI-MFe?E{gKQyb^oo!fl2#v z2b~CO>mm5j@||`NzYrzPTsf5UG~Y8ZY)TN)^&W2q6#H2;C1T~nbW$;f&+F_`Nu|1& z$zuD|INF?uh$LNm+{uXnp&r3e_!Lo`05ncr;=2wVfOZDg=3*Rm_p3&|4z@2@UweOZ z`_IVosZ*!;a#8tC1Lfvei2(k$Ks8%r=K8e^#5?)+v)4>Q3`E%6)*XlLY3;$!4nP6)eS?-K)$WzrB!;&Z^zit85&Tbd34@lz>OEgMjl zSL5DqciD!`Z?pb$xqZ>j&=UC65?(&OQwDSqk!h6{Yy*QRRsr%Atss_|Ut55nQ_^i-Ml!{VMPuq+xmgi_3=57a|v&PL4z&P0TQa}tE zd}uUrEB*DRD}PI;<~uK49fzhqt23s;=7~^vG_(kYw)NY)#H)*=qzrMl}&rcdq#PG%tt;GX}0$D6xgwS~en_LRXsA@|*`KW%Sc1ebe`{47pt$l6sWKe<7Im3KH z%%3)zP_uA*;R|u5ioVPT;kA0eb|ZYnSK#JdXdo*Ci(jra8Ec7xG09|Uh3(foW`05b z9;p!jXLoJd-$u=EftZC)iR~^{t-~frVXt57D~bmk(*ak2|9maKEh^3{nwBkQ>O3mO zF$z9kdxu6w)GD7lH^1YhV|XPVoKHn@@NJ)qBUOwT-=Tn;aa{-`ts4Nl z7NJu?LX4rTW?)Kqac*wz!=t041zKt^G%xlh#`pGr`}Xb5qg#KJ4XvxTtt3azae`&> z!~KtM(k4S_fPdy1ZL&2MIkP$we5S}3B;Qqfq2_9!->p%179iqr=8zIL&plFb=!IWm zxQKdw&nkMKT9gH-8|ANmic4@KX&sCV)h{E5^7jMBCiAZ_WKmvxF8L?efJ^EVyltl;VWUq{+$to ze}27hlkturoh?Prh=m$wegT?d;%j9WbKZa zrC>Mjo>)ZTLCIY#-z7mWq^`5yM6$pA!j5+3o(gQ}#1#<0El=r?IQL{x(Gq%a%u_l^ zXxz!eJC}e{=oFJvmq>|>p_#nEAP4A~Rdo5s%M5f6tnvjJ5D)q1 zDO`F=mK*R|L=7>*%7m1hgeA`JUjt zKldblVALZ$Zb$0E*(^S^@;1}rL{L5skO9|9P~M>Bpzu6qdEe;H=POu58ZWp-FE0ND zLhWwK1q`%6#-iPYuOhik30mOjRDfvNslNkk86Zx7Bj1ep@Yd~TRm>j4|3A0=?;$S# db7~U+0lEjU3&o=INq;~0Fw!^0z0q}u`hVH*>cap4 literal 0 HcmV?d00001 diff --git a/Output/Themes/Genius/RapNotesFillMid.png b/Output/Themes/Genius/RapNotesFillMid.png new file mode 100644 index 0000000000000000000000000000000000000000..172b394a04a90a06d6774bb4923919fb685c7936 GIT binary patch literal 4502 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 SC0_%g=PcITIQP`$tN#YFVy}h( literal 0 HcmV?d00001 diff --git a/Output/Themes/Genius/RapNotesFillRight.png b/Output/Themes/Genius/RapNotesFillRight.png new file mode 100644 index 0000000000000000000000000000000000000000..2a0c56b422052699e49fff7806eefa2a33224ec4 GIT binary patch literal 9186 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 literal 0 HcmV?d00001 diff --git a/Output/Themes/Genius/RapNotesLeft.png b/Output/Themes/Genius/RapNotesLeft.png new file mode 100644 index 0000000000000000000000000000000000000000..ee6365d9d85a4f2ac3a5ad2aecc4e67672c96072 GIT binary patch literal 10817 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 literal 0 HcmV?d00001 diff --git a/Output/Themes/Genius/RapNotesMid.png b/Output/Themes/Genius/RapNotesMid.png new file mode 100644 index 0000000000000000000000000000000000000000..42146d4116dc42dbee6edfa0c993c6ad819a7e6f GIT binary patch literal 13180 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

&`PHAl<#u1P@kwg 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 NoteBackgroundMiddle NoteBackgroundRight + RapNoteLeft + RapNoteMiddle + RapNoteRight + RapNoteFillLeft + RapNoteFillMiddle + RapNoteFillRight + RapNoteBackgroundLeft + RapNoteBackgroundMiddle + RapNoteBackgroundRight Star ToneHelper Star From daec5064452a434bde5d0a6028bc438121282a95 Mon Sep 17 00:00:00 2001 From: Gary Kertopermono Date: Fri, 18 Jun 2021 10:58:55 +0200 Subject: [PATCH 20/39] Rap notes will use the rap notes graphics --- Output/Themes/Genius/01_Standard.xml | 9 +++++++ Output/Themes/Genius/02_Ice_Blue.xml | 9 +++++++ Output/Themes/Genius/03_Crimson_Red.xml | 9 +++++++ VocaluxeLib/Menu/SingNotes/CNoteBars.cs | 30 ++++++++++++------------ VocaluxeLib/Menu/SingNotes/CSingNotes.cs | 12 ++++++++++ 5 files changed, 54 insertions(+), 15 deletions(-) diff --git a/Output/Themes/Genius/01_Standard.xml b/Output/Themes/Genius/01_Standard.xml index eef172ef..3f3cda91 100644 --- a/Output/Themes/Genius/01_Standard.xml +++ b/Output/Themes/Genius/01_Standard.xml @@ -328,6 +328,15 @@ NotesBGLeft.png NotesBGMid.png NotesBGRight.png + RapNotesLeft.png + RapNotesMid.png + RapNotesRight.png + RapNotesFillLeft.png + RapNotesFillMid.png + RapNotesFillRight.png + RapNotesBGLeft.png + RapNotesBGMid.png + RapNotesBGRight.png PointsBar.png PointsBarBG.png LyricHelper.png diff --git a/Output/Themes/Genius/02_Ice_Blue.xml b/Output/Themes/Genius/02_Ice_Blue.xml index dbd343c1..17321512 100644 --- a/Output/Themes/Genius/02_Ice_Blue.xml +++ b/Output/Themes/Genius/02_Ice_Blue.xml @@ -328,6 +328,15 @@ NotesBGLeft.png NotesBGMid.png NotesBGRight.png + RapNotesLeft.png + RapNotesMid.png + RapNotesRight.png + RapNotesFillLeft.png + RapNotesFillMid.png + RapNotesFillRight.png + RapNotesBGLeft.png + RapNotesBGMid.png + RapNotesBGRight.png PointsBar.png PointsBarBG.png LyricHelper.png diff --git a/Output/Themes/Genius/03_Crimson_Red.xml b/Output/Themes/Genius/03_Crimson_Red.xml index 039c7501..76c6dfe1 100644 --- a/Output/Themes/Genius/03_Crimson_Red.xml +++ b/Output/Themes/Genius/03_Crimson_Red.xml @@ -328,6 +328,15 @@ NotesBGLeft.png NotesBGMid.png NotesBGRight.png + RapNotesLeft.png + RapNotesMid.png + RapNotesRight.png + RapNotesFillLeft.png + RapNotesFillMid.png + RapNotesFillRight.png + RapNotesBGLeft.png + RapNotesBGMid.png + RapNotesBGRight.png PointsBar.png PointsBarBG.png LyricHelper.png diff --git a/VocaluxeLib/Menu/SingNotes/CNoteBars.cs b/VocaluxeLib/Menu/SingNotes/CNoteBars.cs index d8ee4c06..585fb62f 100644 --- a/VocaluxeLib/Menu/SingNotes/CNoteBars.cs +++ b/VocaluxeLib/Menu/SingNotes/CNoteBars.cs @@ -109,8 +109,8 @@ namespace VocaluxeLib.Menu.SingNotes { SRectF rect = _GetNoteRect(note); - _DrawNoteBG(rect, color); - _DrawNoteBase(rect, new SColorF(_NoteBaseColor, _NoteBaseColor.A * Alpha), 1f); + _DrawNoteBG(rect, color, note.IsRapNote); + _DrawNoteBase(rect, new SColorF(_NoteBaseColor, _NoteBaseColor.A * Alpha), 1f, note.IsRapNote); } } @@ -128,7 +128,7 @@ namespace VocaluxeLib.Menu.SingNotes float factor = (note.Hit) ? 1f : 0.6f; - _DrawNoteFill(rect, color, factor); + _DrawNoteFill(rect, color, factor, note.IsRapNote); if (note.EndBeat >= CBase.Game.GetRecordedBeat() && note.Hit && note.IsGoldenNote) { @@ -275,26 +275,26 @@ namespace VocaluxeLib.Menu.SingNotes 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) + private void _DrawNoteBase(SRectF rect, SColorF color, float factor, bool isRapNote = false) { - CTextureRef noteBegin = CBase.Themes.GetSkinTexture(_Theme.SkinLeft, _PartyModeID); - CTextureRef noteMiddle = CBase.Themes.GetSkinTexture(_Theme.SkinMiddle, _PartyModeID); - CTextureRef noteEnd = CBase.Themes.GetSkinTexture(_Theme.SkinRight, _PartyModeID); + CTextureRef noteBegin = CBase.Themes.GetSkinTexture(isRapNote ? _Theme.SkinRapLeft : _Theme.SkinLeft, _PartyModeID); + CTextureRef noteMiddle = CBase.Themes.GetSkinTexture(isRapNote ? _Theme.SkinRapMiddle : _Theme.SkinMiddle, _PartyModeID); + CTextureRef noteEnd = CBase.Themes.GetSkinTexture(isRapNote ? _Theme.SkinRapRight : _Theme.SkinRight, _PartyModeID); _DrawNote(rect, color, noteBegin, noteMiddle, noteEnd, factor); } - private void _DrawNoteFill(SRectF rect, SColorF color, float factor) + private void _DrawNoteFill(SRectF rect, SColorF color, float factor, bool isRapNote = false) { - CTextureRef noteBegin = CBase.Themes.GetSkinTexture(_Theme.SkinFillLeft, _PartyModeID); - CTextureRef noteMiddle = CBase.Themes.GetSkinTexture(_Theme.SkinFillMiddle, _PartyModeID); - CTextureRef noteEnd = CBase.Themes.GetSkinTexture(_Theme.SkinFillRight, _PartyModeID); + CTextureRef noteBegin = CBase.Themes.GetSkinTexture(isRapNote ? _Theme.SkinRapFillLeft : _Theme.SkinFillLeft, _PartyModeID); + CTextureRef noteMiddle = CBase.Themes.GetSkinTexture(isRapNote ? _Theme.SkinRapFillMiddle : _Theme.SkinFillMiddle, _PartyModeID); + CTextureRef noteEnd = CBase.Themes.GetSkinTexture(isRapNote ? _Theme.SkinRapFillRight : _Theme.SkinFillRight, _PartyModeID); _DrawNote(rect, color, noteBegin, noteMiddle, noteEnd, factor); } - private void _DrawNoteBG(SRectF rect, SColorF color) + private void _DrawNoteBG(SRectF rect, SColorF color, bool isRapNote = false) { const float period = 1500; //[ms] @@ -308,9 +308,9 @@ namespace VocaluxeLib.Menu.SingNotes var col = new SColorF(color, color.A * alpha); - CTextureRef noteBegin = CBase.Themes.GetSkinTexture(_Theme.SkinBackgroundLeft, _PartyModeID); - CTextureRef noteMiddle = CBase.Themes.GetSkinTexture(_Theme.SkinBackgroundMiddle, _PartyModeID); - CTextureRef noteEnd = CBase.Themes.GetSkinTexture(_Theme.SkinBackgroundRight, _PartyModeID); + CTextureRef noteBegin = CBase.Themes.GetSkinTexture(isRapNote ? _Theme.SkinRapBackgroundLeft : _Theme.SkinBackgroundLeft, _PartyModeID); + CTextureRef noteMiddle = CBase.Themes.GetSkinTexture(isRapNote ? _Theme.SkinRapBackgroundMiddle : _Theme.SkinBackgroundMiddle, _PartyModeID); + CTextureRef noteEnd = CBase.Themes.GetSkinTexture(isRapNote ? _Theme.SkinRapBackgroundRight : _Theme.SkinBackgroundRight, _PartyModeID); _DrawNote(rect, col, noteBegin, noteMiddle, noteEnd, 1f); } diff --git a/VocaluxeLib/Menu/SingNotes/CSingNotes.cs b/VocaluxeLib/Menu/SingNotes/CSingNotes.cs index bedfb95c..4d49befc 100644 --- a/VocaluxeLib/Menu/SingNotes/CSingNotes.cs +++ b/VocaluxeLib/Menu/SingNotes/CSingNotes.cs @@ -49,6 +49,18 @@ namespace VocaluxeLib.Menu.SingNotes public string SkinBackgroundMiddle; public string SkinBackgroundRight; + public string SkinRapLeft; + public string SkinRapMiddle; + public string SkinRapRight; + + public string SkinRapFillLeft; + public string SkinRapFillMiddle; + public string SkinRapFillRight; + + public string SkinRapBackgroundLeft; + public string SkinRapBackgroundMiddle; + public string SkinRapBackgroundRight; + public string SkinGoldenStar; public string SkinToneHelper; public string SkinPerfectNoteStart; From 95f74f5b375df61cef4642e6153534822991d62b Mon Sep 17 00:00:00 2001 From: Gary Kertopermono Date: Mon, 28 Jun 2021 10:51:17 +0200 Subject: [PATCH 21/39] Fixed: Merge added double case for rap notes --- VocaluxeLib/Songs/CSongLoader.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/VocaluxeLib/Songs/CSongLoader.cs b/VocaluxeLib/Songs/CSongLoader.cs index 154eb067..beebe242 100644 --- a/VocaluxeLib/Songs/CSongLoader.cs +++ b/VocaluxeLib/Songs/CSongLoader.cs @@ -573,8 +573,6 @@ namespace VocaluxeLib.Songs case 'R': case 'G': case 'F': - case 'R': // Read R (RAP) and G (Golden RAP) notes as Freestyle notes currently. Final implementation needed! - case 'G': // Read R (RAP) and G (Golden RAP) notes as Freestyle notes currently. Final implementation needed! string[] noteData = line.Split(splitChars, 4); if (noteData.Length < 4) { From 143b3303f004284c8862e190eedc32da2ad8e242 Mon Sep 17 00:00:00 2001 From: Damien LAGUERRE Date: Fri, 22 Dec 2023 12:24:54 +0100 Subject: [PATCH 22/39] Improvements to TicTacToe : + Fix teams limited to 2 players + Add the possibility of changing players --- .../TicTacToe/Languages/English.xml | 3 +- .../PartyModes/TicTacToe/Languages/French.xml | 1 + .../Screens/PartyScreenTicTacToeConfig.xml | 58 ++++++++- .../Screens/PartyScreenTicTacToeMain.xml | 58 +++++++++ .../PartyModeTicTacToe/CPartyModeTicTacToe.cs | 1 + .../CPartyScreenTicTacToeConfig.cs | 7 +- .../CPartyScreenTicTacToeMain.cs | 118 +++++++++++++----- .../CPartyScreenTicTacToeNames.cs | 9 +- 8 files changed, 218 insertions(+), 37 deletions(-) diff --git a/Output/PartyModes/TicTacToe/Languages/English.xml b/Output/PartyModes/TicTacToe/Languages/English.xml index 0066f864..1581f008 100644 --- a/Output/PartyModes/TicTacToe/Languages/English.xml +++ b/Output/PartyModes/TicTacToe/Languages/English.xml @@ -17,7 +17,8 @@ Number of players in team 1 Number of players in team 2 Number of fields - Refill jokers every round + Refill jokers every round + Switch player Tic-Tac-Toe: Choose Player Selected players for this team: Team 1 diff --git a/Output/PartyModes/TicTacToe/Languages/French.xml b/Output/PartyModes/TicTacToe/Languages/French.xml index 67f9cd54..e37c90ab 100644 --- a/Output/PartyModes/TicTacToe/Languages/French.xml +++ b/Output/PartyModes/TicTacToe/Languages/French.xml @@ -18,6 +18,7 @@ Nombre de joueurs dans l'Equipe 2 Nombre de champs Recharger les jokers a chaque tour + Changement de joueur Tic-Tac-Toe: Choix des joueurs Equipe 1 Equipe 2 diff --git a/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeConfig.xml b/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeConfig.xml index a5ad9fa9..5d645321 100644 --- a/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeConfig.xml +++ b/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeConfig.xml @@ -2,7 +2,7 @@ PartyScreenTicTacToeConfig - 2 + 3 @@ -69,6 +69,20 @@ Outline TR_SCREENCONFIG_REFILLJOKERS + + 75 + 210 + 0 + 27 + 0 + + + Left + Center + + Outline + TR_SCREENCONFIG_SWITCH_PLAYER + + + diff --git a/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs b/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs index 321586c9..c1dab85b 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs @@ -127,6 +127,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe public int[] NumJokerRandom; public int[] NumJokerRetry; public EOffOn RefillJokers; + public EOffOn SwitchPlayer; } public SData GameData; diff --git a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs index 640fffbf..16fd7836 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs @@ -31,11 +31,12 @@ namespace VocaluxeLib.PartyModes.TicTacToe // Version number for theme files. Increment it, if you've changed something on the theme files! protected override int _ScreenVersion { - get { return 2; } + get { return 3; } } private const string _SelectSlideNumFields = "SelectSlideNumFields"; private const string _SelectSlideRefillJokers = "SelectSlideRefillJokers"; + private const string _SelectSlideSwitchPlayer = "SelectSlideSwitchPlayer"; private const string _ButtonNext = "ButtonNext"; private const string _ButtonBack = "ButtonBack"; @@ -133,12 +134,16 @@ namespace VocaluxeLib.PartyModes.TicTacToe _SelectSlides[_SelectSlideRefillJokers].AddValues(Enum.GetNames(typeof(EOffOn))); _SelectSlides[_SelectSlideRefillJokers].Selection = (int)_PartyMode.GameData.RefillJokers; + + _SelectSlides[_SelectSlideSwitchPlayer].AddValues(Enum.GetNames(typeof(EOffOn))); + _SelectSlides[_SelectSlideSwitchPlayer].Selection = (int)_PartyMode.GameData.SwitchPlayer; } private void _UpdateSlides() { _PartyMode.GameData.NumFields = _SelectSlides[_SelectSlideNumFields].SelectedTag; _PartyMode.GameData.RefillJokers = (EOffOn)_SelectSlides[_SelectSlideRefillJokers].Selection; + _PartyMode.GameData.SwitchPlayer = (EOffOn)_SelectSlides[_SelectSlideSwitchPlayer].Selection; } } } \ No newline at end of file diff --git a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs index a2722ed4..6143e9c4 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Windows.Forms; using VocaluxeLib.Menu; using VocaluxeLib.Songs; @@ -33,7 +34,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe // ReSharper disable UnusedMember.Global public class CPartyScreenTicTacToeMain : CPartyScreenTicTacToe - // ReSharper restore UnusedMember.Global + // ReSharper restore UnusedMember.Global { // Version number for theme files. Increment it, if you've changed something on the theme files! protected override int _ScreenVersion @@ -60,6 +61,8 @@ namespace VocaluxeLib.PartyModes.TicTacToe private const string _ButtonJokerRandomT2 = "ButtonJokerRandomT2"; private const string _ButtonJokerRetryT1 = "ButtonJokerRetryT1"; private const string _ButtonJokerRetryT2 = "ButtonJokerRetryT2"; + private const string _ButtonSwitchPlayerT1 = "ButtonSwitchPlayerT1"; + private const string _ButtonSwitchPlayerT2 = "ButtonSwitchPlayerT2"; private const string _StaticPopupBG = "StaticPopupBG"; private const string _StaticAvatarT1 = "StaticAvatarT1"; @@ -78,6 +81,9 @@ namespace VocaluxeLib.PartyModes.TicTacToe private const int _FieldSpace = 10; private float _FieldSize = 100; + int idPlayer1 = 0; + int idPlayer2 = 0; + private int _OldSelectedField = -1; private int[,] _Possibilities; @@ -94,7 +100,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe _ButtonNextRound, _ButtonBack, _ButtonExit, _ButtonPopupYes, _ButtonPopupNo, _ButtonField, _ButtonJokerRandomT1, _ButtonJokerRandomT2, _ButtonJokerRetryT1, _ButtonJokerRetryT2 }; - _ThemeStatics = new string[] {_StaticPopupBG, _StaticAvatarT1, _StaticAvatarT2, _StaticTeam1, _StaticTeam2}; + _ThemeStatics = new string[] { _StaticPopupBG, _StaticAvatarT1, _StaticAvatarT2, _StaticTeam1, _StaticTeam2 }; var texts = new List(); texts.AddRange(_EqualizerTeam); @@ -116,7 +122,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe { base.HandleInput(keyEvent); - if (keyEvent.KeyPressed) {} + if (keyEvent.KeyPressed) { } else { switch (keyEvent.Key) @@ -243,6 +249,10 @@ namespace VocaluxeLib.PartyModes.TicTacToe _UseJoker(0, 1); if (_Buttons[_ButtonJokerRetryT2].Selected) _UseJoker(1, 1); + if (_Buttons[_ButtonSwitchPlayerT1].Selected) + _ChangePlayer(0, true); + if (_Buttons[_ButtonSwitchPlayerT2].Selected) + _ChangePlayer(1, true); } } else @@ -269,7 +279,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe _ShowPopup(false); } - if (mouseEvent.Wheel != 0) {} + if (mouseEvent.Wheel != 0) { } return true; } @@ -323,6 +333,8 @@ namespace VocaluxeLib.PartyModes.TicTacToe _Buttons[_ButtonJokerRandomT2].Visible = false; _Buttons[_ButtonJokerRetryT1].Visible = false; _Buttons[_ButtonJokerRetryT2].Visible = false; + _Buttons[_ButtonSwitchPlayerT1].Visible = false; + _Buttons[_ButtonSwitchPlayerT2].Visible = false; _Buttons[_ButtonNextRound].Visible = false; _Texts[_TextFinishMessage].Visible = false; } @@ -357,9 +369,9 @@ namespace VocaluxeLib.PartyModes.TicTacToe for (int i = 0; i < 2; i++) { CBase.Record.AnalyzeBuffer(i); - _Equalizers["EqualizerTeam" + (i+1)].Update(CBase.Record.ToneWeigth(i), CBase.Record.GetMaxVolume(i)); + _Equalizers["EqualizerTeam" + (i + 1)].Update(CBase.Record.ToneWeigth(i), CBase.Record.GetMaxVolume(i)); } - + return true; } @@ -453,38 +465,22 @@ namespace VocaluxeLib.PartyModes.TicTacToe { if (!jokerUsed) { - int singerTeam1 = 0; - int singerTeam2 = 0; - - if (_PartyMode.GameData.PlayerTeam1.Count > 0) - { - singerTeam1 = _PartyMode.GameData.PlayerTeam1[0]; - _PartyMode.GameData.PlayerTeam1.RemoveAt(0); - } - - if (_PartyMode.GameData.PlayerTeam2.Count > 0) - { - singerTeam2 = _PartyMode.GameData.PlayerTeam2[0]; - _PartyMode.GameData.PlayerTeam2.RemoveAt(0); - } - _PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam1 = singerTeam1; - _PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam2 = singerTeam2; - - _UpdatePlayerInformation(); + _ChangePlayer(); } _PartyMode.UpdateSongList(); int[] songIDs = new int[_PartyMode.GameData.GameMode == EGameMode.TR_GAMEMODE_MEDLEY ? _PartyMode.GameData.NumMedleySongs : 1]; - for(int i = 0; i < songIDs.Length; i++) + for (int i = 0; i < songIDs.Length; i++) { songIDs[i] = _PartyMode.GameData.Songs[0]; _PartyMode.GameData.Songs.RemoveAt(0); - } + } _StartPreview(songIDs[0]); _Status = EStatus.FieldSelected; _PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SongIDs = songIDs; _UpdateFieldContents(); _UpdateJokerButtons(); + _UpdateSwitchPlayerButtons(); _Buttons[_ButtonNextRound].Visible = true; _Buttons[_ButtonExit].Visible = true; @@ -519,6 +515,60 @@ namespace VocaluxeLib.PartyModes.TicTacToe CBase.BackgroundMusic.LoadPreview(song); } + private int _GetRamdom(int max) + { + var rnd = new Random(); + return Enumerable + .Range(1, max) + .OrderBy(x => rnd.Next()) + .ToArray()[0]; + } + + private void _ChangePlayer(int teamNr = -1, bool next = false) + { + int singerTeam1 = 0; + int singerTeam2 = 0; + + if (_PartyMode.GameData.PlayerTeam1.Count > 0 && (teamNr == 0 || teamNr == -1)) + { + if (next == true) + { + idPlayer1++; + if (idPlayer1 >= _PartyMode.GameData.PlayerTeam1.Count) + { + idPlayer1 = 0; + } + } + else + { + idPlayer1 = _GetRamdom(_PartyMode.GameData.PlayerTeam1.Count - 1); + } + + singerTeam1 = _PartyMode.GameData.PlayerTeam1[idPlayer1]; + _PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam1 = singerTeam1; + } + + if (_PartyMode.GameData.PlayerTeam2.Count > 0 && (teamNr == 1 || teamNr == -1)) + { + if (next == true) + { + idPlayer2++; + if (idPlayer2 >= _PartyMode.GameData.PlayerTeam2.Count) + { + idPlayer2 = 0; + } + } + else + { + idPlayer2 = _GetRamdom(_PartyMode.GameData.PlayerTeam2.Count - 1); + } + singerTeam2 = _PartyMode.GameData.PlayerTeam2[idPlayer2]; + _PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam2 = singerTeam2; + } + + _UpdatePlayerInformation(); + } + private void _UpdatePlayerInformation() { _Texts[_TextNextPlayerT1].Visible = true; @@ -543,7 +593,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe { switch (jokerNum) { - //Random-Joker + //Random-Joker case 0: if (_PartyMode.GameData.NumJokerRandom[teamNr] > 0) { @@ -552,7 +602,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe } break; - //Retry-Joker + //Retry-Joker case 1: if (_PartyMode.GameData.NumJokerRetry[teamNr] > 0 && _PartyMode.GameData.CurrentRoundNr > 1) { @@ -596,6 +646,16 @@ namespace VocaluxeLib.PartyModes.TicTacToe _Buttons[_ButtonJokerRetryT2].Selectable = _PartyMode.GameData.NumJokerRetry[1] > 0 && _PartyMode.GameData.CurrentRoundNr > 1; } + private void _UpdateSwitchPlayerButtons() + { + if (_PartyMode.GameData.SwitchPlayer == EOffOn.TR_CONFIG_ON) + { + _Buttons[_ButtonSwitchPlayerT1].Visible = true; + _Buttons[_ButtonSwitchPlayerT2].Visible = true; + } + + } + private void _NextRound() { _PartyMode.Next(); @@ -627,7 +687,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe private void _BuildWinnerPossibilities() { var numOneRow = (int)Math.Sqrt(_PartyMode.GameData.NumFields); - _Possibilities = new int[(numOneRow * 2) + 2,numOneRow]; + _Possibilities = new int[(numOneRow * 2) + 2, numOneRow]; for (int i = 0; i < _Possibilities.GetLength(0); i++) { if (i < numOneRow) diff --git a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeNames.cs b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeNames.cs index 49241507..04e8b91f 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeNames.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeNames.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; +using System.Linq; using VocaluxeLib.Menu; namespace VocaluxeLib.PartyModes.TicTacToe @@ -76,11 +77,9 @@ namespace VocaluxeLib.PartyModes.TicTacToe _PartyMode.GameData.ProfileIDsTeam1 = _TeamList[0]; _PartyMode.GameData.ProfileIDsTeam2 = _TeamList[1]; } - if (_NumPlayerTeams.Length == 2) - { - _PartyMode.GameData.NumPlayerTeam1 = _NumPlayerTeams[0]; - _PartyMode.GameData.NumPlayerTeam2 = _NumPlayerTeams[1]; - } + _PartyMode.GameData.NumPlayerTeam1 = _PartyMode.GameData.ProfileIDsTeam1.Count(); + _PartyMode.GameData.NumPlayerTeam2 = _PartyMode.GameData.ProfileIDsTeam2.Count(); + _PartyMode.Next(); } } From cfca322fcdc999509b4e7a4fa250e1e596136643 Mon Sep 17 00:00:00 2001 From: Damien LAGUERRE Date: Fri, 22 Dec 2023 15:47:15 +0100 Subject: [PATCH 23/39] Improves the random choice of players. --- .../PartyModeTicTacToe/CPartyModeTicTacToe.cs | 111 ------------------ .../CPartyScreenTicTacToeMain.cs | 35 +++--- 2 files changed, 17 insertions(+), 129 deletions(-) diff --git a/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs b/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs index c1dab85b..2ec3499c 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs @@ -107,8 +107,6 @@ namespace VocaluxeLib.PartyModes.TicTacToe public int Team; public List ProfileIDsTeam1; public List ProfileIDsTeam2; - public List PlayerTeam1; - public List PlayerTeam2; public ESongSource SongSource; public ESongSorting Sorting; @@ -152,8 +150,6 @@ namespace VocaluxeLib.PartyModes.TicTacToe NumFields = 9, ProfileIDsTeam1 = new List(), ProfileIDsTeam2 = new List(), - PlayerTeam1 = new List(), - PlayerTeam2 = new List(), CurrentRoundNr = 0, FieldNr = 0, Sorting = CBase.Config.GetSongSorting(), @@ -184,8 +180,6 @@ namespace VocaluxeLib.PartyModes.TicTacToe GameData.Songs.Clear(); GameData.Rounds.Clear(); - GameData.PlayerTeam1.Clear(); - GameData.PlayerTeam2.Clear(); } public override bool Init() @@ -248,7 +242,6 @@ namespace VocaluxeLib.PartyModes.TicTacToe GameData.CurrentRoundNr = 1; _CreateRounds(); _SetNumJokers(); - _PreparePlayerList(0); break; case EStage.Main: _Stage = EStage.Singing; @@ -257,7 +250,6 @@ namespace VocaluxeLib.PartyModes.TicTacToe case EStage.Singing: _Stage = EStage.Main; GameData.Team = GameData.Team == 1 ? 0 : 1; - _UpdatePlayerList(); if (GameData.RefillJokers == EOffOn.TR_CONFIG_ON) _SetNumJokers(); break; @@ -338,101 +330,6 @@ namespace VocaluxeLib.PartyModes.TicTacToe } } - private void _PreparePlayerList(int team) - { - switch (team) - { - case 0: - { - GameData.PlayerTeam1 = new List(); - GameData.PlayerTeam2 = new List(); - - //Prepare Player-IDs - var ids1 = new List(); - var ids2 = new List(); - //Add IDs to team-list - while (GameData.PlayerTeam1.Count < GameData.NumFields + GameData.NumJokerRetry[0] && - GameData.PlayerTeam2.Count < GameData.NumFields + GameData.NumJokerRetry[1]) - { - if (ids1.Count == 0) - { - for (int i = 0; i < GameData.NumPlayerTeam1; i++) - ids1.Add(i); - } - if (ids2.Count == 0) - { - for (int i = 0; i < GameData.NumPlayerTeam2; i++) - ids2.Add(i); - } - int num; - if (GameData.PlayerTeam1.Count < GameData.NumFields + GameData.NumJokerRetry[0]) - { - num = CBase.Game.GetRandom(ids1.Count); - if (num >= ids1.Count) - num = ids1.Count - 1; - GameData.PlayerTeam1.Add(ids1[num]); - ids1.RemoveAt(num); - } - if (GameData.PlayerTeam2.Count < GameData.NumFields + GameData.NumJokerRetry[1]) - { - num = CBase.Game.GetRandom(ids2.Count); - if (num >= ids2.Count) - num = ids2.Count - 1; - GameData.PlayerTeam2.Add(ids2[num]); - ids2.RemoveAt(num); - } - } - } - break; - case 1: - { - //Prepare Player-IDs - var ids = new List(); - //Add IDs to team-list - while (GameData.PlayerTeam1.Count < GameData.NumFields + GameData.NumJokerRetry[0] && ids.Count == 0) - { - if (ids.Count == 0) - { - for (int i = 0; i < GameData.NumPlayerTeam1; i++) - ids.Add(i); - } - if (GameData.PlayerTeam1.Count < GameData.NumFields + GameData.NumJokerRetry[0]) - { - int num = CBase.Game.GetRandom(ids.Count); - if (num >= ids.Count) - num = ids.Count - 1; - GameData.PlayerTeam1.Add(ids[num]); - ids.RemoveAt(num); - } - } - } - break; - case 2: - { - //Prepare Player-IDs - var ids = new List(); - //Add IDs to team-list - while (GameData.PlayerTeam2.Count < GameData.NumFields + GameData.NumJokerRetry[1] && ids.Count == 0) - { - if (ids.Count == 0) - { - for (int i = 0; i < GameData.NumPlayerTeam2; i++) - ids.Add(i); - } - if (GameData.PlayerTeam2.Count < GameData.NumFields + GameData.NumJokerRetry[1]) - { - int num = CBase.Game.GetRandom(ids.Count); - if (num >= ids.Count) - num = ids.Count - 1; - GameData.PlayerTeam2.Add(ids[num]); - ids.RemoveAt(num); - } - } - } - break; - } - } - public void UpdateSongList() { if (GameData.Songs.Count > 0) @@ -466,14 +363,6 @@ namespace VocaluxeLib.PartyModes.TicTacToe GameData.Songs.Shuffle(); } - private void _UpdatePlayerList() - { - if (GameData.PlayerTeam1.Count == 0) - _PreparePlayerList(1); - if (GameData.PlayerTeam2.Count == 0) - _PreparePlayerList(2); - } - private void _StartRound(int roundNr) { CBase.Game.Reset(); diff --git a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs index 6143e9c4..72f46d68 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs @@ -84,6 +84,9 @@ namespace VocaluxeLib.PartyModes.TicTacToe int idPlayer1 = 0; int idPlayer2 = 0; + private static readonly Random random = new Random(); + private static readonly object syncLock = new object(); + private int _OldSelectedField = -1; private int[,] _Possibilities; @@ -98,7 +101,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe _ThemeButtons = new string[] { _ButtonNextRound, _ButtonBack, _ButtonExit, _ButtonPopupYes, _ButtonPopupNo, _ButtonField, _ButtonJokerRandomT1, _ButtonJokerRandomT2, _ButtonJokerRetryT1, - _ButtonJokerRetryT2 + _ButtonJokerRetryT2, _ButtonSwitchPlayerT1, _ButtonSwitchPlayerT2 }; _ThemeStatics = new string[] { _StaticPopupBG, _StaticAvatarT1, _StaticAvatarT2, _StaticTeam1, _StaticTeam2 }; @@ -517,53 +520,49 @@ namespace VocaluxeLib.PartyModes.TicTacToe private int _GetRamdom(int max) { - var rnd = new Random(); - return Enumerable - .Range(1, max) - .OrderBy(x => rnd.Next()) - .ToArray()[0]; + lock (syncLock) + { + return random.Next(max+1); + } } private void _ChangePlayer(int teamNr = -1, bool next = false) { - int singerTeam1 = 0; - int singerTeam2 = 0; - if (_PartyMode.GameData.PlayerTeam1.Count > 0 && (teamNr == 0 || teamNr == -1)) + if (_PartyMode.GameData.ProfileIDsTeam1.Count > 0 && (teamNr == 0 || teamNr == -1)) { if (next == true) { idPlayer1++; - if (idPlayer1 >= _PartyMode.GameData.PlayerTeam1.Count) + if (idPlayer1 >= _PartyMode.GameData.ProfileIDsTeam1.Count) { idPlayer1 = 0; } } else { - idPlayer1 = _GetRamdom(_PartyMode.GameData.PlayerTeam1.Count - 1); + idPlayer1 = _GetRamdom(_PartyMode.GameData.ProfileIDsTeam1.Count - 1); } - singerTeam1 = _PartyMode.GameData.PlayerTeam1[idPlayer1]; - _PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam1 = singerTeam1; + _PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam1 = idPlayer1; } - if (_PartyMode.GameData.PlayerTeam2.Count > 0 && (teamNr == 1 || teamNr == -1)) + if (_PartyMode.GameData.ProfileIDsTeam2.Count > 0 && (teamNr == 1 || teamNr == -1)) { if (next == true) { idPlayer2++; - if (idPlayer2 >= _PartyMode.GameData.PlayerTeam2.Count) + if (idPlayer2 >= _PartyMode.GameData.ProfileIDsTeam2.Count) { idPlayer2 = 0; } } else { - idPlayer2 = _GetRamdom(_PartyMode.GameData.PlayerTeam2.Count - 1); + idPlayer2 = _GetRamdom(_PartyMode.GameData.ProfileIDsTeam2.Count - 1); } - singerTeam2 = _PartyMode.GameData.PlayerTeam2[idPlayer2]; - _PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam2 = singerTeam2; + + _PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam2 = idPlayer2; } _UpdatePlayerInformation(); From 5360b997454bde2fee419eaf8c9be73c4a78a575 Mon Sep 17 00:00:00 2001 From: Damien LAGUERRE Date: Fri, 22 Dec 2023 17:16:18 +0100 Subject: [PATCH 24/39] Add number of jocker as game parameter. + Missing input handler for player switch action. --- .../PartyModeTicTacToe/CPartyModeTicTacToe.cs | 12 ++++++------ .../CPartyScreenTicTacToeConfig.cs | 13 ++++++++++++- .../PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs | 4 ++++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs b/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs index 2ec3499c..6a911fcd 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs @@ -104,6 +104,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe public int NumPlayerTeam1; public int NumPlayerTeam2; public int NumFields; + public int NumJockers; public int Team; public List ProfileIDsTeam1; public List ProfileIDsTeam2; @@ -148,6 +149,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe NumPlayerTeam1 = 2, NumPlayerTeam2 = 2, NumFields = 9, + NumJockers = 1, ProfileIDsTeam1 = new List(), ProfileIDsTeam2 = new List(), CurrentRoundNr = 0, @@ -395,25 +397,23 @@ namespace VocaluxeLib.PartyModes.TicTacToe private void _SetNumJokers() { + + GameData.NumJokerRandom[0] = GameData.NumJockers; + GameData.NumJokerRandom[1] = GameData.NumJockers; + switch (GameData.NumFields) { case 9: - GameData.NumJokerRandom[0] = 1; - GameData.NumJokerRandom[1] = 1; GameData.NumJokerRetry[0] = 0; GameData.NumJokerRetry[1] = 0; break; case 16: - GameData.NumJokerRandom[0] = 2; - GameData.NumJokerRandom[1] = 2; GameData.NumJokerRetry[0] = 1; GameData.NumJokerRetry[1] = 1; break; case 25: - GameData.NumJokerRandom[0] = 3; - GameData.NumJokerRandom[1] = 3; GameData.NumJokerRetry[0] = 2; GameData.NumJokerRetry[1] = 2; break; diff --git a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs index 16fd7836..8e0fdc8a 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs @@ -35,7 +35,9 @@ namespace VocaluxeLib.PartyModes.TicTacToe } private const string _SelectSlideNumFields = "SelectSlideNumFields"; + private const string _SelectSlideNumJockers = "SelectSlideNumJockers"; private const string _SelectSlideRefillJokers = "SelectSlideRefillJokers"; + private const string _SelectSlideNumJokers = "SelectSlideNumJokers"; private const string _SelectSlideSwitchPlayer = "SelectSlideSwitchPlayer"; private const string _ButtonNext = "ButtonNext"; @@ -47,7 +49,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe { base.Init(); - _ThemeSelectSlides = new string[] { _SelectSlideNumFields }; + _ThemeSelectSlides = new string[] { _SelectSlideNumFields, _SelectSlideNumJokers, _SelectSlideRefillJokers, _SelectSlideSwitchPlayer }; _ThemeButtons = new string[] {_ButtonNext, _ButtonBack}; } @@ -132,6 +134,14 @@ namespace VocaluxeLib.PartyModes.TicTacToe _SelectSlides[_SelectSlideNumFields].SelectedTag = _PartyMode.GameData.NumFields; + _SelectSlides[_SelectSlideNumJockers].Clear(); + _SelectSlides[_SelectSlideNumJockers].AddValue(0); + _SelectSlides[_SelectSlideNumJockers].AddValue(1); + _SelectSlides[_SelectSlideNumJockers].AddValue(2); + _SelectSlides[_SelectSlideNumJockers].AddValue(3); + + _SelectSlides[_SelectSlideNumJockers].SelectedTag = _PartyMode.GameData.NumJockers; + _SelectSlides[_SelectSlideRefillJokers].AddValues(Enum.GetNames(typeof(EOffOn))); _SelectSlides[_SelectSlideRefillJokers].Selection = (int)_PartyMode.GameData.RefillJokers; @@ -142,6 +152,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe private void _UpdateSlides() { _PartyMode.GameData.NumFields = _SelectSlides[_SelectSlideNumFields].SelectedTag; + _PartyMode.GameData.NumJockers = _SelectSlides[_SelectSlideNumJockers].Selection; _PartyMode.GameData.RefillJokers = (EOffOn)_SelectSlides[_SelectSlideRefillJokers].Selection; _PartyMode.GameData.SwitchPlayer = (EOffOn)_SelectSlides[_SelectSlideSwitchPlayer].Selection; } diff --git a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs index 72f46d68..b52671e1 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs @@ -187,6 +187,10 @@ namespace VocaluxeLib.PartyModes.TicTacToe _UseJoker(0, 1); if (_Buttons[_ButtonJokerRetryT2].Selected) _UseJoker(1, 1); + if (_Buttons[_ButtonSwitchPlayerT1].Selected) + _ChangePlayer(0, true); + if (_Buttons[_ButtonSwitchPlayerT2].Selected) + _ChangePlayer(1, true); } } else From fddd2f3f2fdd40dfa75aa859b9fe6884396ebc6a Mon Sep 17 00:00:00 2001 From: Damien LAGUERRE Date: Fri, 22 Dec 2023 17:46:03 +0100 Subject: [PATCH 25/39] TicTacToe: Add jockers select to config screen. + Translation. --- .../TicTacToe/Languages/English.xml | 1 + .../PartyModes/TicTacToe/Languages/French.xml | 1 + .../Screens/PartyScreenTicTacToeConfig.xml | 68 +++++++++++++++++-- 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/Output/PartyModes/TicTacToe/Languages/English.xml b/Output/PartyModes/TicTacToe/Languages/English.xml index 1581f008..49e44511 100644 --- a/Output/PartyModes/TicTacToe/Languages/English.xml +++ b/Output/PartyModes/TicTacToe/Languages/English.xml @@ -18,6 +18,7 @@ Number of players in team 2 Number of fields Refill jokers every round + Number of jokers Switch player Tic-Tac-Toe: Choose Player Selected players for this team: diff --git a/Output/PartyModes/TicTacToe/Languages/French.xml b/Output/PartyModes/TicTacToe/Languages/French.xml index e37c90ab..73413bae 100644 --- a/Output/PartyModes/TicTacToe/Languages/French.xml +++ b/Output/PartyModes/TicTacToe/Languages/French.xml @@ -18,6 +18,7 @@ Nombre de joueurs dans l'Equipe 2 Nombre de champs Recharger les jokers a chaque tour + Nombre de jokers Changement de joueur Tic-Tac-Toe: Choix des joueurs Equipe 1 diff --git a/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeConfig.xml b/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeConfig.xml index 5d645321..c879b56a 100644 --- a/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeConfig.xml +++ b/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeConfig.xml @@ -55,7 +55,7 @@ Outline TR_SCREENCONFIG_NUMFIELDS - + 75 165 0 @@ -67,11 +67,25 @@ Center Outline + TR_SCREENCONFIG_NUMJOKERS + + + 75 + 225 + 0 + 27 + 0 + + + Left + Center + + Outline TR_SCREENCONFIG_REFILLJOKERS 75 - 210 + 285 0 27 0 @@ -201,7 +215,7 @@ Bold 3 - + SelectSlideArrowLeft SelectSlideArrowRight @@ -241,6 +255,48 @@ 205.33 Outline Bold + 3 + + + + SelectSlideArrowLeft + SelectSlideArrowRight + SelectSlide + SelectSlideArrowLeft + SelectSlideArrowRight + + 500 + 220 + 700 + 50 + 0 + + + 505 + 225 + 40 + 40 + 0 + + + 1155 + 225 + 40 + 40 + 0 + + + + + + + + 27 + 50 + 0 + 205.33 + Outline + Bold 2 @@ -252,21 +308,21 @@ SelectSlideArrowRight 500 - 210 + 270 700 50 0 505 - 215 + 275 40 40 0 1155 - 215 + 275 40 40 0 From b7938ba71cd1790e62f18ff57a0b8b86a5a02c02 Mon Sep 17 00:00:00 2001 From: Damien LAGUERRE Date: Sat, 23 Dec 2023 19:50:07 +0100 Subject: [PATCH 26/39] TicTacToe: Optimisation and code compliance --- .../CPartyScreenTicTacToeConfig.cs | 12 ++--- .../CPartyScreenTicTacToeMain.cs | 49 ++++++++----------- .../CPartyScreenTicTacToeNames.cs | 4 +- 3 files changed, 28 insertions(+), 37 deletions(-) diff --git a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs index 8e0fdc8a..0d68bb52 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs @@ -26,7 +26,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe { // ReSharper disable UnusedMember.Global public class CPartyScreenTicTacToeConfig : CPartyScreenTicTacToe - // ReSharper restore UnusedMember.Global + // ReSharper restore UnusedMember.Global { // Version number for theme files. Increment it, if you've changed something on the theme files! protected override int _ScreenVersion @@ -50,14 +50,14 @@ namespace VocaluxeLib.PartyModes.TicTacToe base.Init(); _ThemeSelectSlides = new string[] { _SelectSlideNumFields, _SelectSlideNumJokers, _SelectSlideRefillJokers, _SelectSlideSwitchPlayer }; - _ThemeButtons = new string[] {_ButtonNext, _ButtonBack}; + _ThemeButtons = new string[] { _ButtonNext, _ButtonBack }; } public override bool HandleInput(SKeyEvent keyEvent) { base.HandleInput(keyEvent); - if (keyEvent.KeyPressed) {} + if (keyEvent.KeyPressed) { } else { switch (keyEvent.Key) @@ -135,10 +135,8 @@ namespace VocaluxeLib.PartyModes.TicTacToe _SelectSlides[_SelectSlideNumFields].SelectedTag = _PartyMode.GameData.NumFields; _SelectSlides[_SelectSlideNumJockers].Clear(); - _SelectSlides[_SelectSlideNumJockers].AddValue(0); - _SelectSlides[_SelectSlideNumJockers].AddValue(1); - _SelectSlides[_SelectSlideNumJockers].AddValue(2); - _SelectSlides[_SelectSlideNumJockers].AddValue(3); + for (int i = 0; i <= 3; i++) + _SelectSlides[_SelectSlideNumJockers].AddValue(i); _SelectSlides[_SelectSlideNumJockers].SelectedTag = _PartyMode.GameData.NumJockers; diff --git a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs index b52671e1..9f04452d 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeMain.cs @@ -81,8 +81,8 @@ namespace VocaluxeLib.PartyModes.TicTacToe private const int _FieldSpace = 10; private float _FieldSize = 100; - int idPlayer1 = 0; - int idPlayer2 = 0; + private int idPlayer1 = 0; + private int idPlayer2 = 0; private static readonly Random random = new Random(); private static readonly object syncLock = new object(); @@ -535,43 +535,36 @@ namespace VocaluxeLib.PartyModes.TicTacToe if (_PartyMode.GameData.ProfileIDsTeam1.Count > 0 && (teamNr == 0 || teamNr == -1)) { - if (next == true) - { - idPlayer1++; - if (idPlayer1 >= _PartyMode.GameData.ProfileIDsTeam1.Count) - { - idPlayer1 = 0; - } - } - else - { - idPlayer1 = _GetRamdom(_PartyMode.GameData.ProfileIDsTeam1.Count - 1); - } - + idPlayer1 = _GetTeamPlayer(idPlayer1, _PartyMode.GameData.ProfileIDsTeam1.Count, next); _PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam1 = idPlayer1; } if (_PartyMode.GameData.ProfileIDsTeam2.Count > 0 && (teamNr == 1 || teamNr == -1)) { - if (next == true) - { - idPlayer2++; - if (idPlayer2 >= _PartyMode.GameData.ProfileIDsTeam2.Count) - { - idPlayer2 = 0; - } - } - else - { - idPlayer2 = _GetRamdom(_PartyMode.GameData.ProfileIDsTeam2.Count - 1); - } - + idPlayer2 = _GetTeamPlayer(idPlayer2, _PartyMode.GameData.ProfileIDsTeam2.Count, next); _PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam2 = idPlayer2; } _UpdatePlayerInformation(); } + private int _GetTeamPlayer(int idPlayer, int teamCount, bool next) + { + if (next) + { + idPlayer++; + if (idPlayer >= _PartyMode.GameData.ProfileIDsTeam1.Count) + { + idPlayer = 0; + } + } + else + { + idPlayer = _GetRamdom(_PartyMode.GameData.ProfileIDsTeam1.Count - 1); + } + return idPlayer; + } + private void _UpdatePlayerInformation() { _Texts[_TextNextPlayerT1].Visible = true; diff --git a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeNames.cs b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeNames.cs index 04e8b91f..875000e7 100644 --- a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeNames.cs +++ b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeNames.cs @@ -77,8 +77,8 @@ namespace VocaluxeLib.PartyModes.TicTacToe _PartyMode.GameData.ProfileIDsTeam1 = _TeamList[0]; _PartyMode.GameData.ProfileIDsTeam2 = _TeamList[1]; } - _PartyMode.GameData.NumPlayerTeam1 = _PartyMode.GameData.ProfileIDsTeam1.Count(); - _PartyMode.GameData.NumPlayerTeam2 = _PartyMode.GameData.ProfileIDsTeam2.Count(); + _PartyMode.GameData.NumPlayerTeam1 = _PartyMode.GameData.ProfileIDsTeam1.Count; + _PartyMode.GameData.NumPlayerTeam2 = _PartyMode.GameData.ProfileIDsTeam2.Count; _PartyMode.Next(); } From 990707d678645cca1257d20f816429574aded0b8 Mon Sep 17 00:00:00 2001 From: Florian Ostertag Date: Thu, 28 Dec 2023 20:58:13 +0100 Subject: [PATCH 27/39] Transifex integration (#655) * Add: Transifex file and renamed lang files * Translate Vocaluxe/Website/locales/en.json in tr 100% translated source file: 'Vocaluxe/Website/locales/en.json' on 'tr'. * Translate Vocaluxe/Website/locales/en.json in es 100% translated source file: 'Vocaluxe/Website/locales/en.json' on 'es'. * Rename all language files to match transifex. * Manual sync of translations * Another manual sync of translations * Adjust pr branch name * Translate Output/Languages/en.xml in pt 97% of minimum 90% translated source file: 'Output/Languages/en.xml' on 'pt'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate Output/Languages/en.xml in cs 96% of minimum 90% translated source file: 'Output/Languages/en.xml' on 'cs'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate Output/Languages/en.xml in it 100% translated source file: 'Output/Languages/en.xml' on 'it'. * Translate Output/Languages/en.xml in ru 100% translated source file: 'Output/Languages/en.xml' on 'ru'. * Translate Output/Languages/en.xml in sv 100% translated source file: 'Output/Languages/en.xml' on 'sv'. * Translate Output/Languages/en.xml in de 100% translated source file: 'Output/Languages/en.xml' on 'de'. * Translate Output/Languages/en.xml in fr 100% translated source file: 'Output/Languages/en.xml' on 'fr'. * Translate Vocaluxe/Website/locales/en.json in hu 100% translated source file: 'Vocaluxe/Website/locales/en.json' on 'hu'. * Translate Vocaluxe/Website/locales/en.json in ru 100% translated source file: 'Vocaluxe/Website/locales/en.json' on 'ru'. * Fix: Unescape String during xml reading * Translate Output/Languages/en.xml in ru 100% translated source file: 'Output/Languages/en.xml' on 'ru'. * Translate Output/Languages/en.xml in ru 100% translated source file: 'Output/Languages/en.xml' on 'ru'. * Translate Output/Languages/en.xml in ru 100% translated source file: 'Output/Languages/en.xml' on 'ru'. * Translate Output/Languages/en.xml in ru 100% translated source file: 'Output/Languages/en.xml' on 'ru'. * Fix: Seperate handling of unescaping * Fix: Typo * Fix: Typo --------- Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- Output/Languages/{Czech.xml => cs.xml} | 23 ++ Output/Languages/{German.xml => de.xml} | 33 ++- Output/Languages/{English.xml => en.xml} | 0 Output/Languages/{Spanish.xml => es.xml} | 0 Output/Languages/{French.xml => fr.xml} | 40 ++- Output/Languages/{Hungarian.xml => hu.xml} | 0 Output/Languages/{Italian.xml => it.xml} | 46 ++- Output/Languages/{Dutch.xml => nl.xml} | 0 Output/Languages/{Portuguese.xml => pt.xml} | 33 +++ Output/Languages/ru.xml | 269 ++++++++++++++++++ Output/Languages/{Swedish.xml => sv.xml} | 33 ++- Output/Languages/{Turkish.xml => tr.xml} | 0 .../Languages/{Asturian.xml => ast.xml} | 0 .../Challenge/Languages/{Czech.xml => cs.xml} | 1 + .../Languages/{German.xml => de.xml} | 0 .../Languages/{English.xml => en.xml} | 0 .../Languages/{Spanish.xml => es.xml} | 0 .../Languages/{French.xml => fr.xml} | 0 .../Languages/{Hungarian.xml => hu.xml} | 6 +- .../Languages/{Italian.xml => it.xml} | 1 + .../Challenge/Languages/{Dutch.xml => nl.xml} | 0 .../Languages/{Portuguese.xml => pt.xml} | 3 + Output/PartyModes/Challenge/Languages/ru.xml | 33 +++ .../Languages/{Swedish.xml => sv.xml} | 0 .../Languages/{Turkish.xml => tr.xml} | 0 .../Languages/{Asturian.xml => ast.xml} | 0 .../TicTacToe/Languages/{Czech.xml => cs.xml} | 6 +- .../Languages/{German.xml => de.xml} | 2 - .../Languages/{English.xml => en.xml} | 0 .../Languages/{Spanish.xml => es.xml} | 5 - .../Languages/{French.xml => fr.xml} | 4 +- .../Languages/{Hungarian.xml => hu.xml} | 6 +- .../Languages/{Italian.xml => it.xml} | 8 +- .../TicTacToe/Languages/{Dutch.xml => nl.xml} | 5 - .../Languages/{Portuguese.xml => pt.xml} | 6 +- Output/PartyModes/TicTacToe/Languages/ru.xml | 31 ++ .../Languages/{Swedish.xml => sv.xml} | 0 .../Languages/{Turkish.xml => tr.xml} | 5 - Tests/VocaluxeLib/XML/CXmlSerializerTest.cs | 46 +++ Vocaluxe/Base/CLanguage.cs | 2 +- Vocaluxe/Website/locales/de.json | 2 +- Vocaluxe/Website/locales/es.json | 6 +- .../locales/{Hungarian.json => hu.json} | 6 +- Vocaluxe/Website/locales/it.json | 4 +- .../Website/locales/{Polish.json => pl.json} | 0 Vocaluxe/Website/locales/ru.json | 86 ++++++ Vocaluxe/Website/locales/tr.json | 6 +- VocaluxeLib/Xml/CXmlDeserializer.cs | 28 +- transifex.yaml | 24 ++ 49 files changed, 736 insertions(+), 73 deletions(-) rename Output/Languages/{Czech.xml => cs.xml} (87%) rename Output/Languages/{German.xml => de.xml} (83%) rename Output/Languages/{English.xml => en.xml} (100%) rename Output/Languages/{Spanish.xml => es.xml} (100%) rename Output/Languages/{French.xml => fr.xml} (83%) rename Output/Languages/{Hungarian.xml => hu.xml} (100%) rename Output/Languages/{Italian.xml => it.xml} (78%) rename Output/Languages/{Dutch.xml => nl.xml} (100%) rename Output/Languages/{Portuguese.xml => pt.xml} (83%) create mode 100644 Output/Languages/ru.xml rename Output/Languages/{Swedish.xml => sv.xml} (81%) rename Output/Languages/{Turkish.xml => tr.xml} (100%) rename Output/PartyModes/Challenge/Languages/{Asturian.xml => ast.xml} (100%) rename Output/PartyModes/Challenge/Languages/{Czech.xml => cs.xml} (97%) rename Output/PartyModes/Challenge/Languages/{German.xml => de.xml} (100%) rename Output/PartyModes/Challenge/Languages/{English.xml => en.xml} (100%) rename Output/PartyModes/Challenge/Languages/{Spanish.xml => es.xml} (100%) rename Output/PartyModes/Challenge/Languages/{French.xml => fr.xml} (100%) rename Output/PartyModes/Challenge/Languages/{Hungarian.xml => hu.xml} (85%) rename Output/PartyModes/Challenge/Languages/{Italian.xml => it.xml} (97%) rename Output/PartyModes/Challenge/Languages/{Dutch.xml => nl.xml} (100%) rename Output/PartyModes/Challenge/Languages/{Portuguese.xml => pt.xml} (89%) create mode 100644 Output/PartyModes/Challenge/Languages/ru.xml rename Output/PartyModes/Challenge/Languages/{Swedish.xml => sv.xml} (100%) rename Output/PartyModes/Challenge/Languages/{Turkish.xml => tr.xml} (100%) rename Output/PartyModes/TicTacToe/Languages/{Asturian.xml => ast.xml} (100%) rename Output/PartyModes/TicTacToe/Languages/{Czech.xml => cs.xml} (86%) rename Output/PartyModes/TicTacToe/Languages/{German.xml => de.xml} (84%) rename Output/PartyModes/TicTacToe/Languages/{English.xml => en.xml} (100%) rename Output/PartyModes/TicTacToe/Languages/{Spanish.xml => es.xml} (85%) rename Output/PartyModes/TicTacToe/Languages/{French.xml => fr.xml} (85%) rename Output/PartyModes/TicTacToe/Languages/{Hungarian.xml => hu.xml} (86%) rename Output/PartyModes/TicTacToe/Languages/{Italian.xml => it.xml} (81%) rename Output/PartyModes/TicTacToe/Languages/{Dutch.xml => nl.xml} (86%) rename Output/PartyModes/TicTacToe/Languages/{Portuguese.xml => pt.xml} (85%) create mode 100644 Output/PartyModes/TicTacToe/Languages/ru.xml rename Output/PartyModes/TicTacToe/Languages/{Swedish.xml => sv.xml} (100%) rename Output/PartyModes/TicTacToe/Languages/{Turkish.xml => tr.xml} (85%) rename Vocaluxe/Website/locales/{Hungarian.json => hu.json} (97%) rename Vocaluxe/Website/locales/{Polish.json => pl.json} (100%) create mode 100644 Vocaluxe/Website/locales/ru.json create mode 100644 transifex.yaml diff --git a/Output/Languages/Czech.xml b/Output/Languages/cs.xml similarity index 87% rename from Output/Languages/Czech.xml rename to Output/Languages/cs.xml index fe288daf..6b378176 100644 --- a/Output/Languages/Czech.xml +++ b/Output/Languages/cs.xml @@ -15,6 +15,7 @@ Nahrané písně Myš Využití paměti + Herní režim Normální Duet Směska @@ -31,6 +32,10 @@ Normální uživatel Správce Uživatel klávesnice + Zdroj písně + Seznam skladeb + Skupina + Všechny písně Software OpenGL Direct3D @@ -151,6 +156,8 @@ Zastavit zpívání Pokračovat Přeskočit tuto píseň + Začít kolo znovu + Začít hru znovu Výsledky Hodnocení Body @@ -183,6 +190,7 @@ Nabídka písně Třídění písně Karty + Přehrávat automaticky náhledy písní Obtížnost hry Režim časomíry Styl pro nejlepší výsledky @@ -234,4 +242,19 @@ Hlasitost Adresa serveru Server neběží. Prověřte, prosím, config.xml! + Promiňte + Vocaluxe postihla chyba a spadl.\r\nPomožte nám opravit problém, pošlete hlášení.\r\nPro odstranění možná citlivých údajů před odesláním upravte následující zápis. + , že jste zažili chybu.\r\nPomožte nám opravit problém, pošlete hlášení.\r\nPro odstranění možná citlivých údajů před odesláním upravte následující zápis. + Nenahrávejte nic (můžete pořád zkopírovat hlášení o chybě výše) + Nahrajte a otevřete téma (veřejně viditelné + vyžaduje účet na Githubu) + Nahrajte a získejte odkaz na svoji zprávu (veřejně viditelné) + Odeslat + Nahrává se + Ukončit + Pokračovat + Odkaz na vaše hlášení: + Chyba při nahrávání zápisu. + Poslední chyba + Nedostupné + Zde popište potíže.\n\n### Kroky k zopakování situace\nŘekněte nám, jak zopakovat tento problém.\n\n### Verze Vocaluxe a soubor se záznamem\n{0}\n{1} diff --git a/Output/Languages/German.xml b/Output/Languages/de.xml similarity index 83% rename from Output/Languages/German.xml rename to Output/Languages/de.xml index 9076e3b8..79e97df3 100644 --- a/Output/Languages/German.xml +++ b/Output/Languages/de.xml @@ -15,6 +15,7 @@ Geladene Songs Maus Speicherverbrauch + Spielmodus Normal Duett Medley @@ -31,6 +32,10 @@ Normaler Benutzer Administrator Tastatur Benutzer + Song-Quelle + Playlist + Kategorie + Alle Lieder Software OpenGL Direct3D @@ -147,19 +152,21 @@ (%v Lieder) (%v Lied) %a -%t - A-Z = Zum Buchstaben springen • F3 = Suchen • STRG+R = Zufällige Auswahl • STRG+S = Starte Medley • STRG+# = Song Sortierung ändern • STRG+T = Kategorieansicht ein-/ausschalten • Leertaste = Lied-Optionen öffnen • ESC = Zurück zum Hauptmenü - A-Z = Interpreten und Titel durchsuchen, Präfixe für die Suche → a: = Interpret • t: = Titel • c: = Ersteller • e: = Edition • g: = Genre • y: = Jahr (z.B. 1999 oder 1980-1989) • l: = Sprache • al: = Album • fi: = Dateiname • fo: = Ordnername - 1-6 = Drücke die Teamnummer um einen Zufallssong Joker zu verwenden + A-Z = Zum Buchstaben springen • F3 = Suchen • STRG+R = Zufällige Auswahl • STRG+S = Medley starten • STRG+# = Song-Reihenfolge ändern • STRG+T = Kategorieansicht an-/abschalten • Leertaste = Songoptionen öffnen • ESC = Zurück zum Hauptmenü + A-Z = Interpret und Titel suchen; Präfixe für die Suche → a: = Interpret • t: = Titel • c: = Autor • e: = Edition • g: = Genre • y: = Jahr (z.B. 1999 oder 1980-1989) • l: = Sprache • al: = Album • fi: = Dateiname • fo: = Ordnername + 1-6 = Drücke die Nummer Deines Teams, um einen zufälligen Song-Joker einzusetzen Sortierung: %s Kein Medley für diesen Song! Pause Lied beenden Fortfahren Lied überspringen + Runde neustarten + Spiel neustarten Keine weiteren Songs in der Playlist! Keine Webcam verfügbar! - Seitenverhältnis: %a - %s Sekunden gesprungen + Bildverhältnis: %a + %s Sekunden übersprungen Auswertung Bewertung Punkte @@ -192,6 +199,7 @@ Song-Menu-Stil Sortierung der Lieder Kategorieren anzeigen + Autoplay für Songvorschau Schwierigkeit Zeit-Modus Highscore-Stil @@ -243,4 +251,19 @@ Lautstärke Serveradresse Server läuft derzeit nicht. Bitte überprüfe die config.xml! + Es tut uns leid + dass Vocaluxe abgestürzt ist.\r\nUm uns zu helfen, das Problem zu beheben, schicke uns bitte einen Absturzbericht.\r\nBitte bearbeite das folgende Protokoll, so dass keine eventuell persönlichen Daten enthalten sind. + dass Du einen Fehler festgestellt hast.\r\nUm uns zu helfen, das Problem zu beheben, schicke uns bitte einen Absturzbericht.\r\nBitte bearbeite das folgende Protokoll, so dass keine eventuell persönlichen Daten enthalten sind. + Nichts hochladen (Du kannst immer noch die Fehlermeldung oben kopieren) + Hochladen und ein Ticket eröffnen (öffentlich sichtbar und benötigt einen github-Account) + Hochladen und einen Link zum Bericht erhalten (öffentlich sichtbar) + Senden + Lade hoch + Verlassen + Fortfahren + Der Link zu Deinem Bericht: + Fehler beim Hochladen des Protokolls. + Letzter Fehler + Nicht verfügbar + Beschreibe Dein Problem hier.\n\n###Schritte zum Reproduzieren des Problems\nTeil uns mit wie man das Problem reproduzieren kann.\n\n###Vocaluxe-Version und -Protokoll\n{0}\n{1} diff --git a/Output/Languages/English.xml b/Output/Languages/en.xml similarity index 100% rename from Output/Languages/English.xml rename to Output/Languages/en.xml diff --git a/Output/Languages/Spanish.xml b/Output/Languages/es.xml similarity index 100% rename from Output/Languages/Spanish.xml rename to Output/Languages/es.xml diff --git a/Output/Languages/French.xml b/Output/Languages/fr.xml similarity index 83% rename from Output/Languages/French.xml rename to Output/Languages/fr.xml index 53dd928d..5968f548 100644 --- a/Output/Languages/French.xml +++ b/Output/Languages/fr.xml @@ -35,7 +35,7 @@ Source des chansons Playlist Catégorie - Toutes les chansons + Toutes les chansons Logiciel OpenGL Direct3D @@ -145,19 +145,28 @@ Options de la chanson Rechercher: Pas de Langue - Pas d'Année + Pas d\'Année Pas de Genre - Pas d'Edition + Pas d\'Edition Toutes les chansons (%v Chansons) (%v Chanson) %a - %t + A-Z = Sauter à la lettre • F3 = Chercher • CTRL+R = Sélectionner au hasard • CTRL+S = Lancer medley • CTRL+# = Changer le tri des chansons • CTRL+T = Activer/Désactiver la vue par catégorie • Espace = Ouvrir les options de chanson • Échap = Retouner au menu précédent + A-Z = Chercher artiste et titre, préfixes pour la recherche → a: = artiste • t: = titre • c: = créateurr • e: = édition • g: = genre • y: = année (ex: 1999 ou 1980-1989) • l: = langage • al: = album • fi: = nom du fichier • fo: = nom du dossier + 1-6 = Pressez votre numéro d'équipe afin d'utiliser une chanson joker au hasard + Classement en cours : %s + Aucun Medley pour cette chanson ! Pause Arrêter de chanter Continuer Passer cette chanson Redémarer le tour Redémarer le jeu + Plus aucune chanson dans la playlist ! + Pas de webcam disponible ! + Ratio d'aspect : %a + %s secondes passées Scores Note Points @@ -242,4 +251,29 @@ Volume Adresse du serveur Le serveur ne fonctionne pas. Merci de vérifier config.xml ! + Nous sommes désolés + Vocaluxe a rencontré une erreur ou un bug. +Pour nous aider à résoudre le problème, envoyez-nous un rapport. +Avant de soumettre le bug, modifiez le journal pour supprimer des informations sensibles. + Vous avez rencontré une erreur ou un bug. +Pour nous aider à résoudre le problème, envoyez-nous un rapport. +Avant de soumettre le bug, modifiez le journal suivant pour supprimer des informations sensibles. + N'envoi rien (vous pouvez toujours copier le message d'erreur ci-dessus) + Envoyer et ouvrir un problème (visible publiquement + nécessite un compte github) + Envoyer et obtenir le lien de votre rapport (visible publiquement) + Soumettre + Envoyer + Quitter + Continuer + Lien de votre rapport: + Erreur lors de l'envoi du journal. + Dernière erreur + Indisponible + Décrivez votre problème ici. + +### Procédure de reproduction +Dites-nous comment reproduire ce problème. +### Version Vocaluxe et fichier journal +{0} +{1} diff --git a/Output/Languages/Hungarian.xml b/Output/Languages/hu.xml similarity index 100% rename from Output/Languages/Hungarian.xml rename to Output/Languages/hu.xml diff --git a/Output/Languages/Italian.xml b/Output/Languages/it.xml similarity index 78% rename from Output/Languages/Italian.xml rename to Output/Languages/it.xml index e2e34af9..a1f0c4a9 100644 --- a/Output/Languages/Italian.xml +++ b/Output/Languages/it.xml @@ -15,6 +15,7 @@ Canzoni caricate Mouse Uso della Memoria + Modalità di gioco Normale Duetto Medley @@ -31,6 +32,10 @@ Utente normale Amministratore Tasti Utente + Sorgente della Canzone + Playlist + Categoria + Tutte le canzoni Software OpenGL Direct3D @@ -51,7 +56,7 @@ Scacchiera Libro Su richiesta - All'avvio + All\\'avvio Dinamico Nessuno Casuale @@ -84,6 +89,7 @@ Niente Riempi Salta + Slide Zoom Sotto Sopra @@ -119,10 +125,10 @@ 4 giocatori 5 giocatori 6 giocatori - Attenzione: Non c'è nessun microfono assegnato al giocatore %v! - Attenzione: Non c'è nessun microfono assegnato ai giocatori %v! - Attenzione: Non c'è nessun profilo assegnato al giocatore %v! - Attenzione: Non c'è nessun profilo assegnato ai giocatori %v! + Attenzione: Non c\'è nessun microfono assegnato al giocatore %v! + Attenzione: Non c\'è nessun microfono assegnato ai giocatori %v! + Attenzione: Non c\'è nessun profilo assegnato al giocatore %v! + Attenzione: Non c\'è nessun profilo assegnato ai giocatori %v! Selezione canzone Canta Aggiungi alla playlist @@ -146,10 +152,21 @@ (%v Canzoni) (%v Canzone) %a - %t + A-Z = Salta alla lettera • F3 = Cerca • CTRL+R = Selezione casuale • CTRL+S = Inizia medley • CTRL+# = Cambia l\'ordinamento delle canzoni • CTRL+T = Attiva/Disattiva visualizzazione categoria • Space = Apri impostazioni canzone • ESC = Ritorna al menu principale + A-Z = Cerca artista e titolo, prefissi per la ricerca → a: = artista • t: = titolo • c: = creatore • e: = edizione • g: = genere • y: = anno (es. 1999 o 1980-1989) • l: = lingua • al: = album • fi: = nome file • fo: = nome cartella + 1-6: Premi il numero del tuo team per usare una canzone giullare casuale + Ordinamento: %s + Nessun Medley per questa canzone! Pausa Smetti di cantare Continua Salta questa canzone + Rinizia turno + Rinizia il gioco + Nessun\'altra canzone nella playlist! + Nessuna webcam disponibile! + Proporzioni: %a + Saltati %s secondi Punteggi Voto Punti @@ -182,8 +199,10 @@ Menu canzone Ordine canzone Schede + Riproduci automaticamente le anteprime delle canzoni Difficoltà gioco Modalità a tempo + Stile del punteggio più alto Opzioni registrazione Dispositivo Input @@ -223,7 +242,7 @@ Webcam Risoluzione-Webcam Sistemazione schermo - Premi CTR + ALT (+ SHIFT) + Freccia|"+\ per sistemare lo schermo + Premi CTR + ALT (+ SHIFT) + Freccia|+ per sistemare lo schermo CTR + ALT + 0 per ripristinare Sopra a sinistra Sopra a destra @@ -232,4 +251,19 @@ Volume Indirizzo server Il server non sta funzionando. Per favore controlla il file config.xml! + Siamo spiacenti + che Vocaluxe si è imbattuto in un errore e si è arrestato.\r\nPer aiutarci a risolvere il problema, vi preghiamo di inviarci un rapporto.\r\nModifica il seguente log prima di inviare per rimuovere le informazioni eventualmente sensibili. + che Vocaluxe si è imbattuto in un errore.\r\nPer aiutarci a risolvere il problema, vi preghiamo di inviarci un rapporto.\r\nModifica il seguente log prima di inviare per rimuovere le informazioni eventualmente sensibili. + Non caricare niente (puoi comunque copiare il messaggio di errore soprastante) + Carica e apri una segnalazione (visibile pubblicamente + richiede un account github) + Carica e ottieni un link per il tuo rapporto (visibile pubblicamente) + Invia + Caricamento + Esci + Continua + Il link al tuo rapporto: + Errore nel caricamento del registro + Ultimo errore + Non disponibile + Descrivi qui il tuo problema.\n\n### Passaggi per riprodurre \nDiteci come riprodurre questo problema.\n\n### Versione di Vocaluxe e file di registro\n{0}\n{1} diff --git a/Output/Languages/Dutch.xml b/Output/Languages/nl.xml similarity index 100% rename from Output/Languages/Dutch.xml rename to Output/Languages/nl.xml diff --git a/Output/Languages/Portuguese.xml b/Output/Languages/pt.xml similarity index 83% rename from Output/Languages/Portuguese.xml rename to Output/Languages/pt.xml index b4b22541..940595b2 100644 --- a/Output/Languages/Portuguese.xml +++ b/Output/Languages/pt.xml @@ -15,6 +15,7 @@ Músicas carregadas Rato Utilização da Memória + Modo de Jogo Normal Dueto Miscelânea @@ -31,6 +32,10 @@ Utilizador Normal Administrador Utilizador de Teclado + Origem da Música + Lista de Reprodução + Categoria + Todas as Músicas Software OpenGL Direct3D @@ -73,6 +78,8 @@ Total Normal Expandida + Mostrar Todas + Mostrar as Melhores Apenas musica e musica de fundo Não utilizar música própria Apenas música própria @@ -80,6 +87,10 @@ Todas Apenas nomes e avatares Nada + Preencher + Saltar + Deslizar + Aumentar Fundo Topo Topo e Fundo @@ -145,6 +156,10 @@ Terminar de cantar Continuar Saltar esta música + Recomeçar a Ronda + Recomeçar o Jogo + Sem mais Músicas na sua lista de reprodução! + Nenhuma câmara web disponível! Pontuações Classificação Pontos @@ -177,8 +192,10 @@ Menu das Músicas Ordenação das Musicas Separadores + Autoplay das Amostras de Músicas Dificildade do Jogo Modo Temporizado + Estilo da Melhor Pontuação Opções de Gravação Dispositivo Entrada @@ -197,6 +214,7 @@ Origem da Música de Fundo Prévisualizar Volume da Música Volume da Música no Jogo + Efeito Karaoke Opções do Tema Tema Skin @@ -226,4 +244,19 @@ Volume Endereço do Servidor Servidor não está em execução. Por favor verifique o config.xml! + Pedimos Desculpa + mas o Vocaluxe encontrou um erro e crashou.\r\nPara nos ajudares a resolver a questão envia-nos um relatório.\r\nSugerimos que edites o log seguinte antes de enviares para removeres alguma informação sigilosa. + que tenhas sofrido um problema.\r\nPara nos ajudares a resolver a questão envia-nos um relatório.\r\nSugerimos que edites o log seguinte antes de enviares para removeres alguma informação sigilosa. + Não fazer upload de nada (ainda podes copiar o código de erro que está por cima) + Fazer upload e abrir um problema (visível publicamente e requer uma conta github) + Fazer upload e obter um link para o teu relatório (visível publicamente) + Submeter + Uploading + Sair + Continuar + O Link para o teu relatório: + Erro a fazer upload do log. + Último erro + Indisponível + Descreve o teu problema aqui.\n\n### Passos para o reproduzir novamente \nDiz-nos como reproduzir este problema.\n\n### Versão do Vocaluxe e ficheiro Log\n{0}\n{1} diff --git a/Output/Languages/ru.xml b/Output/Languages/ru.xml new file mode 100644 index 00000000..8dced1ed --- /dev/null +++ b/Output/Languages/ru.xml @@ -0,0 +1,269 @@ + + + Русский + Вокалюкс + и + Выход + Сохранить + Назад + Старт + Аудиопотоки + Видеопотоки + Текстуры + Тонус + Макс. громкость + Загруженные песни + Мышь + Память + Игровой режим + Нормальный + Дуэт + Попурри + Краткая версия + Вокальный Герой + Суперзвезда + Ведущий певец + Восходящая звезда + Многообещающий + Подражатель + Любитель + Нету слуха + Гость + Обычный пользователь + Администратор + Пользователь клавиатуры + Источник песни + Плейлист + Категория + Все песни + Программное обеспечение + OpenGL + Direct3D + Низший + Низкий + Средний + Высокий + Наивысший + Выкл. + Вкл. + Только FPS + Уровень 1 + Уровень 2 + Уровень 3 + Макс. + Список + Дрейдл + Плитки + Книга + По требованию + При запуске + Динамически + Нет + Случайно + Папка + Исполнитель + Исполнитель по букве + Название по букве + Версия + Жанр + Год + Десятилетие + Язык + Дата добавления + Лёгкая + Нормальная + Сложная + Текущее + Оставшееся + Общее + Обычное + Расширенное + Список всех + Список лучших + Собственная музыка и фоновая музыка + Нет собственной музыки + Только собственная музыка + Только выбранная песня + Все + Только имена и аватары + Ничего + Заполнение + Прыжок + Слайд + Зум + Внизу + Сверху + Сверху и снизу + Динамический + Загрузка + Весь + песни + загружен + Общее Меню + Пение + Вечеринка + Опции + Профили + Профили не найдены! + Выбор режима Вечеринки + Режим Вечеринки + Описание + Автор + Версия + Не получилось загрузить этот режим вечеринки. + Нет настроенных микрофонов! + %d микрофон(ов) необходимо для этого режима вечеринки! + Целевая аудитория + Нет команд + Количество команд + Количество игроков + Выбор игроков + Игрок + 1 игрок + 2 игрока + 3 игрока + 4 игрока + 5 игроков + 6 игроков + Внимание: Не обнаружен микрофон игрока %v! + Внимание: Не обнаружены микрофоны игроков %v! + Внимание: Не обнаружен профиль игрока %v! + Внимание: Не обнаружены профили игроков %v! + Выбор песни + Петь + Добавить в плейлист + Закрыть + Выбрать случайную песню + Выбрать случяйную категорию + Петь все песни + Петь все видимые песни + Открыть плейлист + Выбрать + Спеть случайное попурри + Петь попурри + Новый плейлист + Опции пения + Поиск: + Нет языка + Нет Года + Нет Жанра + Нет Версии + Все песни + (%v песни) + (%v песня) + %a - %t + A-Z = Начать ввод • F3 = Поиск • CTRL+R = Случайный выбор • CTRL+S = Начать попурри • CTRL+# = Выбор сортировки песен • CTRL+T = Включить/Выключить просмотр категории • Space = Открыть параметры песни • ESC = Вернуться в главное меню + A-Z = Поиск исполнителя и названия, префиксы для поиска → a: = артист • t: = название • c: = автор • e: = версия • g: = жанр • y: = год (напр. 1999 или 1980-1989) • l: = язык • al: = альбом • fi: = имя файла • fo: = имя папки + 1-6 = Нажмите номер вашей команды, чтобы использовать случайную песню джокер + Сортировать: %s + Нет Попурри для этой песни! + Пауза + Остановить пение + Продолжить + Пропустить эту песню + Перезапустить раунд + Перезапустить игру + В плейлисте больше нет песен! + Веб-камера недоступна! + Соотношение сторон: %a + Пропущено %s секунд + Счёт + Рейтинг + Очки + Сложность + Общий счёт + Рекорд + Профили + Имя игрока + Сложность игры + Аватар + Роль + Активный + Новый + Удалить + Сделать снимок + Сохранить снимок + Удалить снимок + Веб-камера + Опции + Игра + Звук + Запись + Видео + Текст песни + Тема + Адрес сервера + Опции игры + Язык + Уровень отладки + Стиль меню песни + Сортировка песен + Вкладки + Автозапуск предпросмотра песен + Сложность игры + Режим таймера + Стиль Рекордов + Параметры Записи + Устройство + Ввод + Игрок 1 + Игрок 2 + Игрок 3 + Игрок 4 + Игрок 5 + Игрок 6 + Задержка микрофона + Внимание: один из игроков назначен на два микрофона. + Тест задержки + Настройки Звука + Фоновая музыка + Громкость фоновой музыки + Источник фоновой музыки + Предпрослушивание громкости музыки + Громкость игровой музыки + Эффект Караоке + Настройки темы + Тема + Скин + Тема обложки + Показать строки заметки + Показать тон-помощник + Режим временной шкалы + Угасание информации об игроке + Обложка-поведение при загрузке + Варианты песен + Стиль анимации + Позиция текста + Опции видео + Видео фоны + Предпросмотр видео + Видео во время пения + Отображение текущей фоновой музыки видео + Веб-камеры + Разрешение веб-камеры + Настроить экран + Нажмите CTRL + ALT (+ SHIFT) + Стрелки для настройки экрана + CTRL + ALT + 0 сброс + Сверху слева + Сверху справа + Внизу слева + Внизу справа + Громкость + Адрес сервера + Сервер не работает. Пожалуйста, проверьте config.xml! + Нам очень жаль + В Vocaluxe произошла ошибка и произошел сбой.\r\nЧтобы помочь нам решить проблему, отправьте нам отчет.\r\nИзмените следующий журнал перед отправкой, чтобы удалить потенциально конфиденциальную информацию. + что вы столкнулись с ошибкой.\r\nЧтобы помочь нам решить проблему, отправьте нам отчет..\r\nИзменить следующий журнал перед отправкой, чтобы удалить потенциально конфиденциальную информацию. + Не загружать ничего (вы можете скопировать сообщение об ошибке выше) + Загрузить и откройть проблему (общедоступно + требуется учетная запись github) + Загрузить и получить ссылку на свой отчет (общедоступная) + Отправить + Загрузка + Выход + Продолжить + Ссылка на ваш отчет: + Ошибка при загрузке журнала. + Последняя ошибка + Не доступно + Опишите свою проблему здесь.\n\n### шаги для воспроизведения\nРасскажите, как воспроизвести эту проблему.\n\n### версию Vocaluxe и лог файл\n{0}\n{1} + diff --git a/Output/Languages/Swedish.xml b/Output/Languages/sv.xml similarity index 81% rename from Output/Languages/Swedish.xml rename to Output/Languages/sv.xml index 81bfe9f9..746be5f5 100644 --- a/Output/Languages/Swedish.xml +++ b/Output/Languages/sv.xml @@ -15,6 +15,7 @@ Laddade låtar Mus Minnesanvändning + Spelläge Normal Duett Medley @@ -31,6 +32,10 @@ Normal användare Administratör Tangentbordsanvändare + Låtkälla + Spellista + Kategori + Alla låtar Mjukvara OpenGL Direct3D @@ -147,10 +152,21 @@ (%v låtar) (%v låt) %a - %t + A-Z = Hoppa till bokstaven • F3 = Sök • CTRL+R = Slumpa • CTRL+S = Starta medley • CTRL+# = Ändra sångsortering • CTRL+T = Aktivera/Inaktivera kategorivy • Mellanslag = Öppna sångalternativ • ESC = Tillbaka till huvudmenyn + A-Z = Sök artist och titel, prefix för sökningen → a: = artist • t: = titel • c: = skapare • e: = utgåva • g: = genre • y: = år (t ex. 1999 eller 1980-1989) • l: = språk • al: = album • fi: = filnamn • fo: = mappnamn + 1-6 = Tryck ditt lagnummer för att använda en slumpad sångjoker + Sortering: %s + Inget medley för denna sång! Paus Avsluta låt Fortsätt Hoppa över låt + Starta om runda + Starta om spel + Inga fler sånger i spellistan! + Ingen webkamera tillgänglig! + Bildformat: %a + Hoppade över %s sekunder Resultat Rankning Poäng @@ -183,7 +199,7 @@ Låtmeny Låtsortering Flikar - Förhandsvisa låtar automatiskt + Förhandsgranska låt automatiskt Spelets svårighetsgrad Timerläge Topplistsvy @@ -235,4 +251,19 @@ Volym Serveradress Servern körs inte. Var god kontrollera config.xml! + Vi ber om ursäkt + så Vocaluxe sätte på ett fel och har kraschat..\r\nFör att hjälpa oss att åtgärda problemet, ber vi er att skicka oss en rapport.\r\nÄndra följande logg innan du skickar in den och ta bort eventuellt känslig information. + att du har upplevt ett fel.\r\nFör att hjälp oss att åtgärda problemet, så ber vi er skicka in er rapport.\r\nÄndra loggen innan den skickar in för att ta bort eventuellt känslig information. + Ladda inte upp något. (du kan fortfarande kopiera felmeddelandet ovanför) + Ladda upp och felanmäla ett problem (Som kommer synas för alla och kräver ett github konto) + Ladda upp så får ni länk till er rapport (som kommer synas för alla) + Skicka in + Laddar upp + Lämna + Fortsätt + Länken till er rapport. + Problem uppstod när loggen skulle skickas. + Senaste fel + Inte tillgänglig + Beskriv ert problem här.\n\n### Steg att reproducera \ nBerätta för oss hur du reproducerat detta problem.\n\n### Vocaluxe-version och loggfil\n{0}\n{1} diff --git a/Output/Languages/Turkish.xml b/Output/Languages/tr.xml similarity index 100% rename from Output/Languages/Turkish.xml rename to Output/Languages/tr.xml diff --git a/Output/PartyModes/Challenge/Languages/Asturian.xml b/Output/PartyModes/Challenge/Languages/ast.xml similarity index 100% rename from Output/PartyModes/Challenge/Languages/Asturian.xml rename to Output/PartyModes/Challenge/Languages/ast.xml diff --git a/Output/PartyModes/Challenge/Languages/Czech.xml b/Output/PartyModes/Challenge/Languages/cs.xml similarity index 97% rename from Output/PartyModes/Challenge/Languages/Czech.xml rename to Output/PartyModes/Challenge/Languages/cs.xml index c0fce8eb..6fb11001 100644 --- a/Output/PartyModes/Challenge/Languages/Czech.xml +++ b/Output/PartyModes/Challenge/Languages/cs.xml @@ -11,6 +11,7 @@ Ano Ne Další kolo + Písně Soutěžní režim: Nastavení Počet hráčů Počet mikrofonů diff --git a/Output/PartyModes/Challenge/Languages/German.xml b/Output/PartyModes/Challenge/Languages/de.xml similarity index 100% rename from Output/PartyModes/Challenge/Languages/German.xml rename to Output/PartyModes/Challenge/Languages/de.xml diff --git a/Output/PartyModes/Challenge/Languages/English.xml b/Output/PartyModes/Challenge/Languages/en.xml similarity index 100% rename from Output/PartyModes/Challenge/Languages/English.xml rename to Output/PartyModes/Challenge/Languages/en.xml diff --git a/Output/PartyModes/Challenge/Languages/Spanish.xml b/Output/PartyModes/Challenge/Languages/es.xml similarity index 100% rename from Output/PartyModes/Challenge/Languages/Spanish.xml rename to Output/PartyModes/Challenge/Languages/es.xml diff --git a/Output/PartyModes/Challenge/Languages/French.xml b/Output/PartyModes/Challenge/Languages/fr.xml similarity index 100% rename from Output/PartyModes/Challenge/Languages/French.xml rename to Output/PartyModes/Challenge/Languages/fr.xml diff --git a/Output/PartyModes/Challenge/Languages/Hungarian.xml b/Output/PartyModes/Challenge/Languages/hu.xml similarity index 85% rename from Output/PartyModes/Challenge/Languages/Hungarian.xml rename to Output/PartyModes/Challenge/Languages/hu.xml index 30b313a2..fd86b1aa 100644 --- a/Output/PartyModes/Challenge/Languages/Hungarian.xml +++ b/Output/PartyModes/Challenge/Languages/hu.xml @@ -1,8 +1,8 @@ Magyar - Bajnokság Mód - Bajnokság Módban egymás ellen + Bajnokság + Bajnokság mód egymás ellen Azoknak akik szeretnék megmérettetni magukat egymás ellen Következő Vissza @@ -15,6 +15,8 @@ Játékosok Száma Mikrofonok Száma Körök Száma + Jokerek száma + Jokerek újratöltése minden körben Bajnokság Mód: Válassz Játékost Véletlenszerű választás Bajnokság Mód: Áttekintés diff --git a/Output/PartyModes/Challenge/Languages/Italian.xml b/Output/PartyModes/Challenge/Languages/it.xml similarity index 97% rename from Output/PartyModes/Challenge/Languages/Italian.xml rename to Output/PartyModes/Challenge/Languages/it.xml index 05b77510..cdcfd734 100644 --- a/Output/PartyModes/Challenge/Languages/Italian.xml +++ b/Output/PartyModes/Challenge/Languages/it.xml @@ -11,6 +11,7 @@ Si No Prossimo Turno + Canzoni Modalità Sfida: Configurazione Numero di giocatori Numero di microfoni diff --git a/Output/PartyModes/Challenge/Languages/Dutch.xml b/Output/PartyModes/Challenge/Languages/nl.xml similarity index 100% rename from Output/PartyModes/Challenge/Languages/Dutch.xml rename to Output/PartyModes/Challenge/Languages/nl.xml diff --git a/Output/PartyModes/Challenge/Languages/Portuguese.xml b/Output/PartyModes/Challenge/Languages/pt.xml similarity index 89% rename from Output/PartyModes/Challenge/Languages/Portuguese.xml rename to Output/PartyModes/Challenge/Languages/pt.xml index 0a25c2fc..5cab563b 100644 --- a/Output/PartyModes/Challenge/Languages/Portuguese.xml +++ b/Output/PartyModes/Challenge/Languages/pt.xml @@ -11,10 +11,13 @@ Sim Não Ronda Seguinte + Músicas Modo Desafio: Configuração Número de Jogadores Número de microfones Número de rondas + Número de "Jokers" + Recarregar os "Jokers" todas as rondas Modo Desafio: Escolher Jogador Escolha Aleatória Modo Desafio: Resumo diff --git a/Output/PartyModes/Challenge/Languages/ru.xml b/Output/PartyModes/Challenge/Languages/ru.xml new file mode 100644 index 00000000..b4949f4d --- /dev/null +++ b/Output/PartyModes/Challenge/Languages/ru.xml @@ -0,0 +1,33 @@ + + + Английский + Режим соревнования + Сыграть несколько раундов соревнований. + Для всех, кому интересны дуэльные бои. + Далее + Назад + Начать + Выход + Да + Нет + Следующий раунд + Песни + Режим испытания: Конфигурация + Количество игроков + Количество микрофонов + Количество раундов + Количество джокеров + Пополняйте джокеры каждый раунд + Режим соревнования: Выбор игрока + Случайный выбор + Режим соревнования: Обзор + Позиция + Имя + Раундов + Побед + Очки пения + Счёт + Вы действительно хотите выйти? + Игрок следующего раунда: + Спеты все раунды! И победителем становится... + diff --git a/Output/PartyModes/Challenge/Languages/Swedish.xml b/Output/PartyModes/Challenge/Languages/sv.xml similarity index 100% rename from Output/PartyModes/Challenge/Languages/Swedish.xml rename to Output/PartyModes/Challenge/Languages/sv.xml diff --git a/Output/PartyModes/Challenge/Languages/Turkish.xml b/Output/PartyModes/Challenge/Languages/tr.xml similarity index 100% rename from Output/PartyModes/Challenge/Languages/Turkish.xml rename to Output/PartyModes/Challenge/Languages/tr.xml diff --git a/Output/PartyModes/TicTacToe/Languages/Asturian.xml b/Output/PartyModes/TicTacToe/Languages/ast.xml similarity index 100% rename from Output/PartyModes/TicTacToe/Languages/Asturian.xml rename to Output/PartyModes/TicTacToe/Languages/ast.xml diff --git a/Output/PartyModes/TicTacToe/Languages/Czech.xml b/Output/PartyModes/TicTacToe/Languages/cs.xml similarity index 86% rename from Output/PartyModes/TicTacToe/Languages/Czech.xml rename to Output/PartyModes/TicTacToe/Languages/cs.xml index a328a32f..a7294248 100644 --- a/Output/PartyModes/TicTacToe/Languages/Czech.xml +++ b/Output/PartyModes/TicTacToe/Languages/cs.xml @@ -13,15 +13,11 @@ Spustit Písně Tým - Seznam skladeb - Skupina - Všechny písně Tic-Tac-Toe: Nastavení Počet hráčů v týmu 1 Počet hráčů v týmu 2 Počet polí - Zdroj písně - Herní režim + Doplnit žolíky každé kolo Tic-Tac-Toe: Výběr hráče Tým 1 Tým 2 diff --git a/Output/PartyModes/TicTacToe/Languages/German.xml b/Output/PartyModes/TicTacToe/Languages/de.xml similarity index 84% rename from Output/PartyModes/TicTacToe/Languages/German.xml rename to Output/PartyModes/TicTacToe/Languages/de.xml index 1413dac7..8839754c 100644 --- a/Output/PartyModes/TicTacToe/Languages/German.xml +++ b/Output/PartyModes/TicTacToe/Languages/de.xml @@ -19,11 +19,9 @@ Anzahl der Felder Joker nach jeder Runde auffüllen Tic-Tac-Toe: Spielerwahl - Ausgewählte Spieler für dieses Team: Team 1 Team 2 Zufällig auswählen - Füge mindestens einen Spieler zu beiden Teams hinzu! / Zum Hinzufügen den Spieleravatar auf die Liste der ausgewählten Spieler ziehen! / Zum Entfernen den Spieleravatar mit rechter Maustaste anklicken! Tic-Tac-Toe Wählt ein Feld aus. Nächster Spieler diff --git a/Output/PartyModes/TicTacToe/Languages/English.xml b/Output/PartyModes/TicTacToe/Languages/en.xml similarity index 100% rename from Output/PartyModes/TicTacToe/Languages/English.xml rename to Output/PartyModes/TicTacToe/Languages/en.xml diff --git a/Output/PartyModes/TicTacToe/Languages/Spanish.xml b/Output/PartyModes/TicTacToe/Languages/es.xml similarity index 85% rename from Output/PartyModes/TicTacToe/Languages/Spanish.xml rename to Output/PartyModes/TicTacToe/Languages/es.xml index 48133d84..1a08cbf8 100644 --- a/Output/PartyModes/TicTacToe/Languages/Spanish.xml +++ b/Output/PartyModes/TicTacToe/Languages/es.xml @@ -13,15 +13,10 @@ Iniciar Canciones Equipo - Lista de reproducción - Categoría - Todas las canciones Ta-Te-Ti: Configuración Nro. de cantantes equipo 1 Nro. de cantantes equipo 2 Nro. de campos - Origen de la canción - Modo de juego Ta-Te-Ti: Selección de cantante Equipo 1 Equiipo 2 diff --git a/Output/PartyModes/TicTacToe/Languages/French.xml b/Output/PartyModes/TicTacToe/Languages/fr.xml similarity index 85% rename from Output/PartyModes/TicTacToe/Languages/French.xml rename to Output/PartyModes/TicTacToe/Languages/fr.xml index 73413bae..40e9dd3c 100644 --- a/Output/PartyModes/TicTacToe/Languages/French.xml +++ b/Output/PartyModes/TicTacToe/Languages/fr.xml @@ -18,12 +18,12 @@ Nombre de joueurs dans l'Equipe 2 Nombre de champs Recharger les jokers a chaque tour - Nombre de jokers - Changement de joueur Tic-Tac-Toe: Choix des joueurs + Joueurs sélectionnés pour cette équipe : Equipe 1 Equipe 2 Sélectionner au hasard + Ajoutez au moins un joueur aux deux équipes ! / Tirez l'avatar d'un joueur vers la liste des joueurs sélectionnés ! / Faites un clic droit sur l'avatar d'un joueur pour le retirer ! Tic-Tac-Toe Choisissez une case. Joueur suivant diff --git a/Output/PartyModes/TicTacToe/Languages/Hungarian.xml b/Output/PartyModes/TicTacToe/Languages/hu.xml similarity index 86% rename from Output/PartyModes/TicTacToe/Languages/Hungarian.xml rename to Output/PartyModes/TicTacToe/Languages/hu.xml index 0f1a8dc8..7802ab6f 100644 --- a/Output/PartyModes/TicTacToe/Languages/Hungarian.xml +++ b/Output/PartyModes/TicTacToe/Languages/hu.xml @@ -13,18 +13,14 @@ Kezdés Dalok Csapat - Dal Lista - Kategória - Összes Dal Tic-Tac-Toe: Beállítások 1. Csapat játékosainak száma 2. Csapat játékosainak száma Mezők száma - Dal-forrás - Játék Mód Tic-Tac-Toe: Válassz Játékost 1. Csapat 2. Csapat + Véletlenszerű választás Tic-Tac-Toe Válassz egy mezőt. Következő Játékos diff --git a/Output/PartyModes/TicTacToe/Languages/Italian.xml b/Output/PartyModes/TicTacToe/Languages/it.xml similarity index 81% rename from Output/PartyModes/TicTacToe/Languages/Italian.xml rename to Output/PartyModes/TicTacToe/Languages/it.xml index f20d59dd..f63f982d 100644 --- a/Output/PartyModes/TicTacToe/Languages/Italian.xml +++ b/Output/PartyModes/TicTacToe/Languages/it.xml @@ -13,15 +13,11 @@ Inizia Canzoni Squadra - Playlist - Categoria - Tutte le canzoni Tris: Configurazione Numero di giocatori della squadra 1 Numero di giocatori della squadra 2 Numero di caselle - Sorgente della Canzone - Modalità di Gioco + Ricarica i giullari ad ogni turno Tris: Scegli il Giocatore Squadra 1 Squadra 2 @@ -31,5 +27,5 @@ Prossimo giocatore Vuoi veramente uscire dal Tris? E il vincitore è... - Non c'è nessun vincitore in questo turno... + Non c\'è nessun vincitore in questo turno... diff --git a/Output/PartyModes/TicTacToe/Languages/Dutch.xml b/Output/PartyModes/TicTacToe/Languages/nl.xml similarity index 86% rename from Output/PartyModes/TicTacToe/Languages/Dutch.xml rename to Output/PartyModes/TicTacToe/Languages/nl.xml index cdac1e9a..1d3f7182 100644 --- a/Output/PartyModes/TicTacToe/Languages/Dutch.xml +++ b/Output/PartyModes/TicTacToe/Languages/nl.xml @@ -13,15 +13,10 @@ Start Liedjes Team - Afspeellijst - Categorie - Alle liedjes Drie-op-een-rij: configuratie Aantal spelers in team 1 Aantal spelers in team 2 Aantal vakjes - Liedjesbron - Spelmodus Drie-op-een-rij: Kies speler Team 1 Team 2 diff --git a/Output/PartyModes/TicTacToe/Languages/Portuguese.xml b/Output/PartyModes/TicTacToe/Languages/pt.xml similarity index 85% rename from Output/PartyModes/TicTacToe/Languages/Portuguese.xml rename to Output/PartyModes/TicTacToe/Languages/pt.xml index 42da10a3..c796c00f 100644 --- a/Output/PartyModes/TicTacToe/Languages/Portuguese.xml +++ b/Output/PartyModes/TicTacToe/Languages/pt.xml @@ -13,15 +13,11 @@ Iniciar Músicas Equipa - Lista de Reprodução - Categoria - Todas as Músicas Jogo do Galo: Configuração Número de Jogadores na Equipa 1 Número de Jogadores na Equipa 2 Número de Campos - Origem da Música - Modo do Jogo + Recarregar os \"Jokers\" todas as rondas Jogo do Galo: Esolher Jogador Equipa 1 Equipa 2 diff --git a/Output/PartyModes/TicTacToe/Languages/ru.xml b/Output/PartyModes/TicTacToe/Languages/ru.xml new file mode 100644 index 00000000..8ba288bf --- /dev/null +++ b/Output/PartyModes/TicTacToe/Languages/ru.xml @@ -0,0 +1,31 @@ + + + Английский + Крестики-нолики + Играйте в Крестики-нолики особым образом + Веселые раунды со стратегией, удачей и навыками + Далее + Назад + Начать + Выход + Да + Нет + Старт + Песни + Команда + Крестики-нолики: Конфигурация + Номер игрока из команды 1 + Номер игрока из команды 2 + Количество полей + Пополняйте джокеры каждый раунд + Крестики-нолики: Выберите игрока + Команда 1 + Команда 2 + Случайный выбор + Крестики-нолики + Выберите поле. + Следующий игрок + Действительно выйти из Крестики-нолики? + И победителем становится... + В этом раунде нет победителя... + diff --git a/Output/PartyModes/TicTacToe/Languages/Swedish.xml b/Output/PartyModes/TicTacToe/Languages/sv.xml similarity index 100% rename from Output/PartyModes/TicTacToe/Languages/Swedish.xml rename to Output/PartyModes/TicTacToe/Languages/sv.xml diff --git a/Output/PartyModes/TicTacToe/Languages/Turkish.xml b/Output/PartyModes/TicTacToe/Languages/tr.xml similarity index 85% rename from Output/PartyModes/TicTacToe/Languages/Turkish.xml rename to Output/PartyModes/TicTacToe/Languages/tr.xml index 9af5e420..eb5e284d 100644 --- a/Output/PartyModes/TicTacToe/Languages/Turkish.xml +++ b/Output/PartyModes/TicTacToe/Languages/tr.xml @@ -13,15 +13,10 @@ Başla Şarkılar Takım - Çalma Listesi - Kategori - Tüm Şarkılar XOX: Yapılandırma 1. takımdaki oyuncu sayısı 2. takımdaki oyuncu sayısı Bölge sayısı - Şarkı Kaynağı - Oyun Modu XOX: Oyuncu Seç 1. Takım 2. Takım diff --git a/Tests/VocaluxeLib/XML/CXmlSerializerTest.cs b/Tests/VocaluxeLib/XML/CXmlSerializerTest.cs index 8c027489..ca381abc 100644 --- a/Tests/VocaluxeLib/XML/CXmlSerializerTest.cs +++ b/Tests/VocaluxeLib/XML/CXmlSerializerTest.cs @@ -371,6 +371,38 @@ namespace Tests.VocaluxeLib.XML ", newXml); } + [Test] + public void TestEscapedValues() + { + const string s = _Head + @" + Foo\'Bar + + Foo\'Bar + +"; + _AssertSerDeserMatch(s); + var xml = new CXmlDeserializer(new CXmlErrorHandler(exception => { })); + SUnescaping foo = xml.DeserializeString(@""); + Assert.AreEqual(foo.S, "Foo\'Bar"); + Assert.AreEqual(foo.Sub.S, "Foo\'Bar"); + } + + [Test] + public void TestUnescapedValues() + { + const string s = _Head + @" + Foo\'Bar + + Foo\'Bar + +"; + _AssertSerDeserMatch(s); + var xml = new CXmlDeserializer(new CXmlErrorHandler(exception => { }), true); + SUnescaping foo = xml.DeserializeString(@""); + Assert.AreEqual(foo.S, "Foo'Bar"); + Assert.AreEqual(foo.Sub.S, "Foo'Bar"); + } + [Test] public void TestRealFiles([Values(typeof(SThemeCover), typeof(CConfig.SConfig), /*typeof(SThemeScreen),*/ typeof(SDefaultFonts), typeof(SSkin), typeof(STheme), typeof(Dictionary))] Type type) { @@ -491,6 +523,20 @@ namespace Tests.VocaluxeLib.XML public SDefaultSub Sub; } + private struct SUnescaping + { + [DefaultValue("Foo\'Bar")] + public string S; + public SUnescapingSub Sub; + } + + private struct SUnescapingSub + { + [DefaultValue("Foo\'Bar")] + public string S; + } + + #pragma warning restore 169 #pragma warning restore 649 diff --git a/Vocaluxe/Base/CLanguage.cs b/Vocaluxe/Base/CLanguage.cs index a7f6f1ec..e1a30c41 100644 --- a/Vocaluxe/Base/CLanguage.cs +++ b/Vocaluxe/Base/CLanguage.cs @@ -161,7 +161,7 @@ namespace Vocaluxe.Base private static bool _LoadLanguageEntries(string filePath, out Dictionary texts) { - var deser = new CXmlDeserializer(); + var deser = new CXmlDeserializer(true); try { texts = deser.Deserialize>(filePath); diff --git a/Vocaluxe/Website/locales/de.json b/Vocaluxe/Website/locales/de.json index 1464ca30..4d9812c3 100644 --- a/Vocaluxe/Website/locales/de.json +++ b/Vocaluxe/Website/locales/de.json @@ -15,7 +15,7 @@ "mainPageSelectProfile": "Profile", "mainPageSelectProfileDesc": "Listet alle Profile auf", "mainPageTakePhotoLink": "Nehme Foto auf", - "mainPageTakePhotoLinkDesc": "Nimmt ein Foto auf und zeige es am Ende der Runde an", + "mainPageTakePhotoLinkDesc": "Nimmt ein Foto auf und zeigt es am ende der Runde an", "mainPageKeyboard": "Tastatur", "mainPageKeyboardDesc": "Sende Tastatureingaben", "mainPageSelectUserAdmin": "Administration", diff --git a/Vocaluxe/Website/locales/es.json b/Vocaluxe/Website/locales/es.json index ff33aef1..5c3f4113 100644 --- a/Vocaluxe/Website/locales/es.json +++ b/Vocaluxe/Website/locales/es.json @@ -77,10 +77,10 @@ "discoverConnectButton": "Conectar", "Checking...": "Comprobando...", "timeout": "Tiempo de espera", - "keyboardButtonShift": "Shift", - "keyboardButtonAlt": "Alt", + "keyboardButtonShift": "Shift", + "keyboardButtonAlt": "Alt", "keyboardButtonCtrl": "Control", "keyboardButtonBackspace": "Retroceso", "keyboardAutoSend": "Auto-enviar teclas.", - "keyboardButtonSend": "Mandar" + "keyboardButtonSend": "Mandar" } \ No newline at end of file diff --git a/Vocaluxe/Website/locales/Hungarian.json b/Vocaluxe/Website/locales/hu.json similarity index 97% rename from Vocaluxe/Website/locales/Hungarian.json rename to Vocaluxe/Website/locales/hu.json index a817b65a..a4d4af4a 100644 --- a/Vocaluxe/Website/locales/Hungarian.json +++ b/Vocaluxe/Website/locales/hu.json @@ -77,10 +77,10 @@ "discoverConnectButton": "Kapcsolódás", "Checking...": "Ellenőrzés...", "timeout": "Időtúllépés", - "keyboardButtonShift": "Shift", - "keyboardButtonAlt": "Alt", + "keyboardButtonShift": "Shift", + "keyboardButtonAlt": "Alt", "keyboardButtonCtrl": "Ctrl", "keyboardButtonBackspace": "Backspace", "keyboardAutoSend": "Billentyűleütések automatikus küldése", - "keyboardButtonSend": "Küldés" + "keyboardButtonSend": "Küldés" } \ No newline at end of file diff --git a/Vocaluxe/Website/locales/it.json b/Vocaluxe/Website/locales/it.json index c055b460..399d361b 100644 --- a/Vocaluxe/Website/locales/it.json +++ b/Vocaluxe/Website/locales/it.json @@ -81,6 +81,6 @@ "keyboardButtonAlt": "Alt", "keyboardButtonCtrl": "Control", "keyboardButtonBackspace": "Backspace", - "keyboardAutoSend": "Auto send keys", - "keyboardButtonSend": "Send" + "keyboardAutoSend": "Tasti auto invio", + "keyboardButtonSend": "Invia" } \ No newline at end of file diff --git a/Vocaluxe/Website/locales/Polish.json b/Vocaluxe/Website/locales/pl.json similarity index 100% rename from Vocaluxe/Website/locales/Polish.json rename to Vocaluxe/Website/locales/pl.json diff --git a/Vocaluxe/Website/locales/ru.json b/Vocaluxe/Website/locales/ru.json new file mode 100644 index 00000000..cd5301fa --- /dev/null +++ b/Vocaluxe/Website/locales/ru.json @@ -0,0 +1,86 @@ +{ + "loginName": "Пользователь:", + "loginPassword": "Пароль:", + "loginButton": "Логин", + "registerButton": "Создать профиль", + "discoverReadQrButton": "Сканировать QRкод", + "mainPageYourProfileLink": "Ваш профиль", + "mainPageYourProfileLinkDesc": "Редактировать ваш профиль", + "mainPageCurrentSongLink": "Текущая песня", + "mainPageCurrentSongLinkDesc": "Отображение информации о текущей песне", + "mainPageSelectSong": "Все песни", + "mainPageSelectSongDesc": "Список всех доступных песен", + "mainPageSelectPlaylist": "Все плейлисты", + "mainPageSelectPlaylistDesc": "Список всех плейлистов", + "mainPageSelectProfile": "Профили", + "mainPageSelectProfileDesc": "Показать все профили", + "mainPageTakePhotoLink": "Выбрать Фото", + "mainPageTakePhotoLinkDesc": "Выбрать фотографию и отображать ее в конце текущего раунда", + "mainPageKeyboard": "Клавиатура", + "mainPageKeyboardDesc": "Отправить ключи", + "mainPageSelectUserAdmin": "Администрирование", + "mainPageSelectUserAdminDesc": "Настроить права пользователя", + "mainPageLogoutLink": "Выход из системы", + "mainPageLogoutLinkDesc": "Закрыть сессию", + "selectProfileHeader": "Все профили", + "displayProfileHeader": "Профиль", + "displayProfileName": "Имя:", + "displayProfilePlayerType": "Тип Игрока:", + "displayProfilePlayerTypeNormal": "Обычный", + "displayProfilePlayerTypeGuest": "Гость", + "displayProfilePlayerDifficulty": "Сложность:", + "displayProfilePlayerDifficultyEasy": "Легко", + "displayProfilePlayerDifficultyNormal": "Нормально", + "displayProfilePlayerDifficultyHard": "Сложно", + "displayProfilePlayerPassword": "Новый Пароль:", + "displayProfilePlayerSaveButton": "Сохранить и загрузить", + "displaySongHeader": "Нет текущей песни", + "displaySongArtist": "Артист:", + "displaySongGenre": "Жанр:", + "displaySongYear": "Год:", + "displaySongLanguage": "Язык:", + "displaySongIsDuet": "Дуэт:", + "popupVideoClose": "Закрыть", + "selectSongHeader": "Все песни", + "keyboardHeader": "Клавиатура", + "keyboardButtonUp": "вверх", + "keyboardButtonLeft": "влево", + "keyboardButtonRight": "вправо", + "keyboardButtonDown": "вниз", + "keyboardButtonEscape": "escape", + "keyboardButtonTab": "tab", + "keyboardButtonReturn": "return", + "keyboardButtonKeys": "Чтобы отправить другие ключи введите здесь:", + "selectUserAdminHeader": "Все профили", + "displayUserAdminHeader": "Профиль", + "displayUserAdminContentSaveButton": "Сохранить", + "selectPlaylistHeader": "Выборать из плейлиста", + "displayPlaylistHeader": "Плейлист", + "displayPlaylistSaveButton": "Сохранить", + "selectPlaylistAddPlaylistButton": "Добавить", + "Loading (external)...": "Загрузка (внешняя)...", + "Loading...": "Загрузка...", + "Creating...": "Создание...", + "Error...": "Ошибка...", + "No connection": "Нет соединения", + "No session": "Нет сеанса", + "Uploading photo...": "Загрузка фото..", + "Getting current song...": "Получение текущей песни...", + "Login...": "Логин...", + "Creating profile...": "Создание профиля...", + "This is not a valid name.": "Это неверное имя.", + "Uploading profile...": "Загрузка профиля...", + "songs": "песни", + "YourName": "Ваше имя", + "discoverConnectHeader": "Подключиться к серверу", + "discoverConnectServerAddress": "Адрес сервера:", + "discoverConnectButton": "Соединение", + "Checking...": "Проверка...", + "timeout": "Время ожидания", + "keyboardButtonShift": "Shift", + "keyboardButtonAlt": "Alt", + "keyboardButtonCtrl": "Control", + "keyboardButtonBackspace": "Backspace", + "keyboardAutoSend": "Автоматическая отправка ключей", + "keyboardButtonSend": "Отправить" +} \ No newline at end of file diff --git a/Vocaluxe/Website/locales/tr.json b/Vocaluxe/Website/locales/tr.json index 527a3b48..189d53ac 100644 --- a/Vocaluxe/Website/locales/tr.json +++ b/Vocaluxe/Website/locales/tr.json @@ -77,10 +77,10 @@ "discoverConnectButton": "Bağlan", "Checking...": "Kontrol ediliyor...", "timeout": "Zaman aşımı", - "keyboardButtonShift": "Shift", - "keyboardButtonAlt": "Alt", + "keyboardButtonShift": "Shift", + "keyboardButtonAlt": "Alt", "keyboardButtonCtrl": "Control", "keyboardButtonBackspace": "Backspace", "keyboardAutoSend": "Auto send keys", - "keyboardButtonSend": "Send" + "keyboardButtonSend": "Send" } \ No newline at end of file diff --git a/VocaluxeLib/Xml/CXmlDeserializer.cs b/VocaluxeLib/Xml/CXmlDeserializer.cs index 5a415397..c835dff4 100644 --- a/VocaluxeLib/Xml/CXmlDeserializer.cs +++ b/VocaluxeLib/Xml/CXmlDeserializer.cs @@ -23,6 +23,7 @@ using System.IO; using System.Linq; using System.Reflection; using System.Text; +using System.Text.RegularExpressions; using System.Xml; using VocaluxeLib.Log; @@ -179,14 +180,28 @@ namespace VocaluxeLib.Xml } private readonly IXmlErrorHandler _ErrorHandler; + private readonly bool _UnescapeStringValues; + + ///

+ /// Creates a new XmlDeserializer + /// + /// Set to true if string values should be unescaped during reading + public CXmlDeserializer(bool unescapeStringValues) + { + _ErrorHandler = new CXmlDefaultErrorHandler(); + _UnescapeStringValues = unescapeStringValues; + } + /// /// Creates a new XmlDeserializer /// /// Class to be used for error callbacks, if not given a default handler will be used which throws errors and logs warnings - public CXmlDeserializer(IXmlErrorHandler errorHandler = null) + /// Set to true if string values should be unescaped during reading + public CXmlDeserializer(IXmlErrorHandler errorHandler = null, bool unescapeStringValues = false) { _ErrorHandler = errorHandler ?? new CXmlDefaultErrorHandler(); + _UnescapeStringValues = unescapeStringValues; } /// @@ -216,8 +231,15 @@ namespace VocaluxeLib.Xml } if (type == typeof(Guid)) return Guid.Parse(node.InnerText); - if (type == typeof(string)) - return node == null ? null : node.InnerText; + if (type == typeof(string)) { + if(node == null) { + return null; + } else if(_UnescapeStringValues) { + return Regex.Unescape(node.InnerText); + } else { + return node.InnerText; + } + } if (type.IsPrimitive) return _GetPrimitiveValue(node, type) ?? value; if (type.IsNullable()) diff --git a/transifex.yaml b/transifex.yaml new file mode 100644 index 00000000..51a3a67d --- /dev/null +++ b/transifex.yaml @@ -0,0 +1,24 @@ +git: + filters: + - filter_type: file + file_format: ANDROID + source_file: Output/Languages/en.xml + source_language: en + translation_files_expression: 'Output/Languages/.xml' + - filter_type: file + file_format: ANDROID + source_file: Output/PartyModes/Challenge/Languages/en.xml + source_language: en + translation_files_expression: 'Output/PartyModes/Challenge/Languages/.xml' + - filter_type: file + file_format: ANDROID + source_file: Output/PartyModes/TicTacToe/Languages/en.xml + source_language: en + translation_files_expression: 'Output/PartyModes/TicTacToe/Languages/.xml' + - filter_type: file + file_format: KEYVALUEJSON + source_file: Vocaluxe/Website/locales/en.json + source_language: en + translation_files_expression: 'Vocaluxe/Website/locales/.json' + settings: + pr_branch_name: translations/ \ No newline at end of file From 16bb07404a819676c90d32befe20f09c794092e3 Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Thu, 28 Dec 2023 21:07:19 +0100 Subject: [PATCH 28/39] Updates for project Vocaluxe and language de (#662) * Translate Vocaluxe/Website/locales/en.json in de 100% translated source file: 'Vocaluxe/Website/locales/en.json' on 'de'. * Translate en.xml in de 90% of minimum 90% translated source file: 'en.xml' on 'de'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate en.xml in de 93% of minimum 90% translated source file: 'en.xml' on 'de'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate en.xml in de 96% of minimum 90% translated source file: 'en.xml' on 'de'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate en.xml in de 100% translated source file: 'en.xml' on 'de'. --------- Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- Output/PartyModes/TicTacToe/Languages/de.xml | 4 ++++ Vocaluxe/Website/locales/de.json | 6 +++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/Output/PartyModes/TicTacToe/Languages/de.xml b/Output/PartyModes/TicTacToe/Languages/de.xml index 8839754c..57c68b5f 100644 --- a/Output/PartyModes/TicTacToe/Languages/de.xml +++ b/Output/PartyModes/TicTacToe/Languages/de.xml @@ -18,10 +18,14 @@ Anzahl der Spieler in Team 2 Anzahl der Felder Joker nach jeder Runde auffüllen + Joker-Anzahl + Spieler wechseln Tic-Tac-Toe: Spielerwahl + Ausgewählte Spieler für dieses Team: Team 1 Team 2 Zufällig auswählen + Füge mindestens einen Spieler zu beiden Teams hinzu! / Zum Hinzufügen den Spieleravatar auf die Liste der ausgewählten Spieler ziehen! / Zum Entfernen den Spieleravatar mit rechter Maustaste anklicken! Tic-Tac-Toe Wählt ein Feld aus. Nächster Spieler diff --git a/Vocaluxe/Website/locales/de.json b/Vocaluxe/Website/locales/de.json index 4d9812c3..89b2f705 100644 --- a/Vocaluxe/Website/locales/de.json +++ b/Vocaluxe/Website/locales/de.json @@ -77,10 +77,10 @@ "discoverConnectButton": "Verbinden", "Checking...": "Prüfen...", "timeout": "Zeitüberschreitung", - "keyboardButtonShift": "Shift", - "keyboardButtonAlt": "Alt", + "keyboardButtonShift": "Shift", + "keyboardButtonAlt": "Alt", "keyboardButtonCtrl": "Steuerung", "keyboardButtonBackspace": "Backspace", "keyboardAutoSend": "Automatisch Tasten senden", - "keyboardButtonSend": "Senden" + "keyboardButtonSend": "Senden" } \ No newline at end of file From f7e60110b7566412fb464ca3a41956606db9a89b Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Thu, 28 Dec 2023 21:07:39 +0100 Subject: [PATCH 29/39] Translate Vocaluxe/Website/locales/en.json in cs (#663) 100% translated source file: 'Vocaluxe/Website/locales/en.json' on 'cs'. Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- Vocaluxe/Website/locales/cs.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Vocaluxe/Website/locales/cs.json b/Vocaluxe/Website/locales/cs.json index 3cc5e9c2..e300efc1 100644 --- a/Vocaluxe/Website/locales/cs.json +++ b/Vocaluxe/Website/locales/cs.json @@ -77,10 +77,10 @@ "discoverConnectButton": "Připojit se", "Checking...": "Ověřuje se...", "timeout": "Překročení časového omezení", - "keyboardButtonShift": "Shift", - "keyboardButtonAlt": "Alt", + "keyboardButtonShift": "Shift", + "keyboardButtonAlt": "Alt", "keyboardButtonCtrl": "Ctrl", "keyboardButtonBackspace": "Backspace", "keyboardAutoSend": "Poslat klávesy automaticky", - "keyboardButtonSend": "Poslat" + "keyboardButtonSend": "Poslat" } \ No newline at end of file From dccfebcd728959a3dc70f1d7e153ab4e06ff133a Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Thu, 28 Dec 2023 21:07:50 +0100 Subject: [PATCH 30/39] Translate Vocaluxe/Website/locales/en.json in sv (#661) 100% translated source file: 'Vocaluxe/Website/locales/en.json' on 'sv'. Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- Vocaluxe/Website/locales/sv.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Vocaluxe/Website/locales/sv.json b/Vocaluxe/Website/locales/sv.json index 53203293..98427174 100644 --- a/Vocaluxe/Website/locales/sv.json +++ b/Vocaluxe/Website/locales/sv.json @@ -77,10 +77,10 @@ "discoverConnectButton": "Anslut", "Checking...": "Kontrollerar...", "timeout": "Timeout", - "keyboardButtonShift": "Skift", - "keyboardButtonAlt": "Alt", + "keyboardButtonShift": "Skift", + "keyboardButtonAlt": "Alt", "keyboardButtonCtrl": "Ctrl", "keyboardButtonBackspace": "Backsteg", "keyboardAutoSend": "Autoskicka knappar", - "keyboardButtonSend": "Skicka" + "keyboardButtonSend": "Skicka" } \ No newline at end of file From 806b7a884e165e3240751d0f49c696bb6d9b2883 Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Thu, 28 Dec 2023 21:08:01 +0100 Subject: [PATCH 31/39] Translate Vocaluxe/Website/locales/en.json in it (#660) 100% translated source file: 'Vocaluxe/Website/locales/en.json' on 'it'. Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- Vocaluxe/Website/locales/it.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Vocaluxe/Website/locales/it.json b/Vocaluxe/Website/locales/it.json index 399d361b..906aafea 100644 --- a/Vocaluxe/Website/locales/it.json +++ b/Vocaluxe/Website/locales/it.json @@ -77,10 +77,10 @@ "discoverConnectButton": "Connetti", "Checking...": "Controllo...", "timeout": "Timeout", - "keyboardButtonShift": "Shift", - "keyboardButtonAlt": "Alt", + "keyboardButtonShift": "Shift", + "keyboardButtonAlt": "Alt", "keyboardButtonCtrl": "Control", "keyboardButtonBackspace": "Backspace", "keyboardAutoSend": "Tasti auto invio", - "keyboardButtonSend": "Invia" + "keyboardButtonSend": "Invia" } \ No newline at end of file From 2c006fad24d150e95773b99935877420bc3da48e Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Thu, 28 Dec 2023 21:08:12 +0100 Subject: [PATCH 32/39] Translate Vocaluxe/Website/locales/en.json in pt (#659) 100% translated source file: 'Vocaluxe/Website/locales/en.json' on 'pt'. Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- Vocaluxe/Website/locales/pt.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Vocaluxe/Website/locales/pt.json b/Vocaluxe/Website/locales/pt.json index cfdff899..fc024f99 100644 --- a/Vocaluxe/Website/locales/pt.json +++ b/Vocaluxe/Website/locales/pt.json @@ -77,10 +77,10 @@ "discoverConnectButton": "Ligar", "Checking...": "A verificar...", "timeout": "Tempo de espera excedido", - "keyboardButtonShift": "Shift", - "keyboardButtonAlt": "Alt", + "keyboardButtonShift": "Shift", + "keyboardButtonAlt": "Alt", "keyboardButtonCtrl": "Control", "keyboardButtonBackspace": "Backspace", "keyboardAutoSend": "Enviar teclas automáticamente", - "keyboardButtonSend": "Enviar" + "keyboardButtonSend": "Enviar" } \ No newline at end of file From fa58e6e1de5b4605e78f3569c0899d6df60f1719 Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Thu, 28 Dec 2023 21:08:22 +0100 Subject: [PATCH 33/39] Translate Vocaluxe/Website/locales/en.json in nl (#658) 100% translated source file: 'Vocaluxe/Website/locales/en.json' on 'nl'. Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- Vocaluxe/Website/locales/nl.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Vocaluxe/Website/locales/nl.json b/Vocaluxe/Website/locales/nl.json index aeee54ba..5642fbca 100644 --- a/Vocaluxe/Website/locales/nl.json +++ b/Vocaluxe/Website/locales/nl.json @@ -77,10 +77,10 @@ "discoverConnectButton": "Verbinden", "Checking...": "Controleren...", "timeout": "Timeout", - "keyboardButtonShift": "Shift", - "keyboardButtonAlt": "Alt", + "keyboardButtonShift": "Shift", + "keyboardButtonAlt": "Alt", "keyboardButtonCtrl": "Control", "keyboardButtonBackspace": "Backspace", "keyboardAutoSend": "Stuur toetsen automatisch", - "keyboardButtonSend": "Verzenden" + "keyboardButtonSend": "Verzenden" } \ No newline at end of file From c8188fe3e8ba60197eac0bb8f8bdf456638fc860 Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Thu, 28 Dec 2023 21:08:34 +0100 Subject: [PATCH 34/39] Translate Vocaluxe/Website/locales/en.json in fr (#657) 100% translated source file: 'Vocaluxe/Website/locales/en.json' on 'fr'. Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- Vocaluxe/Website/locales/fr.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Vocaluxe/Website/locales/fr.json b/Vocaluxe/Website/locales/fr.json index 4ab27121..44a3241d 100644 --- a/Vocaluxe/Website/locales/fr.json +++ b/Vocaluxe/Website/locales/fr.json @@ -77,10 +77,10 @@ "discoverConnectButton": "Connecter", "Checking...": "Vérification", "timeout": "Temps dépassé", - "keyboardButtonShift": "Maj.", - "keyboardButtonAlt": "Alt", + "keyboardButtonShift": "Maj.", + "keyboardButtonAlt": "Alt", "keyboardButtonCtrl": "Controle", "keyboardButtonBackspace": "Retour", "keyboardAutoSend": "Envoyer la saisie automatiquement", - "keyboardButtonSend": "Envoyer" + "keyboardButtonSend": "Envoyer" } \ No newline at end of file From e8bba399585bd709220fb78a9734500f5b96b3a2 Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 06:56:28 +0100 Subject: [PATCH 35/39] Updates for project Vocaluxe and language fr (#665) * Translate en.xml in fr 93% of minimum 90% translated source file: 'en.xml' on 'fr'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate en.xml in fr 93% of minimum 90% translated source file: 'en.xml' on 'fr'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate en.xml in fr 96% of minimum 90% translated source file: 'en.xml' on 'fr'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate en.xml in fr 100% translated source file: 'en.xml' on 'fr'. * Translate en.xml in fr 100% translated source file: 'en.xml' on 'fr'. --------- Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- Output/PartyModes/TicTacToe/Languages/fr.xml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Output/PartyModes/TicTacToe/Languages/fr.xml b/Output/PartyModes/TicTacToe/Languages/fr.xml index 40e9dd3c..b4c6f24d 100644 --- a/Output/PartyModes/TicTacToe/Languages/fr.xml +++ b/Output/PartyModes/TicTacToe/Languages/fr.xml @@ -1,8 +1,8 @@ Français - Tic-Tac-Toe - Jouez au Tic-Tac-Toe d'une nouvelle façon + Morpion + Jouez au Morpion d\'une nouvelle façon Des matchs amusants alliant stratégie, gains et compétences Suivant Retour @@ -14,10 +14,12 @@ Chansons Equipe Tic-Tac-Toe: Configuration - Nombre de joueurs dans l'Equipe 1 - Nombre de joueurs dans l'Equipe 2 + Nombre de joueurs dans l\'Équipe 1 + Nombre de joueurs dans l\'Équipe 2 Nombre de champs Recharger les jokers a chaque tour + Nombre de jokers + Changer de joueur Tic-Tac-Toe: Choix des joueurs Joueurs sélectionnés pour cette équipe : Equipe 1 From 456fbe136b0f690af676d166ebc961ddff245e29 Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 06:56:41 +0100 Subject: [PATCH 36/39] Updates for project Vocaluxe and language ru (#664) * Translate en.xml in ru 100% translated source file: 'en.xml' on 'ru'. * Translate en.xml in ru 90% of minimum 90% translated source file: 'en.xml' on 'ru'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate en.xml in ru 93% of minimum 90% translated source file: 'en.xml' on 'ru'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate en.xml in ru 96% of minimum 90% translated source file: 'en.xml' on 'ru'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate Vocaluxe/Website/locales/en.json in ru 100% translated source file: 'Vocaluxe/Website/locales/en.json' on 'ru'. * Translate Output/Languages/en.xml in ru 100% translated source file: 'Output/Languages/en.xml' on 'ru'. * Translate Output/Languages/en.xml in ru 100% translated source file: 'Output/Languages/en.xml' on 'ru'. --------- Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- Output/Languages/ru.xml | 4 ++-- Output/PartyModes/Challenge/Languages/ru.xml | 2 +- Output/PartyModes/TicTacToe/Languages/ru.xml | 5 ++++- Vocaluxe/Website/locales/ru.json | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Output/Languages/ru.xml b/Output/Languages/ru.xml index 8dced1ed..9695f746 100644 --- a/Output/Languages/ru.xml +++ b/Output/Languages/ru.xml @@ -10,7 +10,7 @@ Аудиопотоки Видеопотоки Текстуры - Тонус + ToneAbs Макс. громкость Загруженные песни Мышь @@ -81,7 +81,7 @@ Список всех Список лучших Собственная музыка и фоновая музыка - Нет собственной музыки + Без собственной музыки Только собственная музыка Только выбранная песня Все diff --git a/Output/PartyModes/Challenge/Languages/ru.xml b/Output/PartyModes/Challenge/Languages/ru.xml index b4949f4d..00e55d30 100644 --- a/Output/PartyModes/Challenge/Languages/ru.xml +++ b/Output/PartyModes/Challenge/Languages/ru.xml @@ -1,6 +1,6 @@ - Английский + Русский Режим соревнования Сыграть несколько раундов соревнований. Для всех, кому интересны дуэльные бои. diff --git a/Output/PartyModes/TicTacToe/Languages/ru.xml b/Output/PartyModes/TicTacToe/Languages/ru.xml index 8ba288bf..5879a215 100644 --- a/Output/PartyModes/TicTacToe/Languages/ru.xml +++ b/Output/PartyModes/TicTacToe/Languages/ru.xml @@ -1,6 +1,6 @@ - Английский + Русский Крестики-нолики Играйте в Крестики-нолики особым образом Веселые раунды со стратегией, удачей и навыками @@ -18,7 +18,10 @@ Номер игрока из команды 2 Количество полей Пополняйте джокеры каждый раунд + Количество джокеров + Сменить игрока Крестики-нолики: Выберите игрока + Выбранные игроки для этой команды: Команда 1 Команда 2 Случайный выбор diff --git a/Vocaluxe/Website/locales/ru.json b/Vocaluxe/Website/locales/ru.json index cd5301fa..38f163ae 100644 --- a/Vocaluxe/Website/locales/ru.json +++ b/Vocaluxe/Website/locales/ru.json @@ -3,7 +3,7 @@ "loginPassword": "Пароль:", "loginButton": "Логин", "registerButton": "Создать профиль", - "discoverReadQrButton": "Сканировать QRкод", + "discoverReadQrButton": "Сканировать QR-код", "mainPageYourProfileLink": "Ваш профиль", "mainPageYourProfileLinkDesc": "Редактировать ваш профиль", "mainPageCurrentSongLink": "Текущая песня", From bad9ee304b8c4cfa374ff7ab0b8cd52132b1f3dd Mon Sep 17 00:00:00 2001 From: "transifex-integration[bot]" <43880903+transifex-integration[bot]@users.noreply.github.com> Date: Fri, 29 Dec 2023 10:27:02 +0100 Subject: [PATCH 37/39] Updates for project Vocaluxe and language cs (#666) * Translate Output/Languages/en.xml in cs 97% of minimum 90% translated source file: 'Output/Languages/en.xml' on 'cs'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate Output/Languages/en.xml in cs 97% of minimum 90% translated source file: 'Output/Languages/en.xml' on 'cs'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate Output/Languages/en.xml in cs 97% of minimum 90% translated source file: 'Output/Languages/en.xml' on 'cs'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate Output/Languages/en.xml in cs 98% of minimum 90% translated source file: 'Output/Languages/en.xml' on 'cs'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate Output/Languages/en.xml in cs 98% of minimum 90% translated source file: 'Output/Languages/en.xml' on 'cs'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate Output/Languages/en.xml in cs 98% of minimum 90% translated source file: 'Output/Languages/en.xml' on 'cs'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate Output/Languages/en.xml in cs 99% of minimum 90% translated source file: 'Output/Languages/en.xml' on 'cs'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate Output/Languages/en.xml in cs 99% of minimum 90% translated source file: 'Output/Languages/en.xml' on 'cs'. Sync of partially translated files: untranslated content is included with an empty translation or source language content depending on file format * Translate Output/Languages/en.xml in cs 100% translated source file: 'Output/Languages/en.xml' on 'cs'. * Translate en.xml in cs 100% translated source file: 'en.xml' on 'cs'. * Translate en.xml in cs 100% translated source file: 'en.xml' on 'cs'. * Translate en.xml in cs 100% translated source file: 'en.xml' on 'cs'. --------- Co-authored-by: transifex-integration[bot] <43880903+transifex-integration[bot]@users.noreply.github.com> --- Output/Languages/cs.xml | 9 +++++++++ Output/PartyModes/TicTacToe/Languages/cs.xml | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/Output/Languages/cs.xml b/Output/Languages/cs.xml index 6b378176..39d2c221 100644 --- a/Output/Languages/cs.xml +++ b/Output/Languages/cs.xml @@ -152,12 +152,21 @@ (%v písní) (%v píseň) %a - %t + A-Z = Skok na písmeno • F3 = Vyhledávat • CTRL+R = Náhodný výběr - CTRL+S = Spustit směsku • CTRL+# = Změnit řazení skladeb • CTRL+T = Zapnout/Vypnout zobrazení kategorií • Mezerník = Otevřít volby skladby • ESC = Zpět do hlavní nabídky + A-Z = Vyhledávání umělce a názvu, předpony pro vyhledávání → a: = umělec • t: = název • c: = tvůrce • e: = edice • g: = žánr • y: = rok (např. 1999 nebo 1980-1989) • l: = jazyk • al: = album • fi: = název souboru • fo: = název složky + 1-6 = stisknutím čísla týmu použijete náhodný žolík. + Řazení: %s + Žádnou směsku pro tuto píseň! Pozastavit Zastavit zpívání Pokračovat Přeskočit tuto píseň Začít kolo znovu Začít hru znovu + Žádné další písně v seznamu skladeb! + Webová kamera není dostupná! + Poměr stran: %a + Přeskočeno %s sekund Výsledky Hodnocení Body diff --git a/Output/PartyModes/TicTacToe/Languages/cs.xml b/Output/PartyModes/TicTacToe/Languages/cs.xml index a7294248..49e692fd 100644 --- a/Output/PartyModes/TicTacToe/Languages/cs.xml +++ b/Output/PartyModes/TicTacToe/Languages/cs.xml @@ -18,10 +18,14 @@ Počet hráčů v týmu 2 Počet polí Doplnit žolíky každé kolo + Počet žolíků + Přepnout hráče Tic-Tac-Toe: Výběr hráče + Vybraní hráči pro tento tým: Tým 1 Tým 2 Vybrat náhodně + Přidejte alespoň jednoho hráče do obou týmů! / Přetáhněte zástupné obrázky hráčů a přidejte je do seznamu vybraných hráčů! / Klepnutím pravým tlačítkem myši na jej zastupující obrázek vybraného hráče odeberete! Tic-Tac-Toe Vybrat pole. Další hráč From e6f27d6281b61cc70db0808d23b8fe4c59bb453a Mon Sep 17 00:00:00 2001 From: Damien LAGUERRE Date: Fri, 29 Dec 2023 22:33:48 +0100 Subject: [PATCH 38/39] #559 Display song name on sing screen in pause menu --- Output/Themes/Genius/Screens/ScreenSing.xml | 14 ++++++++++++++ Vocaluxe/Screens/CScreenSing.cs | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/Output/Themes/Genius/Screens/ScreenSing.xml b/Output/Themes/Genius/Screens/ScreenSing.xml index 44badc9c..2561cebb 100644 --- a/Output/Themes/Genius/Screens/ScreenSing.xml +++ b/Output/Themes/Genius/Screens/ScreenSing.xml @@ -694,6 +694,20 @@ Outline TR_SCREENSING_PAUSE + + 640 + 10 + -2.11 + 40 + 0 + + + Center + Center + + Normal + + 10 55 diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs index 1f29a202..a16da86d 100644 --- a/Vocaluxe/Screens/CScreenSing.cs +++ b/Vocaluxe/Screens/CScreenSing.cs @@ -57,6 +57,7 @@ namespace Vocaluxe.Screens private const string _TextDuetName1 = "TextDuetName1"; private const string _TextDuetName2 = "TextDuetName2"; private const string _TextMedleyCountdown = "TextMedleyCountdown"; + private const string _TextPauseSongName = "TextPauseSongName"; private string[,,] _TextScores; private string[,,] _TextNames; private List _TextsPause; @@ -1114,6 +1115,13 @@ namespace Vocaluxe.Screens _Buttons[_ButtonRestartGame].Visible = _Pause; _Buttons[_ButtonRestartRound].Visible = _Pause && CGame.NumRounds > 1; + if (_Pause && _TimerSongText.IsRunning) + _TimerSongText.Stop(); + else + _TimerSongText.Start(); + + _Texts[_TextSongName].Visible = !_Pause; + if (_Pause) CSound.Pause(_CurrentStream); else @@ -1149,6 +1157,7 @@ namespace Vocaluxe.Screens if (rounds > 1) songname += " (" + CGame.RoundNr + "/" + rounds + ")"; _Texts[_TextSongName].Text = songname; + _Texts[_TextPauseSongName].Text = songname; _CurrentStream = CSound.Load(song.GetMP3(), false, true, CConfig.Config.Sound.KaraokeEffect == EOffOn.TR_CONFIG_ON ? EAudioEffect.Karaoke : EAudioEffect.None); CSound.SetStreamVolume(_CurrentStream, 100); From 9daf4c97e16cb7f11ff06450e0c94ab2222843a8 Mon Sep 17 00:00:00 2001 From: Damien LAGUERRE Date: Sun, 31 Dec 2023 10:15:01 +0100 Subject: [PATCH 39/39] Increase the version of ScreenSing to 11. + Adds missing information to the changelog fer version 10. --- Output/Themes/Changelog/Changelog_ScreenSing.txt | 13 +++++++++++++ Output/Themes/Genius/Screens/ScreenSing.xml | 2 +- Vocaluxe/Screens/CScreenSing.cs | 2 +- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/Output/Themes/Changelog/Changelog_ScreenSing.txt b/Output/Themes/Changelog/Changelog_ScreenSing.txt index d86c8747..38ce8c20 100644 --- a/Output/Themes/Changelog/Changelog_ScreenSing.txt +++ b/Output/Themes/Changelog/Changelog_ScreenSing.txt @@ -1,5 +1,18 @@ ScreenSing ++++++++++ +Version 11 + +Add: + + ++++++++++ +Version 10 + +Add: + + + +++++++++ Version 9 diff --git a/Output/Themes/Genius/Screens/ScreenSing.xml b/Output/Themes/Genius/Screens/ScreenSing.xml index 2561cebb..30a03e2d 100644 --- a/Output/Themes/Genius/Screens/ScreenSing.xml +++ b/Output/Themes/Genius/Screens/ScreenSing.xml @@ -2,7 +2,7 @@ ScreenSing - 10 + 11 diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs index a16da86d..b7cb3b65 100644 --- a/Vocaluxe/Screens/CScreenSing.cs +++ b/Vocaluxe/Screens/CScreenSing.cs @@ -41,7 +41,7 @@ namespace Vocaluxe.Screens // Version number for theme files. Increment it, if you've changed something on the theme files! protected override int _ScreenVersion { - get { return 10; } + get { return 11; } } private struct STimeRect