diff --git a/Output/Languages/English.xml b/Output/Languages/English.xml
index a847b5d2..2ad11503 100644
--- a/Output/Languages/English.xml
+++ b/Output/Languages/English.xml
@@ -101,6 +101,7 @@
Version
Can\'t load this party-mode.
There are no mics configured!
+ %d mics are required for this party-mode!
Target audience
No teams
Number of teams
diff --git a/Output/Languages/German.xml b/Output/Languages/German.xml
index 968b2f79..82924766 100644
--- a/Output/Languages/German.xml
+++ b/Output/Languages/German.xml
@@ -101,6 +101,7 @@
Version
Dieser Party-Modus konnte nicht geladen werden.
Es sind keine Mikros konfiguriert!
+ Für diesen Party-Modus werden %d Mikros benötigt!
Zielgruppe
Keine Teams
Anzahl der Teams
diff --git a/Output/PartyModes/Challenge/Themes/Default/Screens/PartyScreenChallengeConfig.xml b/Output/PartyModes/Challenge/Themes/Default/Screens/PartyScreenChallengeConfig.xml
index da365e48..5dfbf453 100644
--- a/Output/PartyModes/Challenge/Themes/Default/Screens/PartyScreenChallengeConfig.xml
+++ b/Output/PartyModes/Challenge/Themes/Default/Screens/PartyScreenChallengeConfig.xml
@@ -194,7 +194,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -236,7 +236,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -278,7 +278,7 @@
27
- 0
+ 50
0
205.33
Outline
diff --git a/Output/PartyModes/Challenge/Themes/Default/Screens/PartyScreenChallengeNames.xml b/Output/PartyModes/Challenge/Themes/Default/Screens/PartyScreenChallengeNames.xml
index a3bd1919..5980e6d3 100644
--- a/Output/PartyModes/Challenge/Themes/Default/Screens/PartyScreenChallengeNames.xml
+++ b/Output/PartyModes/Challenge/Themes/Default/Screens/PartyScreenChallengeNames.xml
@@ -295,7 +295,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -337,8 +337,8 @@
27
- 0
- -5
+ 50
+ 5
205.33
Outline
Bold
diff --git a/Output/PartyModes/ChallengeMedley/Themes/Default/Screens/PartyScreenChallengeMedleyConfig.xml b/Output/PartyModes/ChallengeMedley/Themes/Default/Screens/PartyScreenChallengeMedleyConfig.xml
index 02620808..dbc62be5 100644
--- a/Output/PartyModes/ChallengeMedley/Themes/Default/Screens/PartyScreenChallengeMedleyConfig.xml
+++ b/Output/PartyModes/ChallengeMedley/Themes/Default/Screens/PartyScreenChallengeMedleyConfig.xml
@@ -194,7 +194,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -236,7 +236,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -278,7 +278,7 @@
27
- 0
+ 50
0
205.33
Outline
diff --git a/Output/PartyModes/ChallengeMedley/Themes/Default/Screens/PartyScreenChallengeMedleyNames.xml b/Output/PartyModes/ChallengeMedley/Themes/Default/Screens/PartyScreenChallengeMedleyNames.xml
index 72512c94..2292a076 100644
--- a/Output/PartyModes/ChallengeMedley/Themes/Default/Screens/PartyScreenChallengeMedleyNames.xml
+++ b/Output/PartyModes/ChallengeMedley/Themes/Default/Screens/PartyScreenChallengeMedleyNames.xml
@@ -295,7 +295,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -337,8 +337,8 @@
27
- 0
- -5
+ 50
+ 5
205.33
Outline
Bold
diff --git a/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeConfig.xml b/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeConfig.xml
index 1d02431f..bf570d8d 100644
--- a/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeConfig.xml
+++ b/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeConfig.xml
@@ -194,7 +194,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -236,7 +236,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -278,7 +278,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -320,7 +320,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -362,7 +362,7 @@
27
- 0
+ 50
0
205.33
Outline
diff --git a/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeNames.xml b/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeNames.xml
index df5bc5db..583ea0bc 100644
--- a/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeNames.xml
+++ b/Output/PartyModes/TicTacToe/Themes/Default/Screens/PartyScreenTicTacToeNames.xml
@@ -295,7 +295,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -337,8 +337,8 @@
27
- 0
- -5
+ 50
+ 5
205.33
Outline
Bold
diff --git a/Output/Themes/Ambient/Screens/PopupScreenVolumeControl.xml b/Output/Themes/Ambient/Screens/PopupScreenVolumeControl.xml
index 1bb2bfdd..1ec17015 100644
--- a/Output/Themes/Ambient/Screens/PopupScreenVolumeControl.xml
+++ b/Output/Themes/Ambient/Screens/PopupScreenVolumeControl.xml
@@ -46,22 +46,22 @@
Minus
Plus
- 1090
+ 1070
680
200
- 50
+ 30
-2
1195
- 682
+ 680
30
30
-2
- 1240
- 682
+ 1235
+ 680
30
30
-2
@@ -73,9 +73,9 @@
27
- -15
- -8
- 500
+ 0
+ 0
+ 25
Outline
Bold
1
diff --git a/Output/Themes/Ambient/Screens/ScreenNames.xml b/Output/Themes/Ambient/Screens/ScreenNames.xml
index fe44cdc6..24cac2dd 100644
--- a/Output/Themes/Ambient/Screens/ScreenNames.xml
+++ b/Output/Themes/Ambient/Screens/ScreenNames.xml
@@ -418,7 +418,7 @@
27
- 0
+ 50
0
186
Outline
@@ -460,7 +460,7 @@
20
- 0
+ 50
0
86
Outline
@@ -502,7 +502,7 @@
20
- 0
+ 50
0
86
Outline
@@ -544,7 +544,7 @@
20
- 0
+ 50
0
86
Outline
@@ -586,7 +586,7 @@
20
- 0
+ 50
0
86
Outline
@@ -628,7 +628,7 @@
20
- 0
+ 50
0
86
Outline
@@ -670,7 +670,7 @@
20
- 0
+ 50
0
86
Outline
diff --git a/Output/Themes/Ambient/Screens/ScreenOptionsGame.xml b/Output/Themes/Ambient/Screens/ScreenOptionsGame.xml
index cd75ed75..5b3b6ec4 100644
--- a/Output/Themes/Ambient/Screens/ScreenOptionsGame.xml
+++ b/Output/Themes/Ambient/Screens/ScreenOptionsGame.xml
@@ -302,7 +302,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -344,7 +344,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -386,7 +386,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -428,7 +428,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -470,7 +470,7 @@
27
- 0
+ 50
0
308
Outline
@@ -512,7 +512,7 @@
27
- 0
+ 50
0
205.33
Outline
diff --git a/Output/Themes/Ambient/Screens/ScreenOptionsLyrics.xml b/Output/Themes/Ambient/Screens/ScreenOptionsLyrics.xml
index 4ad2bbf6..ea8f4344 100644
--- a/Output/Themes/Ambient/Screens/ScreenOptionsLyrics.xml
+++ b/Output/Themes/Ambient/Screens/ScreenOptionsLyrics.xml
@@ -145,7 +145,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -187,7 +187,7 @@
27
- 0
+ 50
0
205.33
Outline
diff --git a/Output/Themes/Ambient/Screens/ScreenOptionsRecord.xml b/Output/Themes/Ambient/Screens/ScreenOptionsRecord.xml
index f5696725..95b8464d 100644
--- a/Output/Themes/Ambient/Screens/ScreenOptionsRecord.xml
+++ b/Output/Themes/Ambient/Screens/ScreenOptionsRecord.xml
@@ -338,7 +338,7 @@
27
- 0
+ 50
0
616
Outline
@@ -380,7 +380,7 @@
27
- 0
+ 50
0
154
Outline
@@ -422,7 +422,7 @@
27
- 0
+ 50
0
154
Outline
@@ -464,7 +464,7 @@
27
- 0
+ 50
0
123.2
Outline
diff --git a/Output/Themes/Ambient/Screens/ScreenOptionsSound.xml b/Output/Themes/Ambient/Screens/ScreenOptionsSound.xml
index ae35c3bc..9b7e88c6 100644
--- a/Output/Themes/Ambient/Screens/ScreenOptionsSound.xml
+++ b/Output/Themes/Ambient/Screens/ScreenOptionsSound.xml
@@ -187,7 +187,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -229,7 +229,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -271,7 +271,7 @@
27
- 0
+ 50
0
500
Outline
@@ -313,7 +313,7 @@
27
- 0
+ 50
0
500
Outline
@@ -355,7 +355,7 @@
27
- 0
+ 50
0
500
Outline
diff --git a/Output/Themes/Ambient/Screens/ScreenOptionsTheme.xml b/Output/Themes/Ambient/Screens/ScreenOptionsTheme.xml
index 3f0e890c..61ed39bb 100644
--- a/Output/Themes/Ambient/Screens/ScreenOptionsTheme.xml
+++ b/Output/Themes/Ambient/Screens/ScreenOptionsTheme.xml
@@ -317,7 +317,7 @@
27
- 0
+ 50
0
616
Outline
@@ -359,7 +359,7 @@
27
- 0
+ 50
0
616
Outline
@@ -401,7 +401,7 @@
27
- 0
+ 50
0
308
Outline
@@ -443,7 +443,7 @@
27
- 0
+ 50
0
308
Outline
@@ -485,7 +485,7 @@
27
- 0
+ 50
0
308
Outline
@@ -527,7 +527,7 @@
27
- 0
+ 50
0
308
Outline
@@ -569,7 +569,7 @@
27
- 0
+ 50
0
616
Outline
@@ -611,7 +611,7 @@
27
- 0
+ 50
0
616
Outline
diff --git a/Output/Themes/Ambient/Screens/ScreenOptionsVideo.xml b/Output/Themes/Ambient/Screens/ScreenOptionsVideo.xml
index b5740cc5..06a05c7b 100644
--- a/Output/Themes/Ambient/Screens/ScreenOptionsVideo.xml
+++ b/Output/Themes/Ambient/Screens/ScreenOptionsVideo.xml
@@ -280,7 +280,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -322,7 +322,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -364,7 +364,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -406,7 +406,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -448,7 +448,7 @@
27
- 0
+ 50
0
205.33
Outline
@@ -490,7 +490,7 @@
27
- 0
+ 50
0
150
Outline
diff --git a/Output/Themes/Ambient/Screens/ScreenParty.xml b/Output/Themes/Ambient/Screens/ScreenParty.xml
index de8283d4..3dec51bd 100644
--- a/Output/Themes/Ambient/Screens/ScreenParty.xml
+++ b/Output/Themes/Ambient/Screens/ScreenParty.xml
@@ -348,7 +348,7 @@
27
- 0
+ 50
0
600
Outline
diff --git a/Output/Themes/Ambient/Screens/ScreenProfiles.xml b/Output/Themes/Ambient/Screens/ScreenProfiles.xml
index ca84426b..c612e90e 100644
--- a/Output/Themes/Ambient/Screens/ScreenProfiles.xml
+++ b/Output/Themes/Ambient/Screens/ScreenProfiles.xml
@@ -509,7 +509,7 @@
27
- 0
+ 50
0
219.2
Outline
@@ -551,7 +551,7 @@
27
- 0
+ 50
0
208.67
Outline
@@ -593,7 +593,7 @@
27
- 0
+ 50
0
208.67
Outline
@@ -635,7 +635,7 @@
27
- 0
+ 50
0
313
Outline
@@ -677,7 +677,7 @@
27
- 0
+ 50
0
313
Outline
diff --git a/Output/Themes/Ambient/Screens/ScreenSong.xml b/Output/Themes/Ambient/Screens/ScreenSong.xml
index d9f45cd2..62dba236 100644
--- a/Output/Themes/Ambient/Screens/ScreenSong.xml
+++ b/Output/Themes/Ambient/Screens/ScreenSong.xml
@@ -899,7 +899,7 @@
25
- 0
+ 50
0
280
Outline
@@ -941,7 +941,7 @@
25
- 0
+ 50
0
280
Outline
@@ -983,7 +983,7 @@
25
- 0
+ 50
0
280
Outline
@@ -1025,7 +1025,7 @@
25
- 0
+ 50
0
280
Outline
@@ -1232,7 +1232,7 @@
-
+
Button
SelectSlideArrowLeft
SelectSlideArrowRight
diff --git a/PartyModes/PartyModeChallenge/CChallengeRounds.cs b/PartyModes/PartyModeChallenge/CChallengeRounds.cs
index 6b45ea1f..d09a3b3b 100644
--- a/PartyModes/PartyModeChallenge/CChallengeRounds.cs
+++ b/PartyModes/PartyModeChallenge/CChallengeRounds.cs
@@ -17,218 +17,110 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
+using VocaluxeLib.Utils.Combinatorics;
namespace VocaluxeLib.PartyModes.Challenge
{
public class CChallengeRounds
{
- private readonly Random _Rand;
- private readonly int _NumPlayer;
-
- public readonly List Rounds;
+ private readonly List _Rounds = new List();
public int Count
{
- get { return Rounds.Count; }
+ get { return _Rounds.Count; }
}
- public CCombination this[int index]
+ public CRound this[int index]
{
- get { return Rounds[index]; }
+ get { return _Rounds[index]; }
}
- public CChallengeRounds(int numRounds, int numPlayer, int numPlayerAtOnce)
+ public CChallengeRounds(int numRounds, int numPlayer, int playersPerRound)
{
- Rounds = new List();
- _Rand = new Random(DateTime.Now.Millisecond);
+ if (numRounds < 1 || numPlayer < 1 || playersPerRound < 1)
+ throw new ArgumentException("Invalid paramters for the rounds");
- if (numPlayerAtOnce < 1 || numRounds < 1 || numPlayer == 0)
- _NumPlayer = 0;
- else
- {
- _NumPlayer = numPlayer;
- _BuildRounds(numRounds, numPlayerAtOnce, _Rand);
- }
+ if (playersPerRound > numPlayer)
+ playersPerRound = numPlayer;
+
+ _BuildRounds(numRounds, numPlayer, playersPerRound);
}
- public CCombination GetRound(int roundNr)
+ ///
+ /// Divides players in 2 categories: Those how sung the most and the others
+ ///
+ /// List matching the playerIndex to the number of songs sung
+ private static List _GetPlayersForRound(IList numSung)
{
- if (roundNr >= Rounds.Count || _NumPlayer == 0 || Rounds.Count == 0)
- return null;
-
- return Rounds[roundNr];
+ List mustSing = new List();
+ int max = numSung.Max();
+ for (int i = 0; i < numSung.Count; i++)
+ {
+ if (numSung[i] < max)
+ mustSing.Add(i);
+ }
+ return mustSing;
}
- private void _BuildRounds(int numRounds, int numPlayerAtOnce, Random rand)
+ private static void _AddCombinations(int numPlayer, int playersPerRound, List combinations)
{
- CCombinations combinations = new CCombinations(_NumPlayer, numPlayerAtOnce, rand);
- Rounds.Add(combinations.GetNextCombination(null));
-
- for (int i = 1; i < numRounds; i++)
- Rounds.Add(combinations.GetNextCombination(_GetPlayerDemand(i)));
+ List input = new List(numPlayer);
+ for (int i = 0; i < numPlayer; i++)
+ input.Add(i);
+ CCombinations combs = new CCombinations(input, playersPerRound);
+ combinations.AddRange(combs.Select(combination => new CRound(combination)));
+ combinations.Shuffle();
}
- private IEnumerable _GetPlayerDemand(int roundIndex)
+ private static CRound _GetMatchingCombination(List playersInRound, List combinations)
{
- List numPlayed = new List(_NumPlayer);
- for (int i = 0; i < _NumPlayer; i++)
- numPlayed.Add(0);
-
- for (int i = 0; i < roundIndex; i++)
+ foreach (CRound round in combinations)
{
- foreach (int playerIndex in Rounds[i].Player)
- numPlayed[playerIndex]++;
+ int matching = round.Players.Count(playersInRound.Contains);
+ // A valid round contains only players from playersInRound or all players from playersInRound (and some others)
+ if (matching == round.Players.Count || matching == playersInRound.Count)
+ return round;
}
+ Debug.Assert(false, "This should not happen!");
+ return combinations[0];
+ }
- int max = numPlayed.Max();
-
- int num = Rounds[0].Player.Count;
- List result = new List();
- List other = new List();
- List last = new List();
-
- for (int i = 0; i < numPlayed.Count; i++)
+ private void _BuildRounds(int numRounds, int numPlayer, int playersPerRound)
+ {
+ // What we want is that every player sung the same amount of songs
+ // So we keep track how many songs each palyer sung
+ List numSung = new List(numPlayer);
+ for (int i = 0; i < numPlayer; i++)
+ numSung.Add(0);
+ List combinations = new List();
+ // Posibly add more rounds than requested if the song count per player is unequal
+ for (int i = 0; i < numRounds * 10; i++)
{
- if (roundIndex == 0 || numPlayed[i] < max)
- {
- if (roundIndex == 0 || roundIndex > 0 && numPlayed[i] < max && !Rounds[roundIndex - 1].IsAvailable(i))
- result.Add(i);
- else if (numPlayed[i] < max)
- other.Add(i);
- }
- else
- {
- if (roundIndex > 0)
- {
- if (!Rounds[roundIndex - 1].IsAvailable(i))
- other.Add(i);
- else
- last.Add(i);
- }
- else
- last.Add(i);
- }
+ if (combinations.Count == 0)
+ _AddCombinations(numPlayer, playersPerRound, combinations);
+ List playersInRound = _GetPlayersForRound(numSung);
+ CRound curRound = _GetMatchingCombination(playersInRound, combinations);
+ foreach (int player in curRound.Players)
+ numSung[player]++;
+ _Rounds.Add(curRound);
+ //Stop if we have enough rounds and all players sung the same amount of songs
+ if (_Rounds.Count >= numRounds && numSung.All(ct => ct == numSung[0]))
+ break;
}
-
- while (result.Count < num && other.Count > 0)
- {
- int n = other.Count;
- int r = _Rand.Next(n);
- result.Add(other[r]);
- other.RemoveAt(r);
- }
-
- while (result.Count < num)
- {
- int n = last.Count;
- int r = _Rand.Next(n);
- result.Add(last[r]);
- last.RemoveAt(r);
- }
-
- while (result.Count > num)
- {
- int n = result.Count;
- int r = _Rand.Next(n);
- result.RemoveAt(r);
- }
-
- result.Sort();
- return result;
+ if (_Rounds.Count != numRounds)
+ CBase.Log.LogDebug("Number of rounds does not match. Expected: " + numRounds + ", Is: " + _Rounds.Count + " for " + numPlayer + "/" + playersPerRound);
}
}
- class CCombinations
+ public class CRound
{
- private readonly List _Combs;
- private readonly Random _Rand;
- private readonly int _NumPlayer;
- private readonly int _NumMics;
+ public readonly List Players;
- public CCombinations(int numPlayer, int numMics, Random rand)
+ public CRound(List players)
{
- _Combs = new List();
- _NumMics = numMics;
- _NumPlayer = numPlayer;
- _Rand = rand;
- }
-
- public CCombination GetNextCombination(IEnumerable playerNrDemand)
- {
- if (_Combs.Count == 0)
- _Create();
-
- if (_NumPlayer == _NumMics)
- return _Combs[0];
-
- //filter against PlayerNrDemand
- List combsFiltered = new List();
- if (playerNrDemand != null)
- combsFiltered.AddRange(_Combs.Where(t => t.IsAvailableAll(playerNrDemand)));
-
- //1st fallback
- if (playerNrDemand != null && combsFiltered.Count == 0)
- combsFiltered.AddRange(_Combs.Where(t => t.IsAvailableSomeone(playerNrDemand)));
-
- //2nd fallback
- if (combsFiltered.Count == 0)
- combsFiltered.AddRange(_Combs);
-
- int num = combsFiltered.Count;
- int rand = _Rand.Next(num);
- CCombination c = new CCombination();
- for (int i = 0; i < combsFiltered[rand].Player.Count; i++)
- c.Player.Add(combsFiltered[rand].Player[i]);
- _Combs.Remove(combsFiltered[rand]);
-
- return combsFiltered[rand];
- }
-
- private void _Create()
- {
- _Combs.Clear();
-
- int num = (int)Math.Pow(2, _NumPlayer);
-
- for (int i = 1; i <= num; i++)
- {
- CCombination c = new CCombination();
-
- for (int j = 0; j < _NumPlayer; j++)
- {
- if ((i & (1 << j)) > 0)
- c.Player.Add(j);
- }
-
- if (c.Player.Count == _NumMics)
- _Combs.Add(c);
- }
- }
- }
-
- public class CCombination
- {
- public readonly List Player;
-
- public CCombination()
- {
- Player = new List();
- }
-
- public bool IsAvailable(int playerIndex)
- {
- return Player.Any(p => p == playerIndex);
- }
-
- public bool IsAvailableAll(IEnumerable playerIndices)
- {
- return playerIndices.All(IsAvailable);
- }
-
- public bool IsAvailableSomeone(IEnumerable playerIndices)
- {
- return playerIndices.Any(IsAvailable);
+ Players = players.Shuffle();
}
}
}
\ No newline at end of file
diff --git a/PartyModes/PartyModeChallenge/CPartyModeChallenge.cs b/PartyModes/PartyModeChallenge/CPartyModeChallenge.cs
index db882cd4..938bddc6 100644
--- a/PartyModes/PartyModeChallenge/CPartyModeChallenge.cs
+++ b/PartyModes/PartyModeChallenge/CPartyModeChallenge.cs
@@ -67,11 +67,38 @@ namespace VocaluxeLib.PartyModes.Challenge
public sealed class CPartyModeChallenge : CPartyMode
// ReSharper restore ClassNeverInstantiated.Global
{
- private const int _MaxPlayer = 12;
- private const int _MinPlayer = 1;
- private const int _MaxTeams = 0;
- private const int _MinTeams = 0;
- private const int _MaxNumRounds = 100;
+ public override int MinMics
+ {
+ get { return 1; }
+ }
+ public override int MaxMics
+ {
+ get { return CBase.Config.GetMaxNumMics(); }
+ }
+ public override int MinPlayers
+ {
+ get { return 1; }
+ }
+ public override int MaxPlayers
+ {
+ get { return 12; }
+ }
+ public override int MinTeams
+ {
+ get { return 1; }
+ }
+ public override int MaxTeams
+ {
+ get { return 1; }
+ }
+ public override int MinPlayersPerTeam
+ {
+ get { return MinPlayers; }
+ }
+ public override int MaxPlayersPerTeam
+ {
+ get { return MaxPlayers; }
+ }
private enum EStage
{
@@ -108,7 +135,7 @@ namespace VocaluxeLib.PartyModes.Challenge
public SData GameData;
private EStage _Stage;
- public CPartyModeChallenge(int id, string folder) : base(id, folder)
+ public CPartyModeChallenge(int id) : base(id)
{
_ScreenSongOptions.Selection.RandomOnly = false;
_ScreenSongOptions.Selection.PartyMode = true;
@@ -125,6 +152,8 @@ namespace VocaluxeLib.PartyModes.Challenge
public override bool Init()
{
+ if (!base.Init())
+ return false;
_Stage = EStage.Config;
_ScreenSongOptions.Sorting.IgnoreArticles = CBase.Config.GetIgnoreArticles();
@@ -283,31 +312,6 @@ namespace VocaluxeLib.PartyModes.Challenge
_ScreenSongOptions.Sorting.SearchActive = visible;
}
- public override int GetMaxPlayer()
- {
- return _MaxPlayer;
- }
-
- public override int GetMinPlayer()
- {
- return _MinPlayer;
- }
-
- public override int GetMaxTeams()
- {
- return _MaxTeams;
- }
-
- public override int GetMinTeams()
- {
- return _MinTeams;
- }
-
- public override int GetMaxNumRounds()
- {
- return _MaxNumRounds;
- }
-
public override void JokerUsed(int teamNr)
{
if (_ScreenSongOptions.Selection.NumJokers == null)
@@ -337,13 +341,13 @@ namespace VocaluxeLib.PartyModes.Challenge
if (players.Length < GameData.NumPlayerAtOnce)
return;
- CCombination c = GameData.Rounds.GetRound(GameData.CurrentRoundNr - 1);
+ CRound c = GameData.Rounds[GameData.CurrentRoundNr - 1];
for (int i = 0; i < GameData.NumPlayerAtOnce; i++)
{
//try to fill with the right data
if (c != null)
- players[i].ProfileID = GameData.ProfileIDs[c.Player[i]];
+ players[i].ProfileID = GameData.ProfileIDs[c.Players[i]];
else
players[i].ProfileID = -1;
}
@@ -409,15 +413,10 @@ namespace VocaluxeLib.PartyModes.Challenge
}
_ScreenSongOptions.Selection.TeamNames = new string[GameData.NumPlayerAtOnce];
- CCombination c = GameData.Rounds.GetRound(GameData.CurrentRoundNr - 1);
+ CRound c = GameData.Rounds[GameData.CurrentRoundNr - 1];
for (int i = 0; i < GameData.NumPlayerAtOnce; i++)
- {
- if (c != null)
- _ScreenSongOptions.Selection.TeamNames[i] = CBase.Profiles.GetPlayerName(GameData.ProfileIDs[c.Player[i]]);
- else
- _ScreenSongOptions.Selection.TeamNames[i] = "foobar";
- }
+ _ScreenSongOptions.Selection.TeamNames[i] = CBase.Profiles.GetPlayerName(GameData.ProfileIDs[c.Players[i]]);
}
private void _UpdateScores()
diff --git a/PartyModes/PartyModeChallenge/CPartyScreenChallengeConfig.cs b/PartyModes/PartyModeChallenge/CPartyScreenChallengeConfig.cs
index e1ef8456..d1a4747b 100644
--- a/PartyModes/PartyModeChallenge/CPartyScreenChallengeConfig.cs
+++ b/PartyModes/PartyModeChallenge/CPartyScreenChallengeConfig.cs
@@ -15,6 +15,7 @@
// along with Vocaluxe. If not, see .
#endregion
+using System;
using System.Windows.Forms;
namespace VocaluxeLib.PartyModes.Challenge
@@ -35,8 +36,7 @@ namespace VocaluxeLib.PartyModes.Challenge
private const string _ButtonNext = "ButtonNext";
private const string _ButtonBack = "ButtonBack";
- private int _MaxNumMics = 2;
- private int _MaxNumRounds = 100;
+ private const int _MaxNumRounds = 100;
private int _RoundSteps = 1;
public override void Init()
@@ -107,12 +107,6 @@ namespace VocaluxeLib.PartyModes.Challenge
{
base.OnShow();
- _MaxNumMics = CBase.Config.GetMaxNumMics();
- if (_MaxNumMics > 6)
- _MaxNumMics = 6;
-
- _MaxNumRounds = _PartyMode.GetMaxNumRounds();
-
_RebuildSlides();
}
@@ -125,9 +119,9 @@ namespace VocaluxeLib.PartyModes.Challenge
{
// build num player slide (min player ... max player);
_SelectSlides[_SelectSlideNumPlayers].Clear();
- for (int i = _PartyMode.GetMinPlayer(); i <= _PartyMode.GetMaxPlayer(); i++)
+ for (int i = _PartyMode.MinPlayers; i <= _PartyMode.MaxPlayers; i++)
_SelectSlides[_SelectSlideNumPlayers].AddValue(i.ToString());
- _SelectSlides[_SelectSlideNumPlayers].Selection = _PartyMode.GameData.NumPlayer - _PartyMode.GetMinPlayer();
+ _SelectSlides[_SelectSlideNumPlayers].SelectedValue = _PartyMode.GameData.NumPlayer.ToString();
_UpdateMicsAtOnce();
_SetRoundSteps();
@@ -138,8 +132,8 @@ namespace VocaluxeLib.PartyModes.Challenge
{
int player = _PartyMode.GameData.NumPlayer;
int mics = _PartyMode.GameData.NumPlayerAtOnce;
- _PartyMode.GameData.NumPlayer = _SelectSlides[_SelectSlideNumPlayers].Selection + _PartyMode.GetMinPlayer();
- _PartyMode.GameData.NumPlayerAtOnce = _SelectSlides[_SelectSlideNumMics].Selection + _PartyMode.GetMinPlayer();
+ _PartyMode.GameData.NumPlayer = _SelectSlides[_SelectSlideNumPlayers].Selection + _PartyMode.MinPlayers;
+ _PartyMode.GameData.NumPlayerAtOnce = _SelectSlides[_SelectSlideNumMics].Selection + _PartyMode.MinPlayers;
_PartyMode.GameData.NumRounds = (_SelectSlides[_SelectSlideNumRounds].Selection + 1) * _RoundSteps;
_UpdateMicsAtOnce();
@@ -158,9 +152,7 @@ namespace VocaluxeLib.PartyModes.Challenge
private void _UpdateMicsAtOnce()
{
- int maxNum = _MaxNumMics;
- if (_PartyMode.GameData.NumPlayer < _MaxNumMics)
- maxNum = _PartyMode.GameData.NumPlayer;
+ int maxNum = Math.Min(_PartyMode.MaxMics, _PartyMode.GameData.NumPlayer);
if (_PartyMode.GameData.NumPlayerAtOnce > maxNum)
_PartyMode.GameData.NumPlayerAtOnce = maxNum;
@@ -169,7 +161,7 @@ namespace VocaluxeLib.PartyModes.Challenge
_SelectSlides[_SelectSlideNumMics].Clear();
for (int i = 1; i <= maxNum; i++)
_SelectSlides[_SelectSlideNumMics].AddValue(i.ToString());
- _SelectSlides[_SelectSlideNumMics].Selection = _PartyMode.GameData.NumPlayerAtOnce - _PartyMode.GetMinPlayer();
+ _SelectSlides[_SelectSlideNumMics].Selection = _PartyMode.GameData.NumPlayerAtOnce - _PartyMode.MinPlayers;
}
private void _UpdateSlideRounds()
diff --git a/PartyModes/PartyModeChallenge/CPartyScreenChallengeMain.cs b/PartyModes/PartyModeChallenge/CPartyScreenChallengeMain.cs
index 41805118..5e10bcff 100644
--- a/PartyModes/PartyModeChallenge/CPartyScreenChallengeMain.cs
+++ b/PartyModes/PartyModeChallenge/CPartyScreenChallengeMain.cs
@@ -119,7 +119,7 @@ namespace VocaluxeLib.PartyModes.Challenge
_NextPlayerTexts = new List();
_NextPlayerStatics = new List();
- for (int i = 0; i < _PartyMode.GetMaxPlayer(); i++)
+ for (int i = 0; i < _PartyMode.MaxPlayers; i++)
{
_NextPlayerTexts.Add(GetNewText(_Texts[_TextNextPlayer]));
_AddText(_NextPlayerTexts[_NextPlayerTexts.Count - 1]);
@@ -326,7 +326,7 @@ namespace VocaluxeLib.PartyModes.Challenge
x += _Statics[_StaticNextPlayer].Rect.W + 15;
}
- for (int i = _PartyMode.GameData.NumPlayerAtOnce; i < _PartyMode.GetMaxPlayer(); i++)
+ for (int i = _PartyMode.GameData.NumPlayerAtOnce; i < _PartyMode.MaxPlayers; i++)
{
_NextPlayerStatics[i].Visible = false;
_NextPlayerTexts[i].Visible = false;
@@ -340,7 +340,7 @@ namespace VocaluxeLib.PartyModes.Challenge
_Texts[_TextNextPlayerMessage].Visible = true;
for (int i = 0; i < _PartyMode.GameData.NumPlayerAtOnce; i++)
{
- int id = _PartyMode.GameData.ProfileIDs[_PartyMode.GameData.Rounds[_PartyMode.GameData.CurrentRoundNr - 1].Player[i]];
+ int id = _PartyMode.GameData.ProfileIDs[_PartyMode.GameData.Rounds[_PartyMode.GameData.CurrentRoundNr - 1].Players[i]];
_NextPlayerStatics[i].Texture = CBase.Profiles.GetAvatar(id);
_NextPlayerTexts[i].Text = CBase.Profiles.GetPlayerName(id);
_NextPlayerTexts[i].Color = CBase.Themes.GetPlayerColor(i + 1);
@@ -452,14 +452,14 @@ namespace VocaluxeLib.PartyModes.Challenge
{
for (int p = 0; p < _RoundsTable[i].TextPlayer.Count; p++)
{
- if (_PartyMode.GameData.Rounds.Count > i + _RoundsTableOffset && _PartyMode.GameData.Rounds[i + _RoundsTableOffset].Player.Count > p)
+ if (_PartyMode.GameData.Rounds.Count > i + _RoundsTableOffset && _PartyMode.GameData.Rounds[i + _RoundsTableOffset].Players.Count > p)
{
_RoundsTable[i].Number.Visible = true;
_RoundsTable[i].TextPlayer[p].Visible = true;
_RoundsTable[i].TextScores[p].Visible = true;
_RoundsTable[i].Number.Text = (i + 1 + _RoundsTableOffset) + ")";
_RoundsTable[i].TextPlayer[p].Text =
- CBase.Profiles.GetPlayerName(_PartyMode.GameData.ProfileIDs[_PartyMode.GameData.Rounds[i + _RoundsTableOffset].Player[p]]);
+ CBase.Profiles.GetPlayerName(_PartyMode.GameData.ProfileIDs[_PartyMode.GameData.Rounds[i + _RoundsTableOffset].Players[p]]);
// ReSharper disable ConvertIfStatementToConditionalTernaryExpression
if ((_PartyMode.GameData.CurrentRoundNr - 1) > i + _RoundsTableOffset)
// ReSharper restore ConvertIfStatementToConditionalTernaryExpression
diff --git a/PartyModes/PartyModeChallengeMedley/CChallengeRounds.cs b/PartyModes/PartyModeChallengeMedley/CChallengeRounds.cs
index 01b6068e..caa15ccc 100644
--- a/PartyModes/PartyModeChallengeMedley/CChallengeRounds.cs
+++ b/PartyModes/PartyModeChallengeMedley/CChallengeRounds.cs
@@ -17,218 +17,110 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
+using VocaluxeLib.Utils.Combinatorics;
namespace VocaluxeLib.PartyModes.ChallengeMedley
{
public class CChallengeRounds
{
- private readonly Random _Rand;
- private readonly int _NumPlayer;
-
- public readonly List Rounds;
+ private readonly List _Rounds = new List();
public int Count
{
- get { return Rounds.Count; }
+ get { return _Rounds.Count; }
}
- public CCombination this[int index]
+ public CRound this[int index]
{
- get { return Rounds[index]; }
+ get { return _Rounds[index]; }
}
- public CChallengeRounds(int numRounds, int numPlayer, int numPlayerAtOnce)
+ public CChallengeRounds(int numRounds, int numPlayer, int playersPerRound)
{
- Rounds = new List();
- _Rand = new Random(DateTime.Now.Millisecond);
+ if (numRounds < 1 || numPlayer < 1 || playersPerRound < 1)
+ throw new ArgumentException("Invalid paramters for the rounds");
- if (numPlayerAtOnce < 1 || numRounds < 1 || numPlayer == 0)
- _NumPlayer = 0;
- else
- {
- _NumPlayer = numPlayer;
- _BuildRounds(numRounds, numPlayerAtOnce, _Rand);
- }
+ if (playersPerRound > numPlayer)
+ playersPerRound = numPlayer;
+
+ _BuildRounds(numRounds, numPlayer, playersPerRound);
}
- public CCombination GetRound(int roundNr)
+ ///
+ /// Divides players in 2 categories: Those how sung the most and the others
+ ///
+ /// List matching the playerIndex to the number of songs sung
+ private static List _GetPlayersForRound(IList numSung)
{
- if (roundNr >= Rounds.Count || _NumPlayer == 0 || Rounds.Count == 0)
- return null;
-
- return Rounds[roundNr];
+ List mustSing = new List();
+ int max = numSung.Max();
+ for (int i = 0; i < numSung.Count; i++)
+ {
+ if (numSung[i] < max)
+ mustSing.Add(i);
+ }
+ return mustSing;
}
- private void _BuildRounds(int numRounds, int numPlayerAtOnce, Random rand)
+ private static void _AddCombinations(int numPlayer, int playersPerRound, List combinations)
{
- CCombinations combinations = new CCombinations(_NumPlayer, numPlayerAtOnce, rand);
- Rounds.Add(combinations.GetNextCombination(null));
-
- for (int i = 1; i < numRounds; i++)
- Rounds.Add(combinations.GetNextCombination(_GetPlayerDemand(i)));
+ List input = new List(numPlayer);
+ for (int i = 0; i < numPlayer; i++)
+ input.Add(i);
+ CCombinations combs = new CCombinations(input, playersPerRound);
+ combinations.AddRange(combs.Select(combination => new CRound(combination)));
+ combinations.Shuffle();
}
- private IEnumerable _GetPlayerDemand(int roundIndex)
+ private static CRound _GetMatchingCombination(List playersInRound, List combinations)
{
- List numPlayed = new List(_NumPlayer);
- for (int i = 0; i < _NumPlayer; i++)
- numPlayed.Add(0);
-
- for (int i = 0; i < roundIndex; i++)
+ foreach (CRound round in combinations)
{
- foreach (int playerIndex in Rounds[i].Player)
- numPlayed[playerIndex]++;
+ int matching = round.Players.Count(playersInRound.Contains);
+ // A valid round contains only players from playersInRound or all players from playersInRound (and some others)
+ if (matching == round.Players.Count || matching == playersInRound.Count)
+ return round;
}
+ Debug.Assert(false, "This should not happen!");
+ return combinations[0];
+ }
- int max = numPlayed.Max();
-
- int num = Rounds[0].Player.Count;
- List result = new List();
- List other = new List();
- List last = new List();
-
- for (int i = 0; i < numPlayed.Count; i++)
+ private void _BuildRounds(int numRounds, int numPlayer, int playersPerRound)
+ {
+ // What we want is that every player sung the same amount of songs
+ // So we keep track how many songs each palyer sung
+ List numSung = new List(numPlayer);
+ for (int i = 0; i < numPlayer; i++)
+ numSung.Add(0);
+ List combinations = new List();
+ // Posibly add more rounds than requested if the song count per player is unequal
+ for (int i = 0; i < numRounds * 10; i++)
{
- if (roundIndex == 0 || numPlayed[i] < max)
- {
- if (roundIndex == 0 || roundIndex > 0 && numPlayed[i] < max && !Rounds[roundIndex - 1].IsAvailable(i))
- result.Add(i);
- else if (numPlayed[i] < max)
- other.Add(i);
- }
- else
- {
- if (roundIndex > 0)
- {
- if (!Rounds[roundIndex - 1].IsAvailable(i))
- other.Add(i);
- else
- last.Add(i);
- }
- else
- last.Add(i);
- }
+ if (combinations.Count == 0)
+ _AddCombinations(numPlayer, playersPerRound, combinations);
+ List playersInRound = _GetPlayersForRound(numSung);
+ CRound curRound = _GetMatchingCombination(playersInRound, combinations);
+ foreach (int player in curRound.Players)
+ numSung[player]++;
+ _Rounds.Add(curRound);
+ //Stop if we have enough rounds and all players sung the same amount of songs
+ if (_Rounds.Count >= numRounds && numSung.All(ct => ct == numSung[0]))
+ break;
}
-
- while (result.Count < num && other.Count > 0)
- {
- int n = other.Count;
- int r = _Rand.Next(n);
- result.Add(other[r]);
- other.RemoveAt(r);
- }
-
- while (result.Count < num)
- {
- int n = last.Count;
- int r = _Rand.Next(n);
- result.Add(last[r]);
- last.RemoveAt(r);
- }
-
- while (result.Count > num)
- {
- int n = result.Count;
- int r = _Rand.Next(n);
- result.RemoveAt(r);
- }
-
- result.Sort();
- return result;
+ if (_Rounds.Count != numRounds)
+ CBase.Log.LogDebug("Number of rounds does not match. Expected: " + numRounds + ", Is: " + _Rounds.Count + " for " + numPlayer + "/" + playersPerRound);
}
}
- class CCombinations
+ public class CRound
{
- private readonly List _Combs;
- private readonly Random _Rand;
- private readonly int _NumPlayer;
- private readonly int _NumMics;
+ public readonly List Players;
- public CCombinations(int numPlayer, int numMics, Random rand)
+ public CRound(List players)
{
- _Combs = new List();
- _NumMics = numMics;
- _NumPlayer = numPlayer;
- _Rand = rand;
- }
-
- public CCombination GetNextCombination(IEnumerable playerNrDemand)
- {
- if (_Combs.Count == 0)
- _Create();
-
- if (_NumPlayer == _NumMics)
- return _Combs[0];
-
- //filter against PlayerNrDemand
- List combsFiltered = new List();
- if (playerNrDemand != null)
- combsFiltered.AddRange(_Combs.Where(t => t.IsAvailableAll(playerNrDemand)));
-
- //1st fallback
- if (playerNrDemand != null && combsFiltered.Count == 0)
- combsFiltered.AddRange(_Combs.Where(t => t.IsAvailableSomeone(playerNrDemand)));
-
- //2nd fallback
- if (combsFiltered.Count == 0)
- combsFiltered.AddRange(_Combs);
-
- int num = combsFiltered.Count;
- int rand = _Rand.Next(num);
- CCombination c = new CCombination();
- for (int i = 0; i < combsFiltered[rand].Player.Count; i++)
- c.Player.Add(combsFiltered[rand].Player[i]);
- _Combs.Remove(combsFiltered[rand]);
-
- return combsFiltered[rand];
- }
-
- private void _Create()
- {
- _Combs.Clear();
-
- int num = (int)Math.Pow(2, _NumPlayer);
-
- for (int i = 1; i <= num; i++)
- {
- CCombination c = new CCombination();
-
- for (int j = 0; j < _NumPlayer; j++)
- {
- if ((i & (1 << j)) > 0)
- c.Player.Add(j);
- }
-
- if (c.Player.Count == _NumMics)
- _Combs.Add(c);
- }
- }
- }
-
- public class CCombination
- {
- public readonly List Player;
-
- public CCombination()
- {
- Player = new List();
- }
-
- public bool IsAvailable(int playerIndex)
- {
- return Player.Any(p => p == playerIndex);
- }
-
- public bool IsAvailableAll(IEnumerable playerIndices)
- {
- return playerIndices.All(IsAvailable);
- }
-
- public bool IsAvailableSomeone(IEnumerable playerIndices)
- {
- return playerIndices.Any(IsAvailable);
+ Players = players.Shuffle();
}
}
}
\ No newline at end of file
diff --git a/PartyModes/PartyModeChallengeMedley/CPartyModeChallengeMedley.cs b/PartyModes/PartyModeChallengeMedley/CPartyModeChallengeMedley.cs
index ec9429f9..8d433eaf 100644
--- a/PartyModes/PartyModeChallengeMedley/CPartyModeChallengeMedley.cs
+++ b/PartyModes/PartyModeChallengeMedley/CPartyModeChallengeMedley.cs
@@ -72,13 +72,41 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
public sealed class CPartyModeChallengeMedley : CPartyMode
// ReSharper restore ClassNeverInstantiated.Global
{
- private const int _MaxPlayer = 12;
- private const int _MinPlayer = 1;
- private const int _MaxTeams = 0;
- private const int _MinTeams = 0;
- private const int _MaxNumRounds = 100;
private const int _NumSongs = 5;
+ public override int MinMics
+ {
+ get { return 1; }
+ }
+ public override int MaxMics
+ {
+ get { return CBase.Config.GetMaxNumMics(); }
+ }
+ public override int MinPlayers
+ {
+ get { return 1; }
+ }
+ public override int MaxPlayers
+ {
+ get { return 12; }
+ }
+ public override int MinTeams
+ {
+ get { return 1; }
+ }
+ public override int MaxTeams
+ {
+ get { return 1; }
+ }
+ public override int MinPlayersPerTeam
+ {
+ get { return MinPlayers; }
+ }
+ public override int MaxPlayersPerTeam
+ {
+ get { return MaxPlayers; }
+ }
+
private enum EStage
{
Config,
@@ -114,7 +142,7 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
public SData GameData;
private EStage _Stage;
- public CPartyModeChallengeMedley(int id, string folder) : base(id, folder)
+ public CPartyModeChallengeMedley(int id) : base(id)
{
_ScreenSongOptions.Selection.RandomOnly = false;
_ScreenSongOptions.Selection.PartyMode = true;
@@ -131,6 +159,8 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
public override bool Init()
{
+ if (!base.Init())
+ return false;
_Stage = EStage.Config;
_ScreenSongOptions.Sorting.IgnoreArticles = EOffOn.TR_CONFIG_OFF;
@@ -290,31 +320,6 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
_ScreenSongOptions.Sorting.SearchActive = visible;
}
- public override int GetMaxPlayer()
- {
- return _MaxPlayer;
- }
-
- public override int GetMinPlayer()
- {
- return _MinPlayer;
- }
-
- public override int GetMaxTeams()
- {
- return _MaxTeams;
- }
-
- public override int GetMinTeams()
- {
- return _MinTeams;
- }
-
- public override int GetMaxNumRounds()
- {
- return _MaxNumRounds;
- }
-
public override void JokerUsed(int teamNr)
{
if (_ScreenSongOptions.Selection.NumJokers == null)
@@ -361,13 +366,13 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
if (players.Length < GameData.NumPlayerAtOnce)
return false;
- CCombination c = GameData.Rounds.GetRound(GameData.CurrentRoundNr - 1);
+ CRound c = GameData.Rounds[GameData.CurrentRoundNr - 1];
for (int i = 0; i < GameData.NumPlayerAtOnce; i++)
{
//try to fill with the right data
if (c != null)
- players[i].ProfileID = GameData.ProfileIDs[c.Player[i]];
+ players[i].ProfileID = GameData.ProfileIDs[c.Players[i]];
else
players[i].ProfileID = -1;
}
@@ -470,14 +475,14 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
}
_ScreenSongOptions.Selection.TeamNames = new string[GameData.NumPlayerAtOnce];
- CCombination c = GameData.Rounds.GetRound(GameData.CurrentRoundNr - 1);
+ CRound c = GameData.Rounds[GameData.CurrentRoundNr - 1];
for (int i = 0; i < GameData.NumPlayerAtOnce; i++)
{
if (c != null)
{
- if (GameData.ProfileIDs[c.Player[i]] < profiles.Length)
- _ScreenSongOptions.Selection.TeamNames[i] = profiles[GameData.ProfileIDs[c.Player[i]]].PlayerName;
+ if (GameData.ProfileIDs[c.Players[i]] < profiles.Length)
+ _ScreenSongOptions.Selection.TeamNames[i] = profiles[GameData.ProfileIDs[c.Players[i]]].PlayerName;
else
_ScreenSongOptions.Selection.TeamNames[i] = "foobar";
}
diff --git a/PartyModes/PartyModeChallengeMedley/CPartyScreenChallengeMedleyConfig.cs b/PartyModes/PartyModeChallengeMedley/CPartyScreenChallengeMedleyConfig.cs
index 2174939b..dbb80bb6 100644
--- a/PartyModes/PartyModeChallengeMedley/CPartyScreenChallengeMedleyConfig.cs
+++ b/PartyModes/PartyModeChallengeMedley/CPartyScreenChallengeMedleyConfig.cs
@@ -15,6 +15,7 @@
// along with Vocaluxe. If not, see .
#endregion
+using System;
using System.Windows.Forms;
namespace VocaluxeLib.PartyModes.ChallengeMedley
@@ -35,8 +36,7 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
private const string _ButtonNext = "ButtonNext";
private const string _ButtonBack = "ButtonBack";
- private int _MaxNumMics = 2;
- private int _MaxNumRounds = 100;
+ private const int _MaxNumRounds = 100;
private int _RoundSteps = 1;
public override void Init()
@@ -107,12 +107,6 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
{
base.OnShow();
- _MaxNumMics = CBase.Config.GetMaxNumMics();
- if (_MaxNumMics > 6)
- _MaxNumMics = 6;
-
- _MaxNumRounds = _PartyMode.GetMaxNumRounds();
-
_RebuildSlides();
}
@@ -125,9 +119,9 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
{
// build num player slide (min player ... max player);
_SelectSlides[_SelectSlideNumPlayers].Clear();
- for (int i = _PartyMode.GetMinPlayer(); i <= _PartyMode.GetMaxPlayer(); i++)
+ for (int i = _PartyMode.MinPlayers; i <= _PartyMode.MaxPlayers; i++)
_SelectSlides[_SelectSlideNumPlayers].AddValue(i.ToString());
- _SelectSlides[_SelectSlideNumPlayers].Selection = _PartyMode.GameData.NumPlayer - _PartyMode.GetMinPlayer();
+ _SelectSlides[_SelectSlideNumPlayers].Selection = _PartyMode.GameData.NumPlayer - _PartyMode.MinPlayers;
_UpdateMicsAtOnce();
_SetRoundSteps();
@@ -138,8 +132,8 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
{
int player = _PartyMode.GameData.NumPlayer;
int mics = _PartyMode.GameData.NumPlayerAtOnce;
- _PartyMode.GameData.NumPlayer = _SelectSlides[_SelectSlideNumPlayers].Selection + _PartyMode.GetMinPlayer();
- _PartyMode.GameData.NumPlayerAtOnce = _SelectSlides[_SelectSlideNumMics].Selection + _PartyMode.GetMinPlayer();
+ _PartyMode.GameData.NumPlayer = _SelectSlides[_SelectSlideNumPlayers].Selection + _PartyMode.MinPlayers;
+ _PartyMode.GameData.NumPlayerAtOnce = _SelectSlides[_SelectSlideNumMics].Selection + _PartyMode.MinPlayers;
_PartyMode.GameData.NumRounds = (_SelectSlides[_SelectSlideNumRounds].Selection + 1) * _RoundSteps;
_UpdateMicsAtOnce();
@@ -158,9 +152,7 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
private void _UpdateMicsAtOnce()
{
- int maxNum = _MaxNumMics;
- if (_PartyMode.GameData.NumPlayer < _MaxNumMics)
- maxNum = _PartyMode.GameData.NumPlayer;
+ int maxNum = Math.Min(_PartyMode.MaxMics, _PartyMode.GameData.NumPlayer);
if (_PartyMode.GameData.NumPlayerAtOnce > maxNum)
_PartyMode.GameData.NumPlayerAtOnce = maxNum;
@@ -169,7 +161,7 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
_SelectSlides[_SelectSlideNumMics].Clear();
for (int i = 1; i <= maxNum; i++)
_SelectSlides[_SelectSlideNumMics].AddValue(i.ToString());
- _SelectSlides[_SelectSlideNumMics].Selection = _PartyMode.GameData.NumPlayerAtOnce - _PartyMode.GetMinPlayer();
+ _SelectSlides[_SelectSlideNumMics].Selection = _PartyMode.GameData.NumPlayerAtOnce - _PartyMode.MinPlayers;
}
private void _UpdateSlideRounds()
diff --git a/PartyModes/PartyModeChallengeMedley/CPartyScreenChallengeMedleyMain.cs b/PartyModes/PartyModeChallengeMedley/CPartyScreenChallengeMedleyMain.cs
index 84831c23..8e2841b1 100644
--- a/PartyModes/PartyModeChallengeMedley/CPartyScreenChallengeMedleyMain.cs
+++ b/PartyModes/PartyModeChallengeMedley/CPartyScreenChallengeMedleyMain.cs
@@ -119,7 +119,7 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
_NextPlayerTexts = new List();
_NextPlayerStatics = new List();
- for (int i = 0; i < _PartyMode.GetMaxPlayer(); i++)
+ for (int i = 0; i < _PartyMode.MaxPlayers; i++)
{
_NextPlayerTexts.Add(GetNewText(_Texts[_TextNextPlayer]));
_AddText(_NextPlayerTexts[_NextPlayerTexts.Count - 1]);
@@ -326,7 +326,7 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
x += _Statics[_StaticNextPlayer].Rect.W + 15;
}
- for (int i = _PartyMode.GameData.NumPlayerAtOnce; i < _PartyMode.GetMaxPlayer(); i++)
+ for (int i = _PartyMode.GameData.NumPlayerAtOnce; i < _PartyMode.MaxPlayers; i++)
{
_NextPlayerStatics[i].Visible = false;
_NextPlayerTexts[i].Visible = false;
@@ -340,7 +340,7 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
_Texts[_TextNextPlayerMessage].Visible = true;
for (int i = 0; i < _PartyMode.GameData.NumPlayerAtOnce; i++)
{
- int id = _PartyMode.GameData.ProfileIDs[_PartyMode.GameData.Rounds[_PartyMode.GameData.CurrentRoundNr - 1].Player[i]];
+ int id = _PartyMode.GameData.ProfileIDs[_PartyMode.GameData.Rounds[_PartyMode.GameData.CurrentRoundNr - 1].Players[i]];
_NextPlayerStatics[i].Texture = CBase.Profiles.GetAvatar(id);
_NextPlayerTexts[i].Text = CBase.Profiles.GetPlayerName(id);
_NextPlayerTexts[i].Color = CBase.Themes.GetPlayerColor(i + 1);
@@ -452,14 +452,14 @@ namespace VocaluxeLib.PartyModes.ChallengeMedley
{
for (int p = 0; p < _RoundsTable[i].TextPlayer.Count; p++)
{
- if (_PartyMode.GameData.Rounds.Count > i + _RoundsTableOffset && _PartyMode.GameData.Rounds[i + _RoundsTableOffset].Player.Count > p)
+ if (_PartyMode.GameData.Rounds.Count > i + _RoundsTableOffset && _PartyMode.GameData.Rounds[i + _RoundsTableOffset].Players.Count > p)
{
_RoundsTable[i].Number.Visible = true;
_RoundsTable[i].TextPlayer[p].Visible = true;
_RoundsTable[i].TextScores[p].Visible = true;
_RoundsTable[i].Number.Text = (i + 1 + _RoundsTableOffset) + ")";
_RoundsTable[i].TextPlayer[p].Text =
- CBase.Profiles.GetPlayerName(_PartyMode.GameData.ProfileIDs[_PartyMode.GameData.Rounds[i + _RoundsTableOffset].Player[p]]);
+ CBase.Profiles.GetPlayerName(_PartyMode.GameData.ProfileIDs[_PartyMode.GameData.Rounds[i + _RoundsTableOffset].Players[p]]);
// ReSharper disable ConvertIfStatementToConditionalTernaryExpression
if ((_PartyMode.GameData.CurrentRoundNr - 1) > i + _RoundsTableOffset)
// ReSharper restore ConvertIfStatementToConditionalTernaryExpression
diff --git a/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs b/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs
index 1dadbaea..81d3c308 100644
--- a/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs
+++ b/PartyModes/PartyModeTicTacToe/CPartyModeTicTacToe.cs
@@ -36,15 +36,6 @@ namespace VocaluxeLib.PartyModes.TicTacToe
// ReSharper restore InconsistentNaming
}
- public enum EPartyGameMode
- {
- // ReSharper disable InconsistentNaming
- TR_GAMEMODE_NORMAL,
- TR_GAMEMODE_SHORTSONG,
- TR_GAMEMODE_DUET
- // ReSharper restore InconsistentNaming
- }
-
public class CRound
{
public int SongID;
@@ -71,13 +62,39 @@ namespace VocaluxeLib.PartyModes.TicTacToe
public sealed class CPartyModeTicTacToe : CPartyMode
// ReSharper restore ClassNeverInstantiated.Global
{
- private const int _MaxPlayer = 20;
- private const int _MinPlayer = 2;
- private const int _MaxTeams = 2;
- private const int _MinTeams = 2;
- private const int _MinPlayerPerTeam = 1;
- private const int _MaxPlayerPerTeam = 10;
- private const int _NumFields = 9;
+ public override int MinMics
+ {
+ get { return 2; }
+ }
+ public override int MaxMics
+ {
+ get { return 2; }
+ }
+ public override int MinPlayers
+ {
+ get { return 2; }
+ }
+ public override int MaxPlayers
+ {
+ get { return 20; }
+ }
+ public override int MinTeams
+ {
+ get { return 2; }
+ }
+ public override int MaxTeams
+ {
+ get { return 2; }
+ }
+
+ public override int MinPlayersPerTeam
+ {
+ get { return 1; }
+ }
+ public override int MaxPlayersPerTeam
+ {
+ get { return 10; }
+ }
private enum EStage
{
@@ -99,10 +116,10 @@ namespace VocaluxeLib.PartyModes.TicTacToe
public List PlayerTeam2;
public ESongSource SongSource;
- public int CategoryID;
+ public int CategoryIndex;
public int PlaylistID;
- public EPartyGameMode GameMode;
+ public EGameMode GameMode;
public List Rounds;
public List Songs;
@@ -117,7 +134,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
public SData GameData;
private EStage _Stage;
- public CPartyModeTicTacToe(int id, string folder) : base(id, folder)
+ public CPartyModeTicTacToe(int id) : base(id)
{
_ScreenSongOptions.Selection.RandomOnly = false;
_ScreenSongOptions.Selection.PartyMode = true;
@@ -142,8 +159,8 @@ namespace VocaluxeLib.PartyModes.TicTacToe
FieldNr = 0,
SongSource = ESongSource.TR_ALLSONGS,
PlaylistID = 0,
- CategoryID = 0,
- GameMode = EPartyGameMode.TR_GAMEMODE_NORMAL,
+ CategoryIndex = 0,
+ GameMode = EGameMode.TR_GAMEMODE_NORMAL,
Rounds = new List(),
Songs = new List(),
NumJokerRandom = new int[2],
@@ -153,6 +170,8 @@ namespace VocaluxeLib.PartyModes.TicTacToe
public override bool Init()
{
+ if (!base.Init())
+ return false;
_Stage = EStage.Config;
_ScreenSongOptions.Sorting.IgnoreArticles = CBase.Config.GetIgnoreArticles();
@@ -277,41 +296,6 @@ namespace VocaluxeLib.PartyModes.TicTacToe
throw new ArgumentException("Not required!");
}
- public override int GetMaxPlayer()
- {
- return _MaxPlayer;
- }
-
- public override int GetMinPlayer()
- {
- return _MinPlayer;
- }
-
- public override int GetMaxTeams()
- {
- return _MaxTeams;
- }
-
- public override int GetMinTeams()
- {
- return _MinTeams;
- }
-
- public override int GetMinPlayerPerTeam()
- {
- return _MinPlayerPerTeam;
- }
-
- public override int GetMaxPlayerPerTeam()
- {
- return _MaxPlayerPerTeam;
- }
-
- public override int GetMaxNumRounds()
- {
- return _NumFields;
- }
-
public override void JokerUsed(int teamNr) {}
public override void SongSelected(int songID)
@@ -431,67 +415,36 @@ namespace VocaluxeLib.PartyModes.TicTacToe
}
}
- private static void _Shuffle(IList list)
- {
- for (int n = list.Count - 1; n >= 1; n--)
- {
- int k = CBase.Game.GetRandom(n);
- T value = list[k];
- list[k] = list[n];
- list[n] = value;
- }
- }
-
public void UpdateSongList()
{
if (GameData.Songs.Count > 0)
return;
- EGameMode gm;
- switch (GameData.GameMode)
- {
- case EPartyGameMode.TR_GAMEMODE_NORMAL:
- gm = EGameMode.TR_GAMEMODE_NORMAL;
- break;
-
- case EPartyGameMode.TR_GAMEMODE_DUET:
- gm = EGameMode.TR_GAMEMODE_DUET;
- break;
-
- case EPartyGameMode.TR_GAMEMODE_SHORTSONG:
- gm = EGameMode.TR_GAMEMODE_SHORTSONG;
- break;
-
- default:
- gm = EGameMode.TR_GAMEMODE_NORMAL;
- break;
- }
-
switch (GameData.SongSource)
{
case ESongSource.TR_PLAYLIST:
for (int i = 0; i < CBase.Playlist.GetSongCount(GameData.PlaylistID); i++)
{
int id = CBase.Playlist.GetSong(GameData.PlaylistID, i).SongID;
- if (CBase.Songs.GetSongByID(id).AvailableGameModes.Contains(gm))
+ if (CBase.Songs.GetSongByID(id).AvailableGameModes.Contains(GameData.GameMode))
GameData.Songs.Add(id);
}
break;
case ESongSource.TR_ALLSONGS:
ReadOnlyCollection avSongs = CBase.Songs.GetSongs();
- GameData.Songs.AddRange(avSongs.Where(song => song.AvailableGameModes.Contains(gm)).Select(song => song.ID));
+ GameData.Songs.AddRange(avSongs.Where(song => song.AvailableGameModes.Contains(GameData.GameMode)).Select(song => song.ID));
break;
case ESongSource.TR_CATEGORY:
- CBase.Songs.SetCategory(GameData.CategoryID);
+ CBase.Songs.SetCategory(GameData.CategoryIndex);
avSongs = CBase.Songs.GetVisibleSongs();
- GameData.Songs.AddRange(avSongs.Where(song => song.AvailableGameModes.Contains(gm)).Select(song => song.ID));
+ GameData.Songs.AddRange(avSongs.Where(song => song.AvailableGameModes.Contains(GameData.GameMode)).Select(song => song.ID));
CBase.Songs.SetCategory(-1);
break;
}
- _Shuffle(GameData.Songs);
+ GameData.Songs.Shuffle();
}
private void _UpdatePlayerList()
@@ -534,23 +487,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
if (isDuet)
players[1].VoiceNr = 1;
- var gm = EGameMode.TR_GAMEMODE_NORMAL;
-
- switch (GameData.GameMode)
- {
- case EPartyGameMode.TR_GAMEMODE_NORMAL:
- gm = EGameMode.TR_GAMEMODE_NORMAL;
- break;
-
- case EPartyGameMode.TR_GAMEMODE_DUET:
- gm = EGameMode.TR_GAMEMODE_DUET;
- break;
-
- case EPartyGameMode.TR_GAMEMODE_SHORTSONG:
- gm = EGameMode.TR_GAMEMODE_SHORTSONG;
- break;
- }
- CBase.Game.AddSong(round.SongID, gm);
+ CBase.Game.AddSong(round.SongID, GameData.GameMode);
}
private void _SetNumJokers()
diff --git a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs
index 2986c303..c75cd880 100644
--- a/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs
+++ b/PartyModes/PartyModeTicTacToe/CPartyScreenTicTacToeConfig.cs
@@ -16,6 +16,7 @@
#endregion
using System.Collections.Generic;
+using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;
using VocaluxeLib.Songs;
@@ -113,8 +114,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
{
base.OnShow();
- if (CBase.Config.GetMaxNumMics() >= 2)
- _ConfigOk = true;
+ Debug.Assert(CBase.Config.GetMaxNumMics() >= 2);
_FillSlides();
_UpdateSlides();
@@ -129,15 +129,11 @@ namespace VocaluxeLib.PartyModes.TicTacToe
private void _FillSlides()
{
_SelectSlides[_SelectSlideNumFields].Clear();
- _SelectSlides[_SelectSlideNumFields].AddValue("9");
- _SelectSlides[_SelectSlideNumFields].AddValue("16");
- _SelectSlides[_SelectSlideNumFields].AddValue("25");
- if (_PartyMode.GameData.NumFields == 9)
- _SelectSlides[_SelectSlideNumFields].Selection = 0;
- else if (_PartyMode.GameData.NumFields == 16)
- _SelectSlides[_SelectSlideNumFields].Selection = 1;
- else if (_PartyMode.GameData.NumFields == 25)
- _SelectSlides[_SelectSlideNumFields].Selection = 2;
+ _SelectSlides[_SelectSlideNumFields].AddValue(9);
+ _SelectSlides[_SelectSlideNumFields].AddValue(16);
+ _SelectSlides[_SelectSlideNumFields].AddValue(25);
+
+ _SelectSlides[_SelectSlideNumFields].SelectedTag = _PartyMode.GameData.NumFields;
_SelectSlides[_SelectSlideSongSource].Clear();
_SelectSlides[_SelectSlideSongSource].SetValues((int)_PartyMode.GameData.SongSource);
@@ -152,52 +148,32 @@ namespace VocaluxeLib.PartyModes.TicTacToe
_SelectSlides[_SelectSlidePlaylist].Selection = _PartyMode.GameData.PlaylistID;
_SelectSlides[_SelectSlidePlaylist].Visible = _PartyMode.GameData.SongSource == ESongSource.TR_PLAYLIST;
- var categories = new string[CBase.Songs.GetNumCategories()];
- for (int i = 0; i < CBase.Songs.GetNumCategories(); i++)
- categories[i] = CBase.Songs.GetCategory(i).Name;
_SelectSlides[_SelectSlideCategory].Clear();
- for (int i = 0; i < categories.Length; i++)
+ for (int i = 0; i < CBase.Songs.GetNumCategories(); i++)
{
- string value = categories[i] + " (" + CBase.Songs.GetNumSongsNotSungInCategory(i) + " " + CBase.Language.Translate("TR_SONGS", PartyModeID) + ")";
+ CCategory cat = CBase.Songs.GetCategory(i);
+ string value = cat.Name + " (" + cat.GetNumSongsNotSung() + " " + CBase.Language.Translate("TR_SONGS", PartyModeID) + ")";
_SelectSlides[_SelectSlideCategory].AddValue(value);
}
- _SelectSlides[_SelectSlideCategory].Selection = _PartyMode.GameData.CategoryID;
+ _SelectSlides[_SelectSlideCategory].Selection = _PartyMode.GameData.CategoryIndex;
_SelectSlides[_SelectSlideCategory].Visible = _PartyMode.GameData.SongSource == ESongSource.TR_CATEGORY;
_SelectSlides[_SelectSlideGameMode].Visible = true;
- _SelectSlides[_SelectSlideGameMode].SetValues((int)_PartyMode.GameData.GameMode);
+ _SelectSlides[_SelectSlideGameMode].Clear();
+ _SelectSlides[_SelectSlideGameMode].SetValues((int)_PartyMode.GameData.GameMode);
+ _SelectSlides[_SelectSlideGameMode].RemoveValue(EGameMode.TR_GAMEMODE_MEDLEY.ToString());
}
private void _UpdateSlides()
{
- if (_SelectSlides[_SelectSlideNumFields].Selection == 0)
- _PartyMode.GameData.NumFields = 9;
- else if (_SelectSlides[_SelectSlideNumFields].Selection == 1)
- _PartyMode.GameData.NumFields = 16;
- else if (_SelectSlides[_SelectSlideNumFields].Selection == 2)
- _PartyMode.GameData.NumFields = 25;
+ _PartyMode.GameData.NumFields = _SelectSlides[_SelectSlideNumFields].SelectedTag;
_PartyMode.GameData.SongSource = (ESongSource)_SelectSlides[_SelectSlideSongSource].Selection;
_PartyMode.GameData.PlaylistID = _SelectSlides[_SelectSlidePlaylist].Selection;
- _PartyMode.GameData.CategoryID = _SelectSlides[_SelectSlideCategory].Selection;
- _PartyMode.GameData.GameMode = (EPartyGameMode)_SelectSlides[_SelectSlideGameMode].Selection;
+ _PartyMode.GameData.CategoryIndex = _SelectSlides[_SelectSlideCategory].Selection;
+ _PartyMode.GameData.GameMode = (EGameMode)_SelectSlides[_SelectSlideGameMode].Selection;
- var gm = EGameMode.TR_GAMEMODE_NORMAL;
-
- switch (_PartyMode.GameData.GameMode)
- {
- case EPartyGameMode.TR_GAMEMODE_NORMAL:
- gm = EGameMode.TR_GAMEMODE_NORMAL;
- break;
-
- case EPartyGameMode.TR_GAMEMODE_DUET:
- gm = EGameMode.TR_GAMEMODE_DUET;
- break;
-
- case EPartyGameMode.TR_GAMEMODE_SHORTSONG:
- gm = EGameMode.TR_GAMEMODE_SHORTSONG;
- break;
- }
+ EGameMode gm = _PartyMode.GameData.GameMode;
if (_PartyMode.GameData.SongSource == ESongSource.TR_PLAYLIST)
{
@@ -224,11 +200,11 @@ namespace VocaluxeLib.PartyModes.TicTacToe
{
if (CBase.Songs.GetNumCategories() == 0)
_ConfigOk = false;
- else if (CBase.Songs.GetNumSongsNotSungInCategory(_PartyMode.GameData.CategoryID) <= 0)
+ else if (CBase.Songs.GetNumSongsNotSungInCategory(_PartyMode.GameData.CategoryIndex) <= 0)
_ConfigOk = false;
else
{
- CBase.Songs.SetCategory(_PartyMode.GameData.CategoryID);
+ CBase.Songs.SetCategory(_PartyMode.GameData.CategoryIndex);
_ConfigOk = false;
foreach (CSong song in CBase.Songs.GetVisibleSongs())
{
diff --git a/Vocaluxe/Base/CCover.cs b/Vocaluxe/Base/CCover.cs
index fb621f16..0a155740 100644
--- a/Vocaluxe/Base/CCover.cs
+++ b/Vocaluxe/Base/CCover.cs
@@ -17,6 +17,7 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Threading;
@@ -40,10 +41,10 @@ namespace Vocaluxe.Base
public static CTextureRef NoCover { get; private set; }
- public static void Init()
+ public static bool Init()
{
_LoadCoverThemes();
- _LoadCovers(CConfig.Config.Theme.CoverTheme);
+ return _CoverThemes.Count != 0 && _LoadCovers();
}
public static void Close()
@@ -91,7 +92,10 @@ namespace Vocaluxe.Base
public static CTextureRef GenerateCover(string text, ECoverGeneratorType type, CSong firstSong)
{
- CTextureRef texture = CDraw.CopyTexture(NoCover);
+ CTextureRef texture = Cover(text);
+ if (texture != NoCover)
+ return texture;
+ texture = CDraw.CopyTexture(NoCover);
Task.Factory.StartNew(() =>
{
_CancelToken.Token.ThrowIfCancellationRequested();
@@ -127,7 +131,7 @@ namespace Vocaluxe.Base
public static void ReloadCovers()
{
_UnloadCovers();
- _LoadCovers(CConfig.Config.Theme.CoverTheme);
+ _LoadCovers();
}
private static void _UnloadCovers()
@@ -150,14 +154,15 @@ namespace Vocaluxe.Base
///
/// Returns a SCoverTheme by cover-theme-name
///
- private static SThemeCover _CoverTheme(string coverThemeName)
+ private static SThemeCover _GetCoverTheme()
{
- for (int i = 0; i < _CoverThemes.Count; i++)
+ int index = GetCoverThemeIndex();
+ if (index < 0)
{
- if (_CoverThemes[i].Info.Name == coverThemeName)
- return _CoverThemes[i];
+ index = 0;
+ CConfig.Config.Theme.CoverTheme = _CoverThemes[0].Info.Name;
}
- return new SThemeCover();
+ return _CoverThemes[index];
}
///
@@ -184,7 +189,7 @@ namespace Vocaluxe.Base
continue;
}
- if (theme.Info.Folder != "" && theme.Info.Name != "")
+ if (!String.IsNullOrEmpty(theme.Info.Folder) && !String.IsNullOrEmpty(theme.Info.Name))
{
theme.FolderPath = Path.Combine(folderPath, theme.Info.Folder);
_CoverThemes.Add(theme);
@@ -195,12 +200,11 @@ namespace Vocaluxe.Base
///
/// Loads all covers from the theme
///
- private static void _LoadCovers(string coverThemeName)
+ private static bool _LoadCovers()
{
- SThemeCover coverTheme = _CoverTheme(coverThemeName);
+ SThemeCover coverTheme = _GetCoverTheme();
- if (String.IsNullOrEmpty(coverTheme.Info.Name))
- return;
+ Debug.Assert(!String.IsNullOrEmpty(coverTheme.Info.Name));
List files = CHelper.ListImageFiles(coverTheme.FolderPath, true, true);
@@ -213,9 +217,16 @@ namespace Vocaluxe.Base
else if (_CoverExists(_NoCoverNameAlt))
NoCover = _Covers[_NoCoverNameAlt];
else
- CBase.Log.LogError("Covertheme \"" + coverThemeName + "\" does not include a cover file named \"" + _NoCoverName + "\" and cannot be used!", true, true);
+ {
+ CBase.Log.LogError("Covertheme \"" + coverTheme.Info.Name + "\" does not include a cover file named \"" + _NoCoverName + "\" and cannot be used!", true, true);
+ _UnloadCovers();
+ // Remove current theme and recursively try the other themes
+ _CoverThemes.Remove(coverTheme);
+ return _CoverThemes.Count > 0 && _LoadCovers();
+ }
}
_LoadCoverGenerators(coverTheme);
+ return true;
}
public static ECoverGeneratorType _SongSortingToType(ESongSorting sorting)
diff --git a/Vocaluxe/Base/CDataBase.cs b/Vocaluxe/Base/CDataBase.cs
index a3e6397d..fad913e8 100644
--- a/Vocaluxe/Base/CDataBase.cs
+++ b/Vocaluxe/Base/CDataBase.cs
@@ -75,37 +75,46 @@ namespace Vocaluxe.Base
public static bool GetDataBaseSongInfos(string artist, string title, out int numPlayed, out DateTime dateAdded, out int highscoreID)
{
+ if (_HighscoreDB == null)
+ {
+ numPlayed = 0;
+ dateAdded = new DateTime();
+ highscoreID = 0;
+ return false;
+ }
return _HighscoreDB.GetDataBaseSongInfos(artist, title, out numPlayed, out dateAdded, out highscoreID);
}
public static List LoadScore(int songID, EGameMode gameMode)
{
- return _HighscoreDB.LoadScore(songID, gameMode);
+ return _HighscoreDB == null ? null : _HighscoreDB.LoadScore(songID, gameMode);
}
public static int AddScore(SPlayer player)
{
- return _HighscoreDB.AddScore(player);
+ return _HighscoreDB == null ? -1 : _HighscoreDB.AddScore(player);
}
public static void IncreaseSongCounter(int dataBaseSongID)
{
- _HighscoreDB.IncreaseSongCounter(dataBaseSongID);
+ if (_HighscoreDB != null)
+ _HighscoreDB.IncreaseSongCounter(dataBaseSongID);
}
public static bool GetCover(string fileName, ref CTextureRef tex, int maxSize)
{
- return _CoverDB.GetCover(fileName, ref tex, maxSize);
+ return _CoverDB != null && _CoverDB.GetCover(fileName, ref tex, maxSize);
}
public static void CommitCovers()
{
- _CoverDB.CommitCovers();
+ if (_CoverDB != null)
+ _CoverDB.CommitCovers();
}
public static bool GetCreditsRessource(string fileName, ref CTextureRef tex)
{
- return _ResourceDB.GetCreditsRessource(fileName, ref tex);
+ return _ResourceDB != null && _ResourceDB.GetCreditsRessource(fileName, ref tex);
}
}
}
\ No newline at end of file
diff --git a/Vocaluxe/Base/CParty.cs b/Vocaluxe/Base/CParty.cs
index 6408281b..28847a28 100644
--- a/Vocaluxe/Base/CParty.cs
+++ b/Vocaluxe/Base/CParty.cs
@@ -18,6 +18,7 @@
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
+using System.Diagnostics;
using System.IO;
using System.Reflection;
using Vocaluxe.Base.ThemeSystem;
@@ -32,40 +33,52 @@ namespace Vocaluxe.Base
{
private const int _PartyModeSystemVersion = 1;
- private static Dictionary _PartyModes;
+ private static readonly Dictionary _PartyModes = new Dictionary();
private static int _NextID;
-
- private static int _NormalGameModeID;
- private static SPartyMode _CurrentPartyMode;
+ private static IPartyMode _CurrentPartyMode;
#region public stuff
- public static void Init()
+ public static bool Init()
{
- _PartyModes = new Dictionary();
- _NextID = 0;
-
- //add dummy normal game mode and set it as default
- var pm = new SPartyMode {ScreenFiles = new List(), PartyMode = new CPartyModeNone(_NextID++, null)};
- _NormalGameModeID = pm.PartyMode.ID;
- _PartyModes.Add(pm.PartyMode.ID, pm);
- _CurrentPartyMode = pm;
+ if (_PartyModes.Count > 0)
+ return false; //Already initialized
+ SPartyMode pm = new SPartyMode
+ {
+ Info = new SPartyModeInfos {Author = "Vocaluxe Team", Description = "Normal game", Name = "Normal", TargetAudience = "Just a normal game for everyone"},
+ PartyMode = new CPartyModeNormal(-1),
+ PartyModeSystemVersion = _PartyModeSystemVersion,
+ ScreenFiles = new List()
+ };
+ _PartyModes.Add(-1, pm);
+ _CurrentPartyMode = pm.PartyMode;
+ Debug.Assert(_CurrentPartyMode != null && _CurrentPartyMode.ID == -1);
//load other party modes
_LoadPartyModes();
+ return _CurrentPartyMode.Init();
}
public static int CurrentPartyModeID
{
- get
+ get { return _CurrentPartyMode.ID; }
+ set
{
- if (_CurrentPartyMode.PartyMode.ID != _NormalGameModeID)
- return _CurrentPartyMode.PartyMode.ID;
-
- return -1;
+ if (_CurrentPartyMode.ID == value)
+ return;
+ if (value != -1 && !_PartyModes.ContainsKey(value))
+ throw new ArgumentException("Partymode with ID=" + value + " does not exist!");
+ IPartyMode pm = _PartyModes[value].PartyMode;
+ if (pm.Init())
+ _CurrentPartyMode = pm;
+ else
+ {
+ CLog.LogError("Could not init PartyMode \"" + _PartyModes[value].Info.Name + "\"! Removing...", true);
+ _PartyModes.Remove(value);
+ }
}
}
- public static int NumModes
+ public static int Count
{
get { return _PartyModes.Count; }
}
@@ -90,85 +103,81 @@ namespace Vocaluxe.Base
public static List GetPartyModeInfos()
{
- var infos = new List();
-
- foreach (KeyValuePair kvp in _PartyModes)
+ List list = new List();
+ foreach (SPartyMode pm in _PartyModes.Values)
{
- if (kvp.Key != _NormalGameModeID)
- infos.Add(kvp.Value.Info);
+ if (pm.PartyMode.ID >= 0)
+ list.Add(pm.Info);
}
- return infos;
+ return list;
}
public static void SetNormalGameMode()
{
CSongs.ResetPartySongSung();
- SetPartyMode(_NormalGameModeID);
+ CurrentPartyModeID = -1;
}
public static void SetPartyMode(int partyModeID)
{
- if (!_PartyModes.TryGetValue(partyModeID, out _CurrentPartyMode))
- CLog.LogError("CParty: Can't find party mode ID: " + partyModeID);
-
- _CurrentPartyMode.PartyMode.Init();
+ CurrentPartyModeID = partyModeID;
}
#endregion public stuff
#region Interface
public static void UpdateGame()
{
- _CurrentPartyMode.PartyMode.UpdateGame();
+ _CurrentPartyMode.UpdateGame();
}
public static IMenu GetStartScreen()
{
- return _CurrentPartyMode.PartyMode.GetStartScreen();
+ return _CurrentPartyMode.GetStartScreen();
}
public static SScreenSongOptions GetSongSelectionOptions()
{
- return _CurrentPartyMode.PartyMode.GetScreenSongOptions();
+ return _CurrentPartyMode.GetScreenSongOptions();
}
public static void OnSongChange(int songIndex, ref SScreenSongOptions screenSongOptions)
{
- _CurrentPartyMode.PartyMode.OnSongChange(songIndex, ref screenSongOptions);
+ _CurrentPartyMode.OnSongChange(songIndex, ref screenSongOptions);
}
public static void OnCategoryChange(int categoryIndex, ref SScreenSongOptions screenSongOptions)
{
- _CurrentPartyMode.PartyMode.OnCategoryChange(categoryIndex, ref screenSongOptions);
+ _CurrentPartyMode.OnCategoryChange(categoryIndex, ref screenSongOptions);
}
public static void SetSearchString(string searchString, bool visible)
{
- _CurrentPartyMode.PartyMode.SetSearchString(searchString, visible);
+ _CurrentPartyMode.SetSearchString(searchString, visible);
}
public static void JokerUsed(int teamNr)
{
- _CurrentPartyMode.PartyMode.JokerUsed(teamNr);
+ _CurrentPartyMode.JokerUsed(teamNr);
}
public static void SongSelected(int songID)
{
- _CurrentPartyMode.PartyMode.SongSelected(songID);
+ _CurrentPartyMode.SongSelected(songID);
}
public static void FinishedSinging()
{
- _CurrentPartyMode.PartyMode.FinishedSinging();
+ _CurrentPartyMode.FinishedSinging();
}
public static void LeavingScore()
{
- _CurrentPartyMode.PartyMode.LeavingScore();
+ _CurrentPartyMode.LeavingScore();
}
public static void LeavingHighscore()
{
- _CurrentPartyMode.PartyMode.LeavingHighscore();
+ _CurrentPartyMode.LeavingHighscore();
}
#endregion Interface
@@ -216,7 +225,7 @@ namespace Vocaluxe.Base
return false;
object instance = output.CreateInstance(typeof(IPartyMode).Namespace + "." + pm.Info.Folder + "." + pm.Info.PartyModeFile, false,
- BindingFlags.Public | BindingFlags.Instance, null, new object[] {_NextID++, pathToPm}, null, null);
+ BindingFlags.Public | BindingFlags.Instance, null, new object[] {_NextID++}, null, null);
if (instance == null)
{
CLog.LogError("Error creating Instance of PartyMode file: " + filePath);
@@ -258,7 +267,7 @@ namespace Vocaluxe.Base
return false;
}
pm.PartyMode.LoadTheme();
- pm.Info.LoadData(pm.PartyMode);
+ pm.Info.ExtInfo = pm.PartyMode;
return true;
}
@@ -269,6 +278,7 @@ namespace Vocaluxe.Base
var compilerParams = new CompilerParameters();
compilerParams.ReferencedAssemblies.Add("System.Windows.Forms.dll");
+ compilerParams.ReferencedAssemblies.Add("System.dll");
compilerParams.ReferencedAssemblies.Add("System.Core.dll");
compilerParams.ReferencedAssemblies.Add("VocaluxeLib.dll");
compilerParams.GenerateInMemory = true;
diff --git a/Vocaluxe/Base/XmlStructs.cs b/Vocaluxe/Base/XmlStructs.cs
index e9ee97d2..12046975 100644
--- a/Vocaluxe/Base/XmlStructs.cs
+++ b/Vocaluxe/Base/XmlStructs.cs
@@ -17,6 +17,7 @@
using System.Collections.Generic;
using System.ComponentModel;
+using System.Diagnostics;
using System.Xml.Serialization;
using Vocaluxe.Base.Fonts;
using VocaluxeLib;
@@ -121,17 +122,7 @@ namespace Vocaluxe.Base
[XmlAltName("PartyModeVersionMajor")] public int VersionMajor;
[XmlAltName("PartyModeVersionMinor")] public int VersionMinor;
public string TargetAudience;
- [XmlIgnore] public int MaxPlayers, MinPlayers, MaxTeams, MinTeams;
- [XmlIgnore] public int PartyModeID;
-
- public void LoadData(IPartyMode pm)
- {
- MaxPlayers = pm.GetMaxPlayer();
- MinPlayers = pm.GetMinPlayer();
- MaxTeams = pm.GetMaxTeams();
- MinTeams = pm.GetMinTeams();
- PartyModeID = pm.ID;
- }
+ [XmlIgnore] public IPartyModeInfo ExtInfo;
}
struct SPartyMode
diff --git a/Vocaluxe/Lib/Sound/Playback/GstreamerSharp/CGstreamerSharpAudioStream.cs b/Vocaluxe/Lib/Sound/Playback/GstreamerSharp/CGstreamerSharpAudioStream.cs
index ca0d602d..c66ba54b 100644
--- a/Vocaluxe/Lib/Sound/Playback/GstreamerSharp/CGstreamerSharpAudioStream.cs
+++ b/Vocaluxe/Lib/Sound/Playback/GstreamerSharp/CGstreamerSharpAudioStream.cs
@@ -175,7 +175,7 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
// Passing CLOCK_TIME_NONE here causes the pipeline to block for a long time so with
// prescan enabled the pipeline will wait 500ms for stream to initialize and then continue
// if it takes more than 500ms, duration queries will be performed asynchronously
- Message msg = _Element.Bus.TimedPopFiltered(prescan ? ulong.MaxValue : 0L, MessageType.AsyncDone | MessageType.Error);
+ Message msg = _Element.Bus.TimedPopFiltered(prescan ? ulong.MaxValue : 0L, MessageType.AsyncDone | MessageType.Error | MessageType.DurationChanged);
if (!_OnMessage(msg))
{
_Dispose(true);
@@ -237,7 +237,7 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
private bool _OnMessage(Message msg)
{
- if (msg.Handle == IntPtr.Zero)
+ if (msg == null || msg.Handle == IntPtr.Zero)
return true;
switch (msg.Type)
{
diff --git a/Vocaluxe/Program.cs b/Vocaluxe/Program.cs
index 5e1fb26c..73b5a737 100644
--- a/Vocaluxe/Program.cs
+++ b/Vocaluxe/Program.cs
@@ -199,7 +199,8 @@ namespace Vocaluxe
// Load Cover
CLog.StartBenchmark("Init Cover");
- CCover.Init();
+ if (!CCover.Init())
+ throw new CLoadingException("covertheme");
CLog.StopBenchmark("Init Cover");
Application.DoEvents();
@@ -237,7 +238,8 @@ namespace Vocaluxe
// Init Party Modes;
CLog.StartBenchmark("Init Party Modes");
- CParty.Init();
+ if (!CParty.Init())
+ throw new CLoadingException("Party Modes");
CLog.StopBenchmark("Init Party Modes");
Application.DoEvents();
diff --git a/Vocaluxe/Screens/CScreenOptionsGame.cs b/Vocaluxe/Screens/CScreenOptionsGame.cs
index ce71f532..71794199 100644
--- a/Vocaluxe/Screens/CScreenOptionsGame.cs
+++ b/Vocaluxe/Screens/CScreenOptionsGame.cs
@@ -134,7 +134,7 @@ namespace Vocaluxe.Screens
private void _SaveConfig()
{
CLanguage.LanguageId = _SelectSlides[_SelectSlideLanguage].Selection;
- CConfig.Config.Game.Language = _SelectSlides[_SelectSlideLanguage].Value;
+ CConfig.Config.Game.Language = _SelectSlides[_SelectSlideLanguage].SelectedValue;
CConfig.Config.Debug.DebugLevel = (EDebugLevel)_SelectSlides[_SelectSlideDebugLevel].Selection;
CConfig.Config.Game.SongMenu = (ESongMenu)_SelectSlides[_SelectSlideSongMenu].Selection;
CConfig.Config.Game.SongSorting = (ESongSorting)_SelectSlides[_SelectSlideSongSorting].Selection;
diff --git a/Vocaluxe/Screens/CScreenOptionsRecord.cs b/Vocaluxe/Screens/CScreenOptionsRecord.cs
index bcf3e902..df51de82 100644
--- a/Vocaluxe/Screens/CScreenOptionsRecord.cs
+++ b/Vocaluxe/Screens/CScreenOptionsRecord.cs
@@ -65,7 +65,7 @@ namespace Vocaluxe.Screens
public override EMusicType CurrentMusicType
{
- get { return EMusicType.None; }
+ get { return EMusicType.Game; }
}
public override void Init()
diff --git a/Vocaluxe/Screens/CScreenOptionsTheme.cs b/Vocaluxe/Screens/CScreenOptionsTheme.cs
index e21f5087..6723a305 100644
--- a/Vocaluxe/Screens/CScreenOptionsTheme.cs
+++ b/Vocaluxe/Screens/CScreenOptionsTheme.cs
@@ -171,15 +171,15 @@ namespace Vocaluxe.Screens
CConfig.SaveConfig();
- if (_OldCoverTheme != _SelectSlides[_SelectSlideCover].Value)
+ if (_OldCoverTheme != _SelectSlides[_SelectSlideCover].SelectedValue)
CCover.ReloadCovers();
}
private void _OnChange()
{
- if (CConfig.Config.Theme.Theme != _SelectSlides[_SelectSlideTheme].Value)
+ if (CConfig.Config.Theme.Theme != _SelectSlides[_SelectSlideTheme].SelectedValue)
{
- CConfig.Config.Theme.Theme = _SelectSlides[_SelectSlideTheme].Value;
+ CConfig.Config.Theme.Theme = _SelectSlides[_SelectSlideTheme].SelectedValue;
CThemes.Reload();
CGraphics.ReloadTheme();
@@ -188,9 +188,9 @@ namespace Vocaluxe.Screens
return;
}
- if (CConfig.Config.Theme.Skin != _SelectSlides[_SelectSlideSkin].Value)
+ if (CConfig.Config.Theme.Skin != _SelectSlides[_SelectSlideSkin].SelectedValue)
{
- CConfig.Config.Theme.Skin = _SelectSlides[_SelectSlideSkin].Value;
+ CConfig.Config.Theme.Skin = _SelectSlides[_SelectSlideSkin].SelectedValue;
CThemes.ReloadSkin();
CGraphics.ReloadSkin();
diff --git a/Vocaluxe/Screens/CScreenParty.cs b/Vocaluxe/Screens/CScreenParty.cs
index 3f6d801f..7b11c376 100644
--- a/Vocaluxe/Screens/CScreenParty.cs
+++ b/Vocaluxe/Screens/CScreenParty.cs
@@ -20,6 +20,7 @@ using System.Windows.Forms;
using Vocaluxe.Base;
using VocaluxeLib;
using VocaluxeLib.Menu;
+using VocaluxeLib.PartyModes;
namespace Vocaluxe.Screens
{
@@ -115,7 +116,7 @@ namespace Vocaluxe.Screens
_SelectSlides[_SelectSlideModes].Clear();
foreach (SPartyModeInfos info in _PartyModeInfos)
- _SelectSlides[_SelectSlideModes].AddValue(info.Name, info.PartyModeID);
+ _SelectSlides[_SelectSlideModes].AddValue(info.Name, info.ExtInfo.ID);
_SelectSlides[_SelectSlideModes].Selection = 0;
_UpdateSelection();
@@ -134,42 +135,48 @@ namespace Vocaluxe.Screens
int index = _SelectSlides[_SelectSlideModes].Selection;
if (index >= _PartyModeInfos.Count)
- return;
+ {
+ index = 0;
+ _SelectSlides[_SelectSlideModes].Selection = 0;
+ }
//Description
- _Texts[_TextDescription].Text = _PartyModeInfos[index].Description;
- _Texts[_TextDescription].TranslationID = _PartyModeInfos[index].PartyModeID;
+ SPartyModeInfos infos = _PartyModeInfos[index];
+ IPartyModeInfo extInfo = infos.ExtInfo;
+ _Texts[_TextDescription].Text = infos.Description;
+ _Texts[_TextDescription].TranslationID = extInfo.ID;
//TargetAudience
- _Texts[_TextTargetAudience].TranslationID = _PartyModeInfos[index].PartyModeID;
- _Texts[_TextTargetAudience].Text = _PartyModeInfos[index].TargetAudience;
+ _Texts[_TextTargetAudience].TranslationID = extInfo.ID;
+ _Texts[_TextTargetAudience].Text = infos.TargetAudience;
//NumTeams
- if (_PartyModeInfos[index].MaxTeams == 0)
+ if (extInfo.MaxTeams == 1)
_Texts[_TextNumTeams].Text = "TR_SCREENPARTY_NOTEAMS";
- else if (_PartyModeInfos[index].MaxTeams == _PartyModeInfos[index].MinTeams)
- _Texts[_TextNumTeams].Text = _PartyModeInfos[index].MaxTeams.ToString();
- else if (_PartyModeInfos[index].MaxTeams > _PartyModeInfos[index].MinTeams)
- _Texts[_TextNumTeams].Text = _PartyModeInfos[index].MinTeams + " - " + _PartyModeInfos[index].MaxTeams;
+ else if (extInfo.MaxTeams == extInfo.MinTeams)
+ _Texts[_TextNumTeams].Text = extInfo.MaxTeams.ToString();
+ else
+ _Texts[_TextNumTeams].Text = extInfo.MinTeams + " - " + extInfo.MaxTeams;
//NumPlayers
- if (_PartyModeInfos[index].MaxPlayers == _PartyModeInfos[index].MinPlayers)
- _Texts[_TextNumPlayers].Text = _PartyModeInfos[index].MaxTeams.ToString();
- else if (_PartyModeInfos[index].MaxPlayers > _PartyModeInfos[index].MinPlayers)
- _Texts[_TextNumPlayers].Text = _PartyModeInfos[index].MinPlayers + " - " + _PartyModeInfos[index].MaxPlayers;
+ if (extInfo.MaxPlayers == extInfo.MinPlayers)
+ _Texts[_TextNumPlayers].Text = extInfo.MaxTeams.ToString();
+ else
+ _Texts[_TextNumPlayers].Text = extInfo.MinPlayers + " - " + extInfo.MaxPlayers;
//Author
- _Texts[_TextAuthor].Text = _PartyModeInfos[index].Author;
- _Texts[_TextAuthor].TranslationID = _PartyModeInfos[index].PartyModeID;
+ _Texts[_TextAuthor].Text = infos.Author;
+ _Texts[_TextAuthor].TranslationID = extInfo.ID;
//Version
- _Texts[_TextVersion].Text = _PartyModeInfos[index].VersionMajor + "." + _PartyModeInfos[index].VersionMinor;
- _Texts[_TextVersion].TranslationID = _PartyModeInfos[index].PartyModeID;
+ _Texts[_TextVersion].Text = infos.VersionMajor + "." + infos.VersionMinor;
+ _Texts[_TextVersion].TranslationID = extInfo.ID;
- if (CConfig.GetMaxNumMics() == 0)
+ if (CConfig.GetMaxNumMics() < extInfo.MinMics)
{
_Buttons[_ButtonStart].Visible = false;
- _Texts[_TextError].Text = "TR_SCREENPARTY_ERROR_MICS";
+ _Texts[_TextError].Text = CConfig.GetMaxNumMics() == 0
+ ? "TR_SCREENPARTY_ERROR_MICS" : CLanguage.Translate("TR_SCREENPARTY_ERROR_MIC_NUM").Replace("%d", extInfo.MinMics.ToString());
_Texts[_TextError].Visible = true;
}
else
@@ -193,7 +200,7 @@ namespace Vocaluxe.Screens
return;
}
- CParty.SetPartyMode(_PartyModeInfos[index].PartyModeID);
+ CParty.SetPartyMode(_PartyModeInfos[index].ExtInfo.ID);
CGraphics.FadeTo(CParty.GetStartScreen());
}
}
diff --git a/Vocaluxe/Screens/CScreenProfiles.cs b/Vocaluxe/Screens/CScreenProfiles.cs
index 383ff57b..44196e34 100644
--- a/Vocaluxe/Screens/CScreenProfiles.cs
+++ b/Vocaluxe/Screens/CScreenProfiles.cs
@@ -109,7 +109,7 @@ namespace Vocaluxe.Screens
break;
case EEditMode.PlayerName:
_SelectSlides[_SelectSlideProfiles].RenameValue(
- CProfiles.AddGetPlayerName(_SelectSlides[_SelectSlideProfiles].ValueIndex, keyEvent.Unicode));
+ CProfiles.AddGetPlayerName(_SelectSlides[_SelectSlideProfiles].SelectedTag, keyEvent.Unicode));
_ProfilesChanged = true;
break;
}
@@ -155,7 +155,7 @@ namespace Vocaluxe.Screens
if (_EditMode == EEditMode.PlayerName)
{
_SelectSlides[_SelectSlideProfiles].RenameValue(
- CProfiles.GetDeleteCharInPlayerName(_SelectSlides[_SelectSlideProfiles].ValueIndex));
+ CProfiles.GetDeleteCharInPlayerName(_SelectSlides[_SelectSlideProfiles].SelectedTag));
_ProfilesChanged = true;
}
else
@@ -168,22 +168,22 @@ namespace Vocaluxe.Screens
}
if (_SelectSlides[_SelectSlideDifficulty].Selected)
{
- CProfiles.SetDifficulty(_SelectSlides[_SelectSlideProfiles].ValueIndex,
+ CProfiles.SetDifficulty(_SelectSlides[_SelectSlideProfiles].SelectedTag,
(EGameDifficulty)_SelectSlides[_SelectSlideDifficulty].Selection);
}
else if (_SelectSlides[_SelectSlideAvatars].Selected)
{
- CProfiles.SetAvatar(_SelectSlides[_SelectSlideProfiles].ValueIndex,
- _SelectSlides[_SelectSlideAvatars].ValueIndex);
+ CProfiles.SetAvatar(_SelectSlides[_SelectSlideProfiles].SelectedTag,
+ _SelectSlides[_SelectSlideAvatars].SelectedTag);
}
else if (_SelectSlides[_SelectSlideUserRole].Selected)
{
- CProfiles.SetUserRoleProfile(_SelectSlides[_SelectSlideProfiles].ValueIndex,
+ CProfiles.SetUserRoleProfile(_SelectSlides[_SelectSlideProfiles].SelectedTag,
(EUserRole)_SelectSlides[_SelectSlideUserRole].Selection);
}
else if (_SelectSlides[_SelectSlideActive].Selected)
{
- CProfiles.SetActive(_SelectSlides[_SelectSlideProfiles].ValueIndex,
+ CProfiles.SetActive(_SelectSlides[_SelectSlideProfiles].SelectedTag,
(EOffOn)_SelectSlides[_SelectSlideActive].Selection);
}
}
@@ -215,24 +215,24 @@ namespace Vocaluxe.Screens
}
else if (_SelectSlides[_SelectSlideDifficulty].Selected)
{
- CProfiles.SetDifficulty(_SelectSlides[_SelectSlideProfiles].ValueIndex,
+ CProfiles.SetDifficulty(_SelectSlides[_SelectSlideProfiles].SelectedTag,
(EGameDifficulty)_SelectSlides[_SelectSlideDifficulty].Selection);
}
else if (_SelectSlides[_SelectSlideAvatars].Selected)
{
- CProfiles.SetAvatar(_SelectSlides[_SelectSlideProfiles].ValueIndex,
- _SelectSlides[_SelectSlideAvatars].ValueIndex);
+ CProfiles.SetAvatar(_SelectSlides[_SelectSlideProfiles].SelectedTag,
+ _SelectSlides[_SelectSlideAvatars].SelectedTag);
if (CWebcam.IsDeviceAvailable() && _WebcamTexture != null)
_OnDiscardSnapshot();
}
else if (_SelectSlides[_SelectSlideUserRole].Selected)
{
- CProfiles.SetUserRoleProfile(_SelectSlides[_SelectSlideProfiles].ValueIndex,
+ CProfiles.SetUserRoleProfile(_SelectSlides[_SelectSlideProfiles].SelectedTag,
(EUserRole)_SelectSlides[_SelectSlideUserRole].Selection);
}
else if (_SelectSlides[_SelectSlideActive].Selected)
{
- CProfiles.SetActive(_SelectSlides[_SelectSlideProfiles].ValueIndex,
+ CProfiles.SetActive(_SelectSlides[_SelectSlideProfiles].SelectedTag,
(EOffOn)_SelectSlides[_SelectSlideActive].Selection);
}
else if (_Buttons[_ButtonWebcam].Selected)
@@ -260,16 +260,16 @@ namespace Vocaluxe.Screens
if (_SelectSlides[_SelectSlideProfiles].Selection > -1)
{
- _Buttons[_ButtonPlayerName].Text.Text = CProfiles.GetPlayerName(_SelectSlides[_SelectSlideProfiles].ValueIndex);
+ _Buttons[_ButtonPlayerName].Text.Text = CProfiles.GetPlayerName(_SelectSlides[_SelectSlideProfiles].SelectedTag);
if (_EditMode == EEditMode.PlayerName)
_Buttons[_ButtonPlayerName].Text.Text += "|";
- _SelectSlides[_SelectSlideDifficulty].Selection = (int)CProfiles.GetDifficulty(_SelectSlides[_SelectSlideProfiles].ValueIndex);
- _SelectSlides[_SelectSlideUserRole].Selection = (int)CProfiles.GetUserRoleProfile(_SelectSlides[_SelectSlideProfiles].ValueIndex);
- _SelectSlides[_SelectSlideActive].Selection = (int)CProfiles.GetActive(_SelectSlides[_SelectSlideProfiles].ValueIndex);
+ _SelectSlides[_SelectSlideDifficulty].Selection = (int)CProfiles.GetDifficulty(_SelectSlides[_SelectSlideProfiles].SelectedTag);
+ _SelectSlides[_SelectSlideUserRole].Selection = (int)CProfiles.GetUserRoleProfile(_SelectSlides[_SelectSlideProfiles].SelectedTag);
+ _SelectSlides[_SelectSlideActive].Selection = (int)CProfiles.GetActive(_SelectSlides[_SelectSlideProfiles].SelectedTag);
- int avatarID = CProfiles.GetAvatarID(_SelectSlides[_SelectSlideProfiles].ValueIndex);
- _SelectSlides[_SelectSlideAvatars].SetSelectionByValueIndex(avatarID);
+ int avatarID = CProfiles.GetAvatarID(_SelectSlides[_SelectSlideProfiles].SelectedTag);
+ _SelectSlides[_SelectSlideAvatars].SelectedTag = avatarID;
if (_Snapshot == null)
{
if (CWebcam.IsCapturing())
@@ -357,7 +357,7 @@ namespace Vocaluxe.Screens
_Buttons[_ButtonWebcam].Visible = CWebcam.IsDeviceAvailable();
int id = CProfiles.NewAvatar(file);
- CProfiles.SetAvatar(_SelectSlides[_SelectSlideProfiles].ValueIndex, id);
+ CProfiles.SetAvatar(_SelectSlides[_SelectSlideProfiles].SelectedTag, id);
_LoadAvatars(false);
}
@@ -381,10 +381,9 @@ namespace Vocaluxe.Screens
_EditMode = EEditMode.None;
int id = CProfiles.NewProfile();
_LoadProfiles(false);
- _SelectSlides[_SelectSlideProfiles].SetSelectionByValueIndex(id);
+ _SelectSlides[_SelectSlideProfiles].SelectedTag = id;
- CProfiles.SetAvatar(_SelectSlides[_SelectSlideProfiles].ValueIndex,
- _SelectSlides[_SelectSlideAvatars].ValueIndex);
+ CProfiles.SetAvatar(_SelectSlides[_SelectSlideProfiles].SelectedTag, _SelectSlides[_SelectSlideAvatars].SelectedTag);
_SelectElement(_Buttons[_ButtonPlayerName]);
_EditMode = EEditMode.PlayerName;
@@ -400,7 +399,7 @@ namespace Vocaluxe.Screens
{
_EditMode = EEditMode.None;
- CProfiles.DeleteProfile(_SelectSlides[_SelectSlideProfiles].ValueIndex);
+ CProfiles.DeleteProfile(_SelectSlides[_SelectSlideProfiles].SelectedTag);
int selection = _SelectSlides[_SelectSlideProfiles].Selection;
if (_SelectSlides[_SelectSlideProfiles].NumValues - 1 > selection)
@@ -413,29 +412,23 @@ namespace Vocaluxe.Screens
{
string name = String.Empty;
if (_EditMode == EEditMode.PlayerName)
- name = CProfiles.GetPlayerName(_SelectSlides[_SelectSlideProfiles].ValueIndex);
+ name = CProfiles.GetPlayerName(_SelectSlides[_SelectSlideProfiles].SelectedTag);
- int selectedProfileID = _SelectSlides[_SelectSlideProfiles].ValueIndex;
+ int selectedProfileID = _SelectSlides[_SelectSlideProfiles].SelectedTag;
_SelectSlides[_SelectSlideProfiles].Clear();
CProfile[] profiles = CProfiles.GetProfiles();
foreach (CProfile profile in profiles)
- {
- _SelectSlides[_SelectSlideProfiles].AddValue(
- profile.PlayerName,
- null,
- profile.ID,
- -1);
- }
+ _SelectSlides[_SelectSlideProfiles].AddValue(profile.PlayerName, null, profile.ID);
if (CProfiles.NumProfiles > 0 && CProfiles.NumAvatars > 0)
{
if (selectedProfileID != -1)
- _SelectSlides[_SelectSlideProfiles].SetSelectionByValueIndex(selectedProfileID);
+ _SelectSlides[_SelectSlideProfiles].SelectedTag = selectedProfileID;
else
{
_SelectSlides[_SelectSlideProfiles].Selection = 0;
- selectedProfileID = _SelectSlides[_SelectSlideProfiles].ValueIndex;
+ selectedProfileID = _SelectSlides[_SelectSlideProfiles].SelectedTag;
}
if (!keep)
@@ -443,39 +436,33 @@ namespace Vocaluxe.Screens
_SelectSlides[_SelectSlideDifficulty].Selection = (int)CProfiles.GetDifficulty(selectedProfileID);
_SelectSlides[_SelectSlideUserRole].Selection = (int)CProfiles.GetUserRoleProfile(selectedProfileID);
_SelectSlides[_SelectSlideActive].Selection = (int)CProfiles.GetActive(selectedProfileID);
- _SelectSlides[_SelectSlideAvatars].SetSelectionByValueIndex(CProfiles.GetAvatarID(selectedProfileID));
+ _SelectSlides[_SelectSlideAvatars].SelectedTag = CProfiles.GetAvatarID(selectedProfileID);
}
if (_EditMode == EEditMode.PlayerName)
- CProfiles.SetPlayerName(_SelectSlides[_SelectSlideProfiles].ValueIndex, name);
+ CProfiles.SetPlayerName(_SelectSlides[_SelectSlideProfiles].SelectedTag, name);
}
_ProfilesChanged = false;
}
private void _LoadAvatars(bool keep)
{
- int selectedAvatarID = _SelectSlides[_SelectSlideAvatars].ValueIndex;
+ int selectedAvatarID = _SelectSlides[_SelectSlideAvatars].SelectedTag;
_SelectSlides[_SelectSlideAvatars].Clear();
IEnumerable avatars = CProfiles.GetAvatars();
if (avatars != null)
{
foreach (CAvatar avatar in avatars)
- {
- _SelectSlides[_SelectSlideAvatars].AddValue(
- avatar.GetDisplayName(),
- null,
- avatar.ID,
- -1);
- }
+ _SelectSlides[_SelectSlideAvatars].AddValue(avatar.GetDisplayName(), null, avatar.ID);
}
if (keep)
{
- _SelectSlides[_SelectSlideAvatars].SetSelectionByValueIndex(selectedAvatarID);
- CProfiles.SetAvatar(_SelectSlides[_SelectSlideProfiles].ValueIndex, selectedAvatarID);
+ _SelectSlides[_SelectSlideAvatars].SelectedTag = selectedAvatarID;
+ CProfiles.SetAvatar(_SelectSlides[_SelectSlideProfiles].SelectedTag, selectedAvatarID);
}
else
- _SelectSlides[_SelectSlideAvatars].SetSelectionByValueIndex(CProfiles.GetAvatarID(_SelectSlides[_SelectSlideProfiles].ValueIndex));
+ _SelectSlides[_SelectSlideAvatars].SelectedTag = CProfiles.GetAvatarID(_SelectSlides[_SelectSlideProfiles].SelectedTag);
_AvatarsChanged = false;
}
diff --git a/Vocaluxe/Screens/CScreenScore.cs b/Vocaluxe/Screens/CScreenScore.cs
index 4f8a7aff..adce6bf6 100644
--- a/Vocaluxe/Screens/CScreenScore.cs
+++ b/Vocaluxe/Screens/CScreenScore.cs
@@ -187,26 +187,23 @@ namespace Vocaluxe.Screens
private static string _GetRating(double points)
{
- string rating = String.Empty;
+ string rating;
if (points >= 9800)
- {
- //in case of the game names so:
rating = "TR_RATING_VOCAL_HERO";
- }
- else if (points < 9800 && points >= 8400)
+ else if (points >= 8400)
rating = "TR_RATING_SUPERSTAR";
- else if (points < 8400 && points >= 7000)
+ else if (points >= 7000)
rating = "TR_RATING_LEAD_SINGER";
- else if (points < 7000 && points >= 5600)
+ else if (points >= 5600)
rating = "TR_RATING_RISING_STAR";
- else if (points < 5600 && points >= 4200)
+ else if (points >= 4200)
rating = "TR_RATING_HOPEFUL";
- else if (points < 4200 && points >= 2800)
+ else if (points >= 2800)
rating = "TR_RATING_WANNABE";
- else if (points < 2800 && points >= 1400)
+ else if (points >= 1400)
rating = "TR_RATING_AMATEUR";
- else if (points < 1400)
+ else
rating = "TR_RATING_TONE_DEAF";
return rating;
diff --git a/Vocaluxe/Screens/CScreenSong.cs b/Vocaluxe/Screens/CScreenSong.cs
index 75dea6b9..950551ee 100644
--- a/Vocaluxe/Screens/CScreenSong.cs
+++ b/Vocaluxe/Screens/CScreenSong.cs
@@ -522,12 +522,12 @@ namespace Vocaluxe.Screens
_HandleSelectButton();
return true;
}
- else if (_SelectSlides[_SelectSlideOptionsPlaylistOpen].ValueSelected)
+ else if (_SelectSlides[_SelectSlideOptionsPlaylistOpen].IsValueSelected)
{
_OpenPlaylist(_SelectSlides[_SelectSlideOptionsPlaylistOpen].Selection);
return true;
}
- else if (_SelectSlides[_SelectSlideOptionsPlaylistAdd].ValueSelected)
+ else if (_SelectSlides[_SelectSlideOptionsPlaylistAdd].IsValueSelected)
{
_OpenPlaylist(_SelectSlides[_SelectSlideOptionsPlaylistAdd].Selection - 1);
return true;
@@ -1171,7 +1171,7 @@ namespace Vocaluxe.Screens
{
if (CSongs.VisibleSongs[_SongMenu.GetPreviewSongNr()].IsGameModeAvailable(gameMode))
{
- _SelectSlides[_SelectSlideOptionsMode].AddValue(Enum.GetName(typeof(EGameMode), gameMode));
+ _SelectSlides[_SelectSlideOptionsMode].AddValue(Enum.GetName(typeof(EGameMode), gameMode), null, (int)gameMode);
_AvailableGameModes.Add(gameMode);
}
}
@@ -1189,11 +1189,7 @@ namespace Vocaluxe.Screens
_CheckAndAddGameMode(EGameMode.TR_GAMEMODE_MEDLEY);
//Set SelectSlide-Selection to last selected game-mode if possible
- for (int i = 0; i < _AvailableGameModes.Count; i++)
- {
- if (_AvailableGameModes[i] == lastMode)
- _SelectSlides[_SelectSlideOptionsMode].SetSelectionByValueIndex(i);
- }
+ _SelectSlides[_SelectSlideOptionsMode].SelectedTag = (int)lastMode;
_SelectSlides[_SelectSlideOptionsMode].Visible = true;
_SelectSlides[_SelectSlideOptionsPlaylistAdd].Visible = true;
_Buttons[_ButtonOptionsSing].Visible = true;
@@ -1242,9 +1238,9 @@ namespace Vocaluxe.Screens
_SelectSlides[_SelectSlideOptionsNumMedleySongs].AddValue(i.ToString());
}
if (_SelectSlides[_SelectSlideOptionsNumMedleySongs].NumValues >= 5)
- _SelectSlides[_SelectSlideOptionsNumMedleySongs].SetSelectionByValueIndex(4);
+ _SelectSlides[_SelectSlideOptionsNumMedleySongs].SelectedValue = "5";
else
- _SelectSlides[_SelectSlideOptionsNumMedleySongs].SetSelectionByValueIndex(_SelectSlides[_SelectSlideOptionsNumMedleySongs].NumValues - 1);
+ _SelectSlides[_SelectSlideOptionsNumMedleySongs].SelectLastValue();
_SelectElement(_Buttons[_ButtonOptionsStartMedley]);
}
diff --git a/VocaluxeLib/Extensions.cs b/VocaluxeLib/Extensions.cs
index 12f06137..5e36958d 100644
--- a/VocaluxeLib/Extensions.cs
+++ b/VocaluxeLib/Extensions.cs
@@ -178,6 +178,18 @@ namespace VocaluxeLib
rect.Z);
}
+ public static List Shuffle(this List list)
+ {
+ for (int n = list.Count - 1; n >= 1; n--)
+ {
+ int k = CBase.Game.GetRandom(n);
+ T value = list[k];
+ list[k] = list[n];
+ list[n] = value;
+ }
+ return list;
+ }
+
public static Size GetSize(this Bitmap bmp)
{
return new Size(bmp.Width, bmp.Height);
diff --git a/VocaluxeLib/Menu/CLyric.cs b/VocaluxeLib/Menu/CLyric.cs
index 7ada94b3..7b17d0c0 100644
--- a/VocaluxeLib/Menu/CLyric.cs
+++ b/VocaluxeLib/Menu/CLyric.cs
@@ -188,14 +188,12 @@ namespace VocaluxeLib.Menu
case ELyricStyle.Fill:
_DrawFill();
break;
- case ELyricStyle.Jump:
- _DrawJump();
- break;
case ELyricStyle.Slide:
_DrawSlide();
break;
case ELyricStyle.Zoom:
- _DrawZoom();
+ case ELyricStyle.Jump:
+ _DrawZoomOrJump();
break;
default:
_DrawSlide();
@@ -219,14 +217,15 @@ namespace VocaluxeLib.Menu
{
_Text.Color = _ColorProcessed;
- int diff = note.EndBeat - note.StartBeat;
+ int diff = note.Duration;
if (diff <= 0)
_Text.Draw(0f, 1f);
else
{
- _Text.Draw(0f, (_CurrentBeat - note.StartBeat) / diff);
+ float p = (_CurrentBeat - note.StartBeat) / diff;
+ _Text.Draw(0f, p);
_Text.Color = _Color;
- _Text.Draw((_CurrentBeat - note.StartBeat) / diff, 1f);
+ _Text.Draw(p, 1f);
}
}
else
@@ -245,87 +244,6 @@ namespace VocaluxeLib.Menu
}
}
- private void _DrawZoom()
- {
- float x = X - _Width / 2; // most left position
-
- //find last active note
- int lastNote = _Line.FindPreviousNote((int)_CurrentBeat);
-
- int zoomNote = -1;
- int endBeat = -1;
- float zoomx = 0f;
-
- for (int note = 0; note < _Line.Notes.Length; note++)
- {
- _Text.X = x;
- _SetText(_Line.Notes[note]);
-
- if (_CurrentBeat >= _Line.Notes[note].StartBeat)
- {
- int curEndBeat = _Line.Notes[note].EndBeat;
- if (note < _Line.Notes.Length - 1)
- curEndBeat = _Line.Notes[note + 1].StartBeat - 1;
-
- if (_CurrentBeat <= curEndBeat)
- {
- zoomNote = note;
- endBeat = curEndBeat;
- zoomx = _Text.X;
- }
- else
- {
- // already passed
- _Text.Color = note == lastNote ? _ColorProcessed : _Color;
-
- _Text.Draw();
- }
- }
- else
- {
- // not passed
- _Text.Color = _Color;
- _Text.Draw();
- }
-
- x += _Text.Rect.W;
- }
-
- if (zoomNote > -1)
- {
- _Text.X = zoomx;
- _SetText(_Line.Notes[zoomNote]);
-
- float diff = endBeat - _Line.Notes[zoomNote].StartBeat;
- if (diff <= 0f)
- diff = 1f;
-
- float p = (_CurrentBeat - _Line.Notes[zoomNote].StartBeat) / diff;
- if (p > 1f)
- p = 1f;
-
- p = 1f - p;
-
- float ty = _Text.Y;
- float th = _Text.Font.Height;
- float tz = _Text.Z;
-
- SRectF normalRect = _Text.Rect;
- _Text.Font.Height *= 1f + p * 0.4f;
- _Text.X -= (_Text.Rect.W - normalRect.W) / 2f;
- _Text.Y -= (_Text.Rect.H - normalRect.H) / 2f;
- _Text.Z -= 0.1f;
- _Text.Color = _ColorProcessed;
-
-
- _Text.Draw();
-
- _Text.Y = ty;
- _Text.Font.Height = th;
- _Text.Z = tz;
- }
- }
-
private void _DrawFill()
{
float x = X - _Width / 2; // most left position
@@ -351,37 +269,87 @@ namespace VocaluxeLib.Menu
}
}
- private void _DrawJump()
+ private void _DrawZoomedNote(CBaseNote zoomNote, int endBeat)
+ {
+ float diff = endBeat - zoomNote.StartBeat;
+ if (diff <= 0f)
+ diff = 1f;
+
+ float p = 1f - (_CurrentBeat - zoomNote.StartBeat) / diff;
+ if (p < 0)
+ p = 0;
+
+ float ty = _Text.Y;
+ float th = _Text.Font.Height;
+ float tz = _Text.Z;
+
+ SRectF normalRect = _Text.Rect;
+ _Text.Font.Height *= 1f + p * 0.4f;
+ _Text.X -= (_Text.Rect.W - normalRect.W) / 2f;
+ _Text.Y -= (_Text.Rect.H - normalRect.H) / 2f;
+ _Text.Z -= 0.1f;
+ _Text.Color = _ColorProcessed;
+
+
+ _Text.Draw();
+
+ _Text.Y = ty;
+ _Text.Font.Height = th;
+ _Text.Z = tz;
+ }
+
+ private void _DrawJumpingNode(CBaseNote jumpNote)
+ {
+ _Text.Color = _ColorProcessed;
+
+ int diff = jumpNote.Duration;
+ if (diff <= 0)
+ diff = 1;
+
+ float p = 1f - (_CurrentBeat - jumpNote.StartBeat) / diff;
+
+ if (p < 0.001)
+ _Text.Draw();
+ else
+ {
+ float y = _Text.Y;
+ _Text.Y -= _Text.Font.Height * 0.1f * p;
+ _Text.Draw();
+ _Text.Y = y;
+ }
+ }
+
+ private void _DrawZoomOrJump()
{
float x = X - _Width / 2; // most left position
- //find last active note
int lastNote = _Line.FindPreviousNote((int)_CurrentBeat);
-
- int jumpNote = -1;
- float jumpx = 0f;
+ CSongNote highlightNote = null;
+ int hEndBeat = 0;
+ float hX = 0;
for (int note = 0; note < _Line.Notes.Length; note++)
{
_Text.X = x;
- _SetText(_Line.Notes[note]);
+ CSongNote curNote = _Line.Notes[note];
+ _SetText(curNote);
- if (_CurrentBeat >= _Line.Notes[note].StartBeat)
+ if (_CurrentBeat >= curNote.StartBeat)
{
- int curEndBeat = _Line.Notes[note].EndBeat;
+ int curEndBeat = curNote.EndBeat;
if (note < _Line.Notes.Length - 1)
curEndBeat = _Line.Notes[note + 1].StartBeat - 1;
if (_CurrentBeat <= curEndBeat)
{
- jumpNote = note;
- jumpx = _Text.X;
+ highlightNote = curNote;
+ hEndBeat = curEndBeat;
+ hX = x;
}
else
{
// already passed
- _Text.Color = note == lastNote ? _ColorProcessed : _Color;
-
+ _Text.Color = lastNote == note ? _ColorProcessed : _Color;
_Text.Draw();
}
}
@@ -395,28 +363,15 @@ namespace VocaluxeLib.Menu
x += _Text.Rect.W;
}
- if (jumpNote < 0)
+ // Draw the highlighted note after all others because we want it to be above those! (transparency won't work well otherwhise)
+ if (highlightNote == null)
return;
-
- _Text.X = jumpx;
- _Text.Color = _ColorProcessed;
- _SetText(_Line.Notes[jumpNote]);
-
- int diff = _Line.Notes[jumpNote].EndBeat - _Line.Notes[jumpNote].StartBeat;
- if (diff <= 0)
- diff = 1;
-
- float p = 1f - (_CurrentBeat - _Line.Notes[jumpNote].StartBeat) / diff;
-
- if (Math.Abs(p) < float.Epsilon)
- _Text.Draw();
+ _SetText(highlightNote);
+ _Text.X = hX;
+ if (LyricStyle == ELyricStyle.Jump)
+ _DrawJumpingNode(highlightNote);
else
- {
- float y = _Text.Y;
- _Text.Y -= _Text.Font.Height * 0.1f * p;
- _Text.Draw();
- _Text.Y = y;
- }
+ _DrawZoomedNote(highlightNote, hEndBeat);
}
#endregion draw
diff --git a/VocaluxeLib/Menu/CMenu.cs b/VocaluxeLib/Menu/CMenu.cs
index dfc66cce..7bb87d13 100644
--- a/VocaluxeLib/Menu/CMenu.cs
+++ b/VocaluxeLib/Menu/CMenu.cs
@@ -137,6 +137,26 @@ namespace VocaluxeLib.Menu
}
}
+ private class CLoadThemeErrorHandler : CXmlDeserializer.CXmlDefaultErrorHandler
+ {
+ private static readonly string[] _AllowedMissing = new string[]
+ {
+ "Backgrounds", "Statics", "Texts", "Buttons", "SongMenus", "Lyrics", "SelectSlides", "SingNotes",
+ "NameSelections", "Equalizers", "Playlists", "ParticleEffects", "ScreenSettings"
+ };
+
+ public override void HandleError(CXmlException e)
+ {
+ CXmlMissingElementException missingEx = e as CXmlMissingElementException;
+ if (missingEx != null)
+ {
+ if (_AllowedMissing.Contains(missingEx.Field.Name))
+ return;
+ }
+ base.HandleError(e);
+ }
+ }
+
public virtual void LoadTheme(string xmlPath)
{
if (CBase.Config.GetLoadOldThemeFiles())
@@ -149,26 +169,10 @@ namespace VocaluxeLib.Menu
string file = Path.Combine(xmlPath, ThemeName + ".xml");
- Theme.Informations = new SScreenInformation();
- Theme.Backgrounds = new List();
- Theme.Statics = new List();
- Theme.Texts = new List();
- Theme.Buttons = new List();
- Theme.SongMenus = new List();
- Theme.Lyrics = new List();
- Theme.SelectSlides = new List();
- Theme.SingNotes = new List();
- Theme.NameSelections = new List();
- Theme.Equalizers = new List();
- Theme.Playlists = new List();
- Theme.ParticleEffects = new List();
- Theme.ScreenSettings = new List();
-
try
{
- TextReader textReader = new StreamReader(file);
- XmlSerializer deserializer = new XmlSerializer(typeof(SThemeScreen));
- Theme = (SThemeScreen)deserializer.Deserialize(textReader);
+ CXmlDeserializer deserializer = new CXmlDeserializer(new CLoadThemeErrorHandler());
+ Theme = deserializer.Deserialize(file);
foreach (SThemeBackground bg in Theme.Backgrounds)
_AddBackground(new CBackground(bg, PartyModeID), bg.Name);
@@ -227,6 +231,10 @@ namespace VocaluxeLib.Menu
{
CBase.Log.LogError("Error while reading " + ThemeName + ".xml", true, true);
}
+ catch (CXmlException e)
+ {
+ CBase.Log.LogError("Error while reading " + ThemeName + ".xml: " + e, true, true);
+ }
catch (Exception e)
{
CBase.Log.LogError(e.Message + e.StackTrace, true, true);
@@ -308,12 +316,8 @@ namespace VocaluxeLib.Menu
try
{
- TextWriter textWriter = new StreamWriter(Path.Combine(ThemePath, ThemeName + ".xml"));
-
- XmlSerializer serializer = new XmlSerializer(typeof(SThemeScreen));
- serializer.Serialize(textWriter, Theme);
-
- textWriter.Close();
+ CXmlSerializer serializer = new CXmlSerializer();
+ serializer.Serialize(Path.Combine(ThemePath, ThemeName + ".xml"), Theme);
}
catch (Exception e)
{
diff --git a/VocaluxeLib/Menu/CMenuPartyNameSelection.cs b/VocaluxeLib/Menu/CMenuPartyNameSelection.cs
index 6e3d1090..423d89e8 100644
--- a/VocaluxeLib/Menu/CMenuPartyNameSelection.cs
+++ b/VocaluxeLib/Menu/CMenuPartyNameSelection.cs
@@ -29,8 +29,10 @@ namespace VocaluxeLib.Menu
get
{
for (int team = 0; team < _NumTeams; team++)
+ {
if (_TeamList[team].Count < _NumPlayerTeams[team])
return false;
+ }
return true;
}
}
@@ -147,7 +149,7 @@ namespace VocaluxeLib.Menu
{
if (!_ChangePlayerNumDynamic && _TeamList[_CurrentTeam].Count == _NumPlayerTeams[_CurrentTeam])
resetSelection = true;
- else if (_TeamList[_CurrentTeam].Count == _PartyMode.GetMaxPlayerPerTeam())
+ else if (_TeamList[_CurrentTeam].Count == _PartyMode.MaxPlayersPerTeam)
resetSelection = true;
}
else if (!_SelectingFast)
@@ -344,13 +346,13 @@ namespace VocaluxeLib.Menu
if (numPressed > 0)
{
- if (_ChangeTeamNumDynamic && numPressed < _PartyMode.GetMaxTeams() && numPressed > _SelectSlides[_SelectSlideTeams].NumValues)
+ if (_ChangeTeamNumDynamic && numPressed < _PartyMode.MaxTeams && numPressed > _SelectSlides[_SelectSlideTeams].NumValues)
{
- while (numPressed < _PartyMode.GetMaxTeams())
+ while (numPressed < _PartyMode.MaxTeams)
IncreaseTeamNum();
}
if (numPressed <= _SelectSlides[_SelectSlideTeams].NumValues)
- _SelectSlides[_SelectSlideTeams].SetSelectionByValueIndex(numPressed - 1);
+ _SelectSlides[_SelectSlideTeams].SelectedTag = numPressed;
}
}
if (_SelectingFastPlayerNr > 0 && _SelectingFastPlayerNr <= _NumPlayerTeams[_CurrentTeam])
@@ -433,7 +435,7 @@ namespace VocaluxeLib.Menu
if (!_ChangePlayerNumDynamic && _TeamList[_CurrentTeam].Count == _NumPlayerTeams[_CurrentTeam])
stopSelectingFast = true;
- else if (_TeamList[_CurrentTeam].Count == _PartyMode.GetMaxPlayerPerTeam())
+ else if (_TeamList[_CurrentTeam].Count == _PartyMode.MaxPlayersPerTeam)
stopSelectingFast = true;
}
else
@@ -488,7 +490,7 @@ namespace VocaluxeLib.Menu
else if (mouseEvent.RB)
{
bool exit = true;
- if (_SelectSlides[_SelectSlidePlayer].Selected && _TeamList[_CurrentTeam].Count > 0)
+ if (_SelectSlides[_SelectSlidePlayer].Selected && _TeamList[_CurrentTeam].Count > _SelectSlides[_SelectSlidePlayer].Selection)
{
int currentSelection = _SelectSlides[_SelectSlidePlayer].Selection;
int id = _TeamList[_CurrentTeam][currentSelection];
@@ -505,7 +507,7 @@ namespace VocaluxeLib.Menu
{
if (!_ChangePlayerNumDynamic && _TeamList[_CurrentTeam].Count == _NumPlayerTeams[_CurrentTeam])
stopSelectingFast = true;
- else if (_TeamList[_CurrentTeam].Count == _PartyMode.GetMaxPlayerPerTeam())
+ else if (_TeamList[_CurrentTeam].Count == _PartyMode.MaxPlayersPerTeam)
stopSelectingFast = true;
}
else if (mouseEvent.MB)
@@ -539,8 +541,8 @@ namespace VocaluxeLib.Menu
public override void LoadTheme(string xmlPath)
{
base.LoadTheme(xmlPath);
- _SelectSlides[_SelectSlidePlayer].WithTextures = true;
- _SelectSlides[_SelectSlidePlayer].SelectionByHover = true;
+ _SelectSlides[_SelectSlidePlayer].DrawTextures = true;
+ _SelectSlides[_SelectSlidePlayer].SelectByHovering = true;
_AddStatic(_ChooseAvatarStatic);
}
@@ -571,7 +573,7 @@ namespace VocaluxeLib.Menu
if (!_AllowChangeTeamNum)
return;
- if (_NumTeams + 1 <= _PartyMode.GetMaxTeams())
+ if (_NumTeams + 1 <= _PartyMode.MaxTeams)
{
_NumTeams++;
int[] numPlayerTeams = _NumPlayerTeams;
@@ -600,7 +602,7 @@ namespace VocaluxeLib.Menu
if (!_AllowChangeTeamNum)
return;
- if (_NumTeams - 1 >= _PartyMode.GetMinTeams())
+ if (_NumTeams - 1 >= _PartyMode.MinTeams)
_NumTeams--;
_UpdateButtonState();
}
@@ -611,7 +613,7 @@ namespace VocaluxeLib.Menu
return;
if (_NumPlayerTeams.Length > team)
{
- if (_NumPlayerTeams[team] + 1 <= _PartyMode.GetMaxPlayerPerTeam())
+ if (_NumPlayerTeams[team] + 1 <= _PartyMode.MaxPlayersPerTeam)
_NumPlayerTeams[team]++;
_UpdatePlayerSlide();
}
@@ -624,7 +626,7 @@ namespace VocaluxeLib.Menu
return;
if (_NumPlayerTeams.Length > team)
{
- if (_NumPlayerTeams[team] - 1 >= _PartyMode.GetMinPlayerPerTeam())
+ if (_NumPlayerTeams[team] - 1 >= _PartyMode.MinPlayersPerTeam)
_NumPlayerTeams[team]--;
if (_TeamList[team].Count > _NumPlayerTeams[team])
_RemovePlayerByIndex(team, _NumPlayerTeams[team] - 1);
@@ -684,7 +686,7 @@ namespace VocaluxeLib.Menu
_SelectSlides[_SelectSlidePlayer].AddValue("", _NameSelections[_NameSelection].TextureEmptyTile);
if (selection >= _TeamList[_CurrentTeam].Count)
selection = _TeamList[_CurrentTeam].Count - 1;
- _SelectSlides[_SelectSlidePlayer].SetSelectionByValueIndex(selection);
+ _SelectSlides[_SelectSlidePlayer].Selection = selection;
}
private void _UpdateTeamSlide()
@@ -692,25 +694,25 @@ namespace VocaluxeLib.Menu
_SelectSlides[_SelectSlideTeams].Visible = _Teams;
_SelectSlides[_SelectSlideTeams].Clear();
for (int i = 1; i <= _NumTeams; i++)
- _SelectSlides[_SelectSlideTeams].AddValue("Team " + i);
+ _SelectSlides[_SelectSlideTeams].AddValue("Team " + i, null, i);
}
private void _UpdateButtonVisibility()
{
- _Buttons[_ButtonIncreaseTeams].Visible = _AllowChangePlayerNum && _Teams && _PartyMode.GetMinTeams() != _PartyMode.GetMaxTeams();
- _Buttons[_ButtonDecreaseTeams].Visible = _AllowChangePlayerNum && _Teams && _PartyMode.GetMinTeams() != _PartyMode.GetMaxTeams();
+ _Buttons[_ButtonIncreaseTeams].Visible = _AllowChangePlayerNum && _Teams && _PartyMode.MinTeams != _PartyMode.MaxTeams;
+ _Buttons[_ButtonDecreaseTeams].Visible = _AllowChangePlayerNum && _Teams && _PartyMode.MinTeams != _PartyMode.MaxTeams;
_Buttons[_ButtonIncreasePlayer].Visible = _AllowChangePlayerNum;
_Buttons[_ButtonDecreasePlayer].Visible = _AllowChangePlayerNum;
}
private void _UpdateButtonState()
{
- _Buttons[_ButtonIncreaseTeams].Selectable = _NumTeams < _PartyMode.GetMaxTeams();
- _Buttons[_ButtonDecreaseTeams].Selectable = _NumTeams > _PartyMode.GetMinTeams();
+ _Buttons[_ButtonIncreaseTeams].Selectable = _NumTeams < _PartyMode.MaxTeams;
+ _Buttons[_ButtonDecreaseTeams].Selectable = _NumTeams > _PartyMode.MinTeams;
if (_NumPlayerTeams != null && _NumPlayerTeams.Length > _CurrentTeam)
{
- _Buttons[_ButtonIncreasePlayer].Selectable = _NumPlayerTeams[_CurrentTeam] < _PartyMode.GetMaxPlayerPerTeam();
- _Buttons[_ButtonDecreasePlayer].Selectable = _NumPlayerTeams[_CurrentTeam] > _PartyMode.GetMinPlayerPerTeam();
+ _Buttons[_ButtonIncreasePlayer].Selectable = _NumPlayerTeams[_CurrentTeam] < _PartyMode.MaxPlayersPerTeam;
+ _Buttons[_ButtonDecreasePlayer].Selectable = _NumPlayerTeams[_CurrentTeam] > _PartyMode.MinPlayersPerTeam;
}
else
{
@@ -723,7 +725,7 @@ namespace VocaluxeLib.Menu
{
if (_NumPlayerTeams[team] == _TeamList[team].Count && !_ChangePlayerNumDynamic)
return;
- if (_NumPlayerTeams[team] == _PartyMode.GetMaxPlayerPerTeam())
+ if (_NumPlayerTeams[team] == _PartyMode.MaxPlayersPerTeam)
return;
_NameSelections[_NameSelection].UseProfile(profileID);
diff --git a/VocaluxeLib/Menu/CPlaylist.cs b/VocaluxeLib/Menu/CPlaylist.cs
index 1280c513..4a7b28eb 100644
--- a/VocaluxeLib/Menu/CPlaylist.cs
+++ b/VocaluxeLib/Menu/CPlaylist.cs
@@ -1145,12 +1145,9 @@ namespace VocaluxeLib.Menu
string t1 = CBase.Language.Translate(_Text1.Text).Replace("%a", song.Artist).Replace("%t", song.Title);
_PlaylistElements[i].Text1.Text = /*(Offset + i + 1) + ") " + */ t1; //TODO: Add text field for the number
_PlaylistElements[i].SelectSlide.Clear();
- for (int g = 0; g < pec.Modes.Count; g++)
- {
- _PlaylistElements[i].SelectSlide.AddValue(Enum.GetName(typeof(EGameMode), pec.Modes[g]));
- if (pec.Modes[g] == pec.Mode)
- _PlaylistElements[i].SelectSlide.SetSelectionByValueIndex(g);
- }
+ foreach (EGameMode gm in pec.Modes)
+ _PlaylistElements[i].SelectSlide.AddValue(Enum.GetName(typeof(EGameMode), gm), null, (int)gm);
+ _PlaylistElements[i].SelectSlide.SelectedTag = (int)pec.Mode;
}
else
{
diff --git a/VocaluxeLib/Menu/CSelectSlide.cs b/VocaluxeLib/Menu/CSelectSlide.cs
index f5a876b0..64f39b08 100644
--- a/VocaluxeLib/Menu/CSelectSlide.cs
+++ b/VocaluxeLib/Menu/CSelectSlide.cs
@@ -17,6 +17,8 @@
using System;
using System.Collections.Generic;
+using System.ComponentModel;
+using System.Diagnostics;
using System.Drawing;
using System.Xml.Serialization;
using VocaluxeLib.Draw;
@@ -51,8 +53,8 @@ namespace VocaluxeLib.Menu
public SThemeColor TextSelColor;
public float TextH;
- public float TextRelativeX;
- public float TextRelativeY;
+ [DefaultValue(0.0f)] public float TextRelativeX;
+ [DefaultValue(0.0f)] public float TextRelativeY;
public float TextMaxW;
public string TextFont;
@@ -61,8 +63,23 @@ namespace VocaluxeLib.Menu
public int NumVisible;
}
- public sealed class CSelectSlide : CMenuElementBase, IMenuElement, ICloneable, IThemeable
+ public sealed class CSelectSlide : CMenuElementBase, IMenuElement, IThemeable
{
+ private struct SValue
+ {
+ public string Text;
+ public int TranslationId;
+ public int Tag;
+ public CTextureRef Texture;
+ }
+
+ private class CElement
+ {
+ public CText Text;
+ public CStatic Img;
+ public SRectF Bounds;
+ }
+
private readonly int _PartyModeID;
private SThemeSelectSlide _Theme;
@@ -138,52 +155,52 @@ namespace VocaluxeLib.Menu
}
}
}
- public bool ValueSelected
+ public bool IsValueSelected
{
get { return Selected && !_ArrowLeftSelected && !_ArrowRightSelected; }
}
- public bool SelectionByHover;
-
private bool _ArrowLeftSelected;
private bool _ArrowRightSelected;
- private readonly List _ValueNames;
- private readonly List _ValuePartyModeIDs;
- private readonly List _Textures;
- private readonly List _ValueIndexes;
-
- private readonly List _ValueBounds = new List();
-
- public bool WithTextures;
+ public bool SelectByHovering;
+ public bool DrawTextures;
private int _Selection = -1;
public int Selection
{
get { return _Selection; }
- set { _Selection = value.Clamp(0, _ValueNames.Count - 1, false); }
- }
-
- public string Value
- {
- get { return (_Selection >= 0 && _Selection < _ValueNames.Count) ? _ValueNames[_Selection] : null; }
- }
-
- public int ValueIndex
- {
- get
+ set
{
- if (_Selection >= 0 && _ValueIndexes.Count > _Selection)
- return _ValueIndexes[_Selection];
- return -1;
+ value = value.Clamp(0, _Values.Count - 1, false);
+ if (value == _Selection)
+ return;
+ _Selection = value;
+ _Invalidate();
}
}
+ public string SelectedValue
+ {
+ get { return _Selection >= 0 ? _Values[_Selection].Text : null; }
+ set { Selection = _Values.FindIndex(val => val.Text == value); }
+ }
+
+ public int SelectedTag
+ {
+ get { return _Selection >= 0 ? _Values[_Selection].Tag : -1; }
+ set { Selection = _Values.FindIndex(val => val.Tag == value); }
+ }
+
public int NumValues
{
- get { return _ValueNames.Count; }
+ get { return _Values.Count; }
}
+ private readonly List _Values = new List();
+ private readonly List _VisibleElements = new List();
+ private bool _NeedsRevalidate = true;
+
private int _NumVisible = -1;
private CTextureRef _Texture;
private CTextureRef _TextureArrowLeft;
@@ -197,10 +214,11 @@ namespace VocaluxeLib.Menu
get { return _NumVisible; }
set
{
- if (value > 0)
- _NumVisible = value;
+ if (value <= 0 || value == _NumVisible)
+ return;
+ _NumVisible = value;
- _ValueBounds.Clear();
+ _Invalidate();
}
}
@@ -210,11 +228,6 @@ namespace VocaluxeLib.Menu
ThemeLoaded = false;
_TextH = 1f;
_MaxW = 0f;
-
- _Textures = new List();
- _ValueIndexes = new List();
- _ValueNames = new List();
- _ValuePartyModeIDs = new List();
}
public CSelectSlide(CSelectSlide slide)
@@ -241,15 +254,11 @@ namespace VocaluxeLib.Menu
_TextRelativeY = slide._TextRelativeY;
_MaxW = slide._MaxW;
- _Textures = new List(slide._Textures);
- _ValueIndexes = new List(slide._ValueIndexes);
- _ValueNames = new List(slide._ValueNames);
- _ValueBounds = new List(slide._ValueBounds);
- _ValuePartyModeIDs = new List(slide._ValuePartyModeIDs);
+ _Values.AddRange(slide._Values);
_Selection = slide._Selection;
_NumVisible = slide._NumVisible;
- WithTextures = slide.WithTextures;
+ DrawTextures = slide.DrawTextures;
Visible = slide.Visible;
}
@@ -258,11 +267,6 @@ namespace VocaluxeLib.Menu
_PartyModeID = partyModeID;
_Theme = theme;
- _Textures = new List();
- _ValueIndexes = new List();
- _ValueNames = new List();
- _ValuePartyModeIDs = new List();
-
ThemeLoaded = true;
}
@@ -382,58 +386,73 @@ namespace VocaluxeLib.Menu
return ThemeLoaded;
}
- public void AddValue(string value)
+ private void _Invalidate()
{
- AddValue(value, _PartyModeID);
+ _NeedsRevalidate = true;
}
- public void AddValue(string value, int partyModeID)
+ ///
+ /// Adds an integer to the slide setting its tag to the value and its text to the text representation of the tag
+ ///
+ /// Value to add
+ public void AddValue(int tag)
{
- AddValue(value, null, _ValueIndexes.Count, partyModeID);
+ AddValue(tag.ToString(), null, tag);
}
- public void AddValue(string value, CTextureRef texture)
+ ///
+ /// Adds an entry to the slide.
+ ///
+ /// Label to show
+ /// Texture to show
+ /// User value (e.g. id of entry)
+ public void AddValue(string text, CTextureRef texture = null, int tag = 0)
{
- AddValue(value, texture, _ValueIndexes.Count, _PartyModeID);
+ AddValue(text, _PartyModeID, texture, tag);
}
- private void _AddValue(string value, CTextureRef texture, int valueIndex)
+ ///
+ /// Adds an entry to the slide.
+ ///
+ /// Label to show
+ /// Translation id to use for the text
+ /// Texture to show
+ /// User value (e.g. id of entry)
+ public void AddValue(string text, int translationId, CTextureRef texture = null, int tag = 0)
{
- AddValue(value, texture, valueIndex, _PartyModeID);
- }
+ SValue value = new SValue {Text = text, TranslationId = translationId, Tag = tag, Texture = texture};
- public void AddValue(string value, CTextureRef texture, int valueIndex, int partyModeID)
- {
- _ValueNames.Add(value);
- _Textures.Add(texture);
- _ValueIndexes.Add(valueIndex);
- _ValuePartyModeIDs.Add(partyModeID);
+ _Values.Add(value);
- if (Selection == -1)
+ if (Selection < 0)
Selection = 0;
- _ValueBounds.Clear();
+ _Invalidate();
}
public void AddValues(IEnumerable values)
{
foreach (string value in values)
- _AddValue(value, null, _PartyModeID);
-
- _ValueBounds.Clear();
+ AddValue(value);
}
public void AddValues(string[] values, CTextureRef[] textures)
{
- if (values.Length != textures.Length)
- return;
+ Debug.Assert(values.Length == textures.Length);
for (int i = 0; i < values.Length; i++)
AddValue(values[i], textures[i]);
- if (Selection == -1)
- Selection = 0;
+ }
- _ValueBounds.Clear();
+ public void RemoveValue(string text)
+ {
+ int idx = _Values.FindIndex(val => val.Text == text);
+ if (idx < 0)
+ return;
+ _Values.RemoveAt(idx);
+ if (Selection >= idx)
+ Selection--;
+ _Invalidate();
}
public void SetValues(int selection)
@@ -447,31 +466,20 @@ namespace VocaluxeLib.Menu
RenameValue(Selection, newName);
}
- public void RenameValue(int selection, string newName, CTextureRef newTexture = null)
+ public void RenameValue(int index, string newName, CTextureRef newTexture = null)
{
- if (selection < 0 && selection >= _ValueNames.Count)
+ if (index < 0 && index >= _Values.Count)
return;
- _ValueNames[selection] = newName;
- _Textures[selection] = newTexture;
- }
-
- public bool SetSelectionByValueIndex(int valueIndex)
- {
- for (int i = 0; i < _ValueIndexes.Count; i++)
- {
- if (_ValueIndexes[i] == valueIndex)
- {
- Selection = i;
- return true;
- }
- }
- return false;
+ SValue value = _Values[index];
+ value.Text = newName;
+ value.Texture = newTexture;
+ _Values[index] = value;
}
public bool SelectNextValue()
{
- if (Selection < _ValueNames.Count - 1)
+ if (Selection < _Values.Count - 1)
{
Selection++;
return true;
@@ -491,50 +499,46 @@ namespace VocaluxeLib.Menu
public void SelectFirstValue()
{
- if (_ValueNames.Count > 0)
+ if (_Values.Count > 0)
Selection = 0;
}
public void SelectLastValue()
{
- if (_ValueNames.Count > 0)
- Selection = _ValueNames.Count - 1;
+ if (_Values.Count > 0)
+ Selection = _Values.Count - 1;
}
public void Clear()
{
+ _Values.Clear();
_Selection = -1;
- _ValueNames.Clear();
- _Textures.Clear();
- _ValueBounds.Clear();
- _ValueIndexes.Clear();
+ _Invalidate();
+ }
+
+ private int _GetCurOffset()
+ {
+ int offset = _Selection - _NumVisible / 2;
+ return offset.Clamp(0, _Values.Count - _NumVisible, true);
+ }
+
+ private void _SelectAtPos(int x, int y)
+ {
+ if (_NeedsRevalidate)
+ _Revalidate();
+ int index = _VisibleElements.FindIndex(el => CHelper.IsInBounds(el.Bounds, x, y));
+ if (index < 0)
+ return;
+ Selection = index + _GetCurOffset();
}
public void ProcessMouseMove(int x, int y)
{
_ArrowLeftSelected = CHelper.IsInBounds(RectArrowLeft, x, y) && _Selection > 0;
- _ArrowRightSelected = CHelper.IsInBounds(RectArrowRight, x, y) && _Selection < _ValueNames.Count - 1;
+ _ArrowRightSelected = CHelper.IsInBounds(RectArrowRight, x, y) && _Selection < _Values.Count - 1;
- if (SelectionByHover)
- {
- for (int i = 0; i < _ValueBounds.Count; i++)
- {
- if (CHelper.IsInBounds(_ValueBounds[i], x, y))
- {
- int offset = _Selection - _NumVisible / 2;
-
- if (_ValueNames.Count - _NumVisible - offset < 0)
- offset = _ValueNames.Count - _NumVisible;
-
- if (offset < 0)
- offset = 0;
-
- Selection = i + offset;
- _ValueBounds.Clear();
- break;
- }
- }
- }
+ if (SelectByHovering)
+ _SelectAtPos(x, y);
}
public void ProcessMouseLBClick(int x, int y)
@@ -547,21 +551,78 @@ namespace VocaluxeLib.Menu
if (_ArrowRightSelected)
SelectNextValue();
- for (int i = 0; i < _ValueBounds.Count; i++)
+ _SelectAtPos(x, y);
+ }
+
+ private void _Revalidate()
+ {
+ if (!_NeedsRevalidate)
+ return;
+ _NeedsRevalidate = false;
+ int numvis = Math.Min(_NumVisible, _Values.Count);
+ if (numvis != _VisibleElements.Count)
{
- if (CHelper.IsInBounds(_ValueBounds[i], x, y))
+ _VisibleElements.Clear();
+ for (int i = 0; i < numvis; i++)
{
- int offset = _Selection - _NumVisible / 2;
+ var el = new CElement
+ {
+ Text = new CText(0, 0, 0, _TextH, _MaxW, EAlignment.Center, _Theme.TextStyle, _Theme.TextFont, _TextColor, "T", _PartyModeID),
+ Img = new CStatic(_PartyModeID)
+ };
+ _VisibleElements.Add(el);
+ }
+ }
+ if (numvis == 0)
+ return;
- if (_ValueNames.Count - _NumVisible - offset < 0)
- offset = _ValueNames.Count - _NumVisible;
+ float elWidth = (Rect.W - _TextRelativeX * 2) / numvis;
+ //Center point of the first entry
+ float xStart = Rect.X + _TextRelativeX + elWidth / 2f;
- if (offset < 0)
- offset = 0;
+ int offset = _GetCurOffset();
- Selection = i + offset;
- _ValueBounds.Clear();
- break;
+ for (int i = 0; i < numvis; i++)
+ {
+ CText text = _VisibleElements[i].Text;
+ RectangleF textBounds;
+ float curX = xStart + elWidth * i;
+ if (String.IsNullOrEmpty(_Values[i + offset].Text))
+ {
+ text.Visible = false;
+ textBounds = new RectangleF();
+ }
+ else
+ {
+ text.Visible = true;
+ text.Text = _Values[i + offset].Text;
+ text.TranslationID = _Values[i + offset].TranslationId;
+ text.Color = (i + offset == Selection) ? _SelTextColor : _TextColor;
+ textBounds = CBase.Fonts.GetTextBounds(text);
+ text.X = curX;
+ text.Z = Rect.Z;
+ }
+
+ CStatic img = _VisibleElements[i].Img;
+ if (!DrawTextures || _Values[i + offset].Texture == null)
+ {
+ if (text.Visible)
+ text.Y = Rect.Y + (Rect.H - textBounds.Height) / 2 - _TextRelativeY;
+ img.Visible = false;
+ _VisibleElements[i].Bounds = new SRectF(text.X - textBounds.Width / 2f, text.Y, textBounds.Width, textBounds.Height, Rect.Z);
+ }
+ else
+ {
+ text.Y = (int)(Rect.Y + Rect.H - textBounds.Height - _TextRelativeY);
+ img.Texture = _Values[i + offset].Texture;
+ float alpha = (i + offset == _Selection) ? 1f : 0.35f;
+ img.Color = new SColorF(1f, 1f, 1f, alpha);
+ float size = Rect.H - textBounds.Height - 2 * _TextRelativeY;
+ if (size > elWidth)
+ size = elWidth;
+ var imgRect = new SRectF(curX - size / 2, Rect.Y + _TextRelativeY, size, size, Rect.Z);
+ img.MaxRect = imgRect;
+ _VisibleElements[i].Bounds = imgRect;
}
}
}
@@ -584,7 +645,7 @@ namespace VocaluxeLib.Menu
CBase.Drawing.DrawTexture(_TextureArrowLeft, RectArrowLeft, _ColorArrow);
}
- if (_Selection < _ValueNames.Count - 1 || CBase.Settings.GetProgramState() == EProgramState.EditTheme)
+ if (_Selection < _Values.Count - 1 || CBase.Settings.GetProgramState() == EProgramState.EditTheme)
{
if (_ArrowRightSelected)
CBase.Drawing.DrawTexture(_SelTextureArrowRight, RectArrowRight, _SelColorArrow);
@@ -592,63 +653,12 @@ namespace VocaluxeLib.Menu
CBase.Drawing.DrawTexture(_TextureArrowRight, RectArrowRight, _ColorArrow);
}
- if (_NumVisible < 1 || _ValueNames.Count == 0)
- return;
-
- float x = Rect.X + (Rect.W - _TextRelativeX) * 0.1f;
- float dx = (Rect.W - _TextRelativeX) * 0.8f / _NumVisible;
- //float y = Rect.Y + (Rect.H - TextH);
- int offset = _Selection - _NumVisible / 2;
-
- if (_ValueNames.Count - _NumVisible - offset < 0)
- offset = _ValueNames.Count - _NumVisible;
-
- if (offset < 0)
- offset = 0;
-
-
- int numvis = _NumVisible;
- if (_ValueNames.Count < numvis)
- numvis = _ValueNames.Count;
-
- _ValueBounds.Clear();
- for (int i = 0; i < numvis; i++)
+ if (_NeedsRevalidate)
+ _Revalidate();
+ foreach (CElement element in _VisibleElements)
{
- var text = new CText(0, 0, 0, _TextH, _MaxW, EAlignment.Center, _Theme.TextStyle, _Theme.TextFont, _TextColor, "T",
- _ValuePartyModeIDs[i + offset]);
-
- if (_ValueNames[i + offset] != "")
- text.Text = _ValueNames[i + offset];
- else
- text.Visible = false;
-
- var alpha = new SColorF(1f, 1f, 1f, 0.35f);
- if (i + offset == _Selection)
- {
- text.Color = _SelTextColor;
- alpha = new SColorF(1f, 1f, 1f, 1f);
- }
-
- RectangleF bounds = CBase.Fonts.GetTextBounds(text);
- text.X = (x + dx / 2f + dx * i) + _TextRelativeX;
-
- if (!WithTextures)
- text.Y = (int)((Rect.Y + (Rect.H - bounds.Height) / 2) + _TextRelativeY);
- else
- text.Y = (int)((Rect.Y + (Rect.H - bounds.Height)) + _TextRelativeY);
-
- text.Z = Rect.Z;
- text.Draw();
-
- if (WithTextures)
- {
- float dh = text.Y - Rect.Y - Rect.H * 0.1f;
- var rect = new SRectF(text.X - dh / 2, Rect.Y + Rect.H * 0.05f, dh, dh, Rect.Z);
- CBase.Drawing.DrawTexture(_Textures[i + offset], rect, alpha, rect);
- _ValueBounds.Add(rect);
- }
- else
- _ValueBounds.Add(new SRectF(text.X - bounds.Width / 2f, text.Y, bounds.Width, bounds.Height, Rect.Z));
+ element.Text.Draw();
+ element.Img.Draw();
}
}
@@ -686,6 +696,7 @@ namespace VocaluxeLib.Menu
_SelTexture = CBase.Themes.GetSkinTexture(_Theme.SkinSelected, _PartyModeID);
_SelTextureArrowLeft = CBase.Themes.GetSkinTexture(_Theme.SkinArrowLeftSelected, _PartyModeID);
_SelTextureArrowRight = CBase.Themes.GetSkinTexture(_Theme.SkinArrowRightSelected, _PartyModeID);
+ _Invalidate();
}
public void ReloadSkin()
@@ -694,11 +705,6 @@ namespace VocaluxeLib.Menu
LoadSkin();
}
- public object Clone()
- {
- return MemberwiseClone();
- }
-
#region ThemeEdit
public void MoveElement(int stepX, int stepY)
{
diff --git a/VocaluxeLib/Menu/SingNotes/CSingNotes.cs b/VocaluxeLib/Menu/SingNotes/CSingNotes.cs
index 4d072af0..71c09fdc 100644
--- a/VocaluxeLib/Menu/SingNotes/CSingNotes.cs
+++ b/VocaluxeLib/Menu/SingNotes/CSingNotes.cs
@@ -17,6 +17,8 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
using System.Xml.Serialization;
using VocaluxeLib.Xml;
@@ -56,6 +58,12 @@ namespace VocaluxeLib.Menu.SingNotes
public readonly List PlayerNotes = new List();
+ private SRectF _Rect;
+ public override SRectF Rect
+ {
+ get { return _Rect; }
+ }
+
public bool Selectable
{
get { return false; }
@@ -143,6 +151,16 @@ namespace VocaluxeLib.Menu.SingNotes
PlayerNotes.Clear();
for (int p = 0; p < numPlayers; p++)
PlayerNotes.Add(new CNoteBars(_PartyModeID, p, _BarPos[p, numPlayers - 1], _Theme));
+ if (numPlayers == 0)
+ _Rect = new SRectF(0, 0, 0, 0, Rect.Z);
+ else
+ {
+ _Rect.X = PlayerNotes.Select(bp => bp.Rect.X).Min();
+ _Rect.Y = PlayerNotes.Select(bp => bp.Rect.X).Min();
+ _Rect.Right = PlayerNotes.Select(bp => bp.Rect.Right).Max();
+ _Rect.Bottom = PlayerNotes.Select(bp => bp.Rect.Bottom).Max();
+ _Rect.Z = PlayerNotes.Select(bp => bp.Rect.Z).Average();
+ }
}
public void Draw()
@@ -155,6 +173,12 @@ namespace VocaluxeLib.Menu.SingNotes
public void LoadSkin()
{
+ Debug.Assert(_Theme.BarPos.Length > 0);
+ X = _Theme.BarPos.Select(bp => bp.Rect.X).Min();
+ Y = _Theme.BarPos.Select(bp => bp.Rect.X).Min();
+ W = X - _Theme.BarPos.Select(bp => bp.Rect.Right).Max();
+ H = Y - _Theme.BarPos.Select(bp => bp.Rect.Bottom).Max();
+ Z = _Theme.BarPos.Select(bp => bp.Rect.Z).Average();
foreach (SBarPosition bp in _Theme.BarPos)
{
int n = Int32.Parse(bp.Name.Substring(3, 1)) - 1;
diff --git a/VocaluxeLib/PartyModes/CPartyMode.cs b/VocaluxeLib/PartyModes/CPartyMode.cs
index 14192af7..5a4d2b14 100644
--- a/VocaluxeLib/PartyModes/CPartyMode.cs
+++ b/VocaluxeLib/PartyModes/CPartyMode.cs
@@ -16,21 +16,20 @@
#endregion
using System.Collections.Generic;
+using System.Diagnostics;
using VocaluxeLib.Menu;
namespace VocaluxeLib.PartyModes
{
public abstract class CPartyMode : IPartyMode
{
- private readonly string _Folder;
private readonly int _ID;
protected SScreenSongOptions _ScreenSongOptions = new SScreenSongOptions {Selection = new SSelectionOptions(), Sorting = new SSortingOptions()};
protected readonly Dictionary _Screens = new Dictionary();
- protected CPartyMode(int id, string folder)
+ protected CPartyMode(int id)
{
_ID = id;
- _Folder = folder;
}
#region Implementation
@@ -39,7 +38,15 @@ namespace VocaluxeLib.PartyModes
get { return _ID; }
}
- public abstract bool Init();
+ public int NumPlayers { get; set; }
+ public int NumTeams { get; set; }
+
+ public virtual bool Init()
+ {
+ Debug.Assert(MinPlayers > 0 && MinPlayers <= MaxPlayers);
+ Debug.Assert(MinTeams > 0 && MinTeams <= MaxTeams);
+ return true;
+ }
public void LoadTheme()
{
@@ -75,61 +82,6 @@ namespace VocaluxeLib.PartyModes
entry.Value.SaveTheme();
}
- public virtual void UpdateGame() {}
-
- public abstract IMenu GetStartScreen();
-
- public virtual SScreenSongOptions GetScreenSongOptions()
- {
- return new SScreenSongOptions();
- }
-
- public virtual void OnSongChange(int songIndex, ref SScreenSongOptions screenSongOptions) {}
-
- public virtual void OnCategoryChange(int categoryIndex, ref SScreenSongOptions screenSongOptions) {}
-
- public virtual int GetMaxPlayer()
- {
- return 6;
- }
-
- public virtual int GetMinPlayer()
- {
- return 1;
- }
-
- public virtual int GetMaxTeams()
- {
- return 0;
- }
-
- public virtual int GetMinTeams()
- {
- return 0;
- }
-
- public virtual int GetMinPlayerPerTeam()
- {
- return GetMinPlayer();
- }
-
- public virtual int GetMaxPlayerPerTeam()
- {
- return GetMaxPlayer();
- }
-
- public virtual int GetMaxNumRounds()
- {
- return 1;
- }
-
- public string GetFolder()
- {
- return _Folder;
- }
-
- public virtual void SetSearchString(string searchString, bool visible) {}
-
public virtual void JokerUsed(int teamNr)
{
if (_ScreenSongOptions.Selection.NumJokers == null)
@@ -142,8 +94,6 @@ namespace VocaluxeLib.PartyModes
_ScreenSongOptions.Selection.NumJokers[teamNr]--;
}
- public abstract void SongSelected(int songID);
-
public virtual void FinishedSinging()
{
CBase.Graphics.FadeTo(EScreen.Score);
@@ -159,5 +109,25 @@ namespace VocaluxeLib.PartyModes
CBase.Graphics.FadeTo(EScreen.Song);
}
#endregion Implementation
+
+ #region Abstract members
+ public abstract int MinMics { get; }
+ public abstract int MaxMics { get; }
+ public abstract int MinPlayers { get; }
+ public abstract int MaxPlayers { get; }
+ public abstract int MinTeams { get; }
+ public abstract int MaxTeams { get; }
+ public abstract int MinPlayersPerTeam { get; }
+ public abstract int MaxPlayersPerTeam { get; }
+
+ public abstract void UpdateGame();
+ public abstract IMenu GetStartScreen();
+ public abstract SScreenSongOptions GetScreenSongOptions();
+ public abstract void OnSongChange(int songIndex, ref SScreenSongOptions screenSongOptions);
+ public abstract void OnCategoryChange(int categoryIndex, ref SScreenSongOptions screenSongOptions);
+ public abstract void SetSearchString(string searchString, bool visible);
+
+ public abstract void SongSelected(int songID);
+ #endregion Abstract members
}
}
\ No newline at end of file
diff --git a/VocaluxeLib/PartyModes/CPartyModeNone.cs b/VocaluxeLib/PartyModes/CPartyModeNormal.cs
similarity index 68%
rename from VocaluxeLib/PartyModes/CPartyModeNone.cs
rename to VocaluxeLib/PartyModes/CPartyModeNormal.cs
index c3e3ea6a..a84ecb73 100644
--- a/VocaluxeLib/PartyModes/CPartyModeNone.cs
+++ b/VocaluxeLib/PartyModes/CPartyModeNormal.cs
@@ -20,10 +20,42 @@ using VocaluxeLib.Menu;
namespace VocaluxeLib.PartyModes
{
- public class CPartyModeNone : CPartyMode
+ public class CPartyModeNormal : CPartyMode
{
- //just a dummy for normal game mode
- public CPartyModeNone(int id, string folder) : base(id, folder)
+ public override int MinMics
+ {
+ get { return 1; }
+ }
+ public override int MaxMics
+ {
+ get { return CBase.Config.GetMaxNumMics(); }
+ }
+ public override int MinPlayers
+ {
+ get { return 1; }
+ }
+ public override int MaxPlayers
+ {
+ get { return CBase.Settings.GetMaxNumPlayer(); }
+ }
+ public override int MinTeams
+ {
+ get { return 1; }
+ }
+ public override int MaxTeams
+ {
+ get { return 1; }
+ }
+ public override int MinPlayersPerTeam
+ {
+ get { return MinPlayers; }
+ }
+ public override int MaxPlayersPerTeam
+ {
+ get { return MaxPlayers; }
+ }
+
+ public CPartyModeNormal(int id) : base(id)
{
_ScreenSongOptions.Selection.RandomOnly = false;
_ScreenSongOptions.Selection.PartyMode = false;
@@ -42,6 +74,8 @@ namespace VocaluxeLib.PartyModes
return true;
}
+ public override void UpdateGame() {}
+
public override IMenu GetStartScreen()
{
return CBase.Graphics.GetScreen(EScreen.Names);
@@ -60,6 +94,10 @@ namespace VocaluxeLib.PartyModes
return _ScreenSongOptions;
}
+ public override void OnSongChange(int songIndex, ref SScreenSongOptions screenSongOptions) {}
+
+ public override void OnCategoryChange(int categoryIndex, ref SScreenSongOptions screenSongOptions) {}
+
public override void SetSearchString(string searchString, bool visible)
{
_ScreenSongOptions.Sorting.SearchString = searchString;
diff --git a/VocaluxeLib/PartyModes/IPartyMode.cs b/VocaluxeLib/PartyModes/IPartyMode.cs
index d432e368..d1aa7e1f 100644
--- a/VocaluxeLib/PartyModes/IPartyMode.cs
+++ b/VocaluxeLib/PartyModes/IPartyMode.cs
@@ -79,9 +79,24 @@ namespace VocaluxeLib.PartyModes
}
#endregion Structs
- public interface IPartyMode
+ public interface IPartyModeInfo
{
int ID { get; }
+ int MinMics { get; }
+ int MaxMics { get; }
+ int MinPlayers { get; }
+ int MaxPlayers { get; }
+ int MinTeams { get; }
+ int MaxTeams { get; }
+ int MinPlayersPerTeam { get; }
+ int MaxPlayersPerTeam { get; }
+ }
+
+ public interface IPartyMode : IPartyModeInfo
+ {
+ int NumPlayers { get; set; }
+ int NumTeams { get; set; }
+
bool Init();
void LoadTheme();
@@ -99,14 +114,6 @@ namespace VocaluxeLib.PartyModes
void OnSongChange(int songIndex, ref SScreenSongOptions screenSongOptions);
void OnCategoryChange(int categoryIndex, ref SScreenSongOptions screenSongOptions);
- int GetMaxPlayer();
- int GetMinPlayer();
- int GetMaxTeams();
- int GetMinTeams();
- int GetMinPlayerPerTeam();
- int GetMaxPlayerPerTeam();
- int GetMaxNumRounds();
-
void SetSearchString(string searchString, bool visible);
void JokerUsed(int teamNr);
diff --git a/VocaluxeLib/Songs/CLineBase.cs b/VocaluxeLib/Songs/CLineBase.cs
index 6c972851..577f732e 100644
--- a/VocaluxeLib/Songs/CLineBase.cs
+++ b/VocaluxeLib/Songs/CLineBase.cs
@@ -75,10 +75,10 @@ namespace VocaluxeLib.Songs
#region Methods
///
- /// Find last note with StartBeat
+ /// Find last note with StartBeat <= beat
///
///
- /// Note index of last note with StartBeat or -1 if all notes start after beat
+ /// Note index of last note with StartBeat <= beat or -1 if all notes start after beat
public int FindPreviousNote(int beat)
{
//If no notes -> No previous note
diff --git a/VocaluxeLib/Structs.cs b/VocaluxeLib/Structs.cs
index d59163a3..09a1b960 100644
--- a/VocaluxeLib/Structs.cs
+++ b/VocaluxeLib/Structs.cs
@@ -186,6 +186,7 @@ namespace VocaluxeLib
public float Z;
[XmlIgnore] public float Rotation; //0..360°
+ [XmlIgnore]
public float Right
{
get { return X + W; }
@@ -195,6 +196,8 @@ namespace VocaluxeLib
Debug.Assert(W >= 0);
}
}
+
+ [XmlIgnore]
public float Bottom
{
get { return Y + H; }
@@ -204,10 +207,14 @@ namespace VocaluxeLib
Debug.Assert(H >= 0);
}
}
+
+ [XmlIgnore]
public Size SizeI
{
get { return new Size((int)W, (int)H); }
}
+
+ [XmlIgnore]
public SizeF Size
{
get { return new SizeF(W, H); }
diff --git a/VocaluxeLib/Utils/Combinatorics/CCombinations.cs b/VocaluxeLib/Utils/Combinatorics/CCombinations.cs
new file mode 100644
index 00000000..78e5c0b7
--- /dev/null
+++ b/VocaluxeLib/Utils/Combinatorics/CCombinations.cs
@@ -0,0 +1,157 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+
+namespace VocaluxeLib.Utils.Combinatorics
+{
+ ///
+ /// Calculates all combinations (without repetition) of a given input sequence
+ /// Example: {A B C}, select 2 --> {A B}, {A C}, {B C}
+ ///
+ /// Type of the input elements
+ public class CCombinations : IEnumerable>
+ {
+ private readonly List _Values;
+ private readonly int _NumSelected;
+ private readonly int _Count;
+
+ ///
+ /// Construct combinations for the input sequence when selecting numSelected elements
+ /// The values should not contain duplicates as this will result in duplicates in the output
+ ///
+ /// Input sequence
+ /// Number of elements to select
+ public CCombinations(List values, int numSelected)
+ {
+ _Values = values;
+ _NumSelected = numSelected;
+ // This also acts as a parameter check
+ _Count = Count(_Values.Count, _NumSelected);
+ }
+
+ ///
+ /// Calculates how many combinations are possible when k out of n elements are selected
+ ///
+ /// Number of elements
+ /// Number of selected elements
+ ///
+ public static int Count(int n, int k)
+ {
+ if (n < 0 || k < 0)
+ throw new ArgumentException("Parameters must not be negative");
+ if (n < k)
+ return 0;
+ // Try to optimize because (n k) = (n n-k)
+ if (n - k < k)
+ k = n - k;
+ if (k == 0) // or k == n but both are the same after the optimization above
+ return 1;
+
+ long result = n;
+ for (long i = 1; i < k; i++)
+ {
+ checked
+ {
+ result = result * (n - i) / (i + 1);
+ }
+ }
+ return (int)result;
+ }
+
+ ///
+ /// Gets the number of combinations that are generated
+ ///
+ ///
+ public int Count()
+ {
+ return _Count;
+ }
+
+ ///
+ /// Gets all possible combinations as a list
+ ///
+ ///
+ public List> GetAll()
+ {
+ List> result = new List>(Count());
+ result.AddRange(this);
+ return result;
+ }
+
+ public IEnumerator> GetEnumerator()
+ {
+ return new CEnumerator(this);
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ private class CEnumerator : IEnumerator>
+ {
+ private readonly int _N;
+ private readonly int _K;
+ private readonly CCombinations _Parent;
+ private int[] _CurSet;
+
+ public CEnumerator(CCombinations parent)
+ {
+ _N = parent._Values.Count;
+ _K = parent._NumSelected;
+ _Parent = parent;
+ Debug.Assert(_N >= 0 && _K >= 0);
+ }
+
+ public void Dispose() {}
+
+ public bool MoveNext()
+ {
+ if (_N < _K)
+ return false;
+
+ if (_CurSet == null)
+ {
+ _CurSet = new int[_K];
+ for (int i = 0; i < _K; i++)
+ _CurSet[i] = i;
+ return true;
+ }
+
+ // Check if we reached the end
+ if (_K == 0 || _CurSet[0] == _N - _K)
+ return false;
+ // Search for element to increment
+ int idx = _K - 1;
+ while (idx > 0 && _CurSet[idx] == _N - _K + idx)
+ idx--;
+ _CurSet[idx]++;
+ // Increment all elements "right" of this to 1+their left neighbour
+ for (int j = idx; j < _K - 1; j++)
+ _CurSet[j + 1] = _CurSet[j] + 1;
+ return true;
+ }
+
+ public void Reset()
+ {
+ _CurSet = null;
+ }
+
+ public List Current
+ {
+ get
+ {
+ List result = new List(_K);
+ result.AddRange(_CurSet.Select(i => _Parent._Values[i]));
+ return result;
+ }
+ }
+ object IEnumerator.Current
+ {
+ get { return Current; }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/VocaluxeLib/VocaluxeLib.csproj b/VocaluxeLib/VocaluxeLib.csproj
index b452b5e5..e1faa2d8 100644
--- a/VocaluxeLib/VocaluxeLib.csproj
+++ b/VocaluxeLib/VocaluxeLib.csproj
@@ -108,6 +108,7 @@
+
@@ -138,7 +139,7 @@
-
+
diff --git a/VocaluxeLib/Xml/CXmlDeserializer.cs b/VocaluxeLib/Xml/CXmlDeserializer.cs
index cc51c26f..df8c7879 100644
--- a/VocaluxeLib/Xml/CXmlDeserializer.cs
+++ b/VocaluxeLib/Xml/CXmlDeserializer.cs
@@ -86,14 +86,14 @@ namespace VocaluxeLib.Xml
}
#endregion Debug Helpers
- private readonly XmlNode _Node;
+ public readonly XmlNode Node;
public readonly bool IsError;
public CXmlException(string msg, XmlNode node, bool isError = true)
: base(msg)
{
IsError = isError;
- _Node = node;
+ Node = node;
}
public override string Message
@@ -103,12 +103,22 @@ namespace VocaluxeLib.Xml
public override String ToString()
{
- string xPath = _Node == null ? "" : _GetXPath(_Node);
+ string xPath = Node == null ? "" : _GetXPath(Node);
string type = IsError ? "Error" : "Warning";
return type + ": " + base.Message.Replace("%n", xPath);
}
}
+ public class CXmlMissingElementException : CXmlException
+ {
+ public readonly SFieldInfo Field;
+
+ public CXmlMissingElementException(XmlNode parent, SFieldInfo field, bool isError = true) : base("Element: " + field.Name + " is missing in %n", parent, isError)
+ {
+ Field = field;
+ }
+ }
+
public class CXmlInvalidValueException : CXmlException
{
private readonly string _Value;
@@ -157,9 +167,9 @@ namespace VocaluxeLib.Xml
public class CXmlDeserializer
{
- private class CXmlDefaultErrorHandler : IXmlErrorHandler
+ public class CXmlDefaultErrorHandler : IXmlErrorHandler
{
- public void HandleError(CXmlException e)
+ public virtual void HandleError(CXmlException e)
{
if (e.IsError)
throw e;
@@ -421,7 +431,7 @@ namespace VocaluxeLib.Xml
Dictionary>> embLists = new Dictionary>>();
foreach (XmlNode node in nodes)
{
- if (node is XmlComment)
+ if (node is XmlComment || node.LocalName == "xsd" || node.LocalName == "xsi")
continue;
SFieldInfo field = new SFieldInfo();
@@ -505,7 +515,7 @@ namespace VocaluxeLib.Xml
if (!_CheckAndSetDefaultValue(o, field))
{
if (parent != null)
- _ErrorHandler.HandleError(new CXmlException("element: " + field.Name + " is missing in %n", parent));
+ _ErrorHandler.HandleError(new CXmlMissingElementException(parent, field));
object value = _GetValue(null, field.Type, field.ArrayItemName, field.GetValue(o));
if (value != null)
field.SetValue(o, value);
diff --git a/VocaluxeTests/CTestHelpers.cs b/VocaluxeTests/CTestHelpers.cs
new file mode 100644
index 00000000..4ad00bf3
--- /dev/null
+++ b/VocaluxeTests/CTestHelpers.cs
@@ -0,0 +1,21 @@
+using System;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+namespace VocaluxeTests
+{
+ static class CTestHelpers
+ {
+ public static void AssertFail(Action test) where T : Exception
+ {
+ try
+ {
+ test.Invoke();
+ Assert.Fail("Exception " + typeof(T).Name + " not thrown!");
+ }
+ catch (Exception e)
+ {
+ Assert.IsInstanceOfType(e, typeof(T));
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/VocaluxeTests/CombinatoricsTest.cs b/VocaluxeTests/CombinatoricsTest.cs
new file mode 100644
index 00000000..50d274e1
--- /dev/null
+++ b/VocaluxeTests/CombinatoricsTest.cs
@@ -0,0 +1,75 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using VocaluxeLib.Utils.Combinatorics;
+
+namespace VocaluxeTests
+{
+ [TestClass]
+ public class CCombinatoricsTest
+ {
+ [TestMethod]
+ public void TestCounts()
+ {
+ Assert.AreEqual(4, CCombinations.Count(4, 3));
+ Assert.AreEqual(6, CCombinations.Count(4, 2));
+ Assert.AreEqual(66, CCombinations.Count(12, 2));
+ // Corner cases
+ for (int i = 1; i < 12; i++)
+ {
+ Assert.AreEqual(1, CCombinations.Count(i, 0));
+ Assert.AreEqual(1, CCombinations.Count(i, i));
+ Assert.AreEqual(0, CCombinations.Count(i, i + 1));
+ }
+ // Check identity (n k) = (n n-k)
+ for (int i = 0; i <= 12; i++)
+ Assert.AreEqual(CCombinations.Count(12, i), CCombinations.Count(12, 12 - i));
+ CTestHelpers.AssertFail(() => CCombinations.Count(-1, -1));
+ CTestHelpers.AssertFail(() => CCombinations.Count(-1, 1));
+ CTestHelpers.AssertFail(() => CCombinations.Count(1, -1));
+ }
+
+ // ReSharper disable UnusedParameter.Local
+ private static void _CheckResults(CCombinations combs, List input)
+ // ReSharper restore UnusedParameter.Local
+ {
+ List> results = new List>();
+ foreach (List comb in combs)
+ {
+ foreach (List other in results)
+ Assert.IsFalse(other.SequenceEqual(comb), "Result must be unique");
+ for (int i = 0; i < comb.Count - 1; i++)
+ {
+ Assert.IsTrue(comb.IndexOf(comb[i], i + 1) < 0, "Repetition not allowed");
+ Assert.IsTrue(input.Contains(comb[i]), "Output must be in input sequence");
+ }
+ results.Add(comb);
+ }
+ Assert.AreEqual(combs.Count(), results.Count);
+ List> results2 = combs.GetAll();
+ Assert.AreEqual(results.Count, results2.Count);
+ for (int i = 0; i < results2.Count; i++)
+ Assert.IsTrue(results[i].SequenceEqual(results2[i]));
+ }
+
+ [TestMethod]
+ public void TestResults()
+ {
+ Random rand = new Random();
+ for (int n = 0; n < 8; n++)
+ {
+ for (int k = 0; k <= n; k++)
+ {
+ List collection = new List(n);
+ int r = rand.Next(1000);
+ for (int i = 0; i < n; i++)
+ collection.Add(i + r);
+ CCombinations combs = new CCombinations(collection, k);
+ Assert.AreEqual(CCombinations.Count(n, k), combs.Count());
+ _CheckResults(combs, collection);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/VocaluxeTests/PartyModeTests.cs b/VocaluxeTests/PartyModeTests.cs
new file mode 100644
index 00000000..1678b7ff
--- /dev/null
+++ b/VocaluxeTests/PartyModeTests.cs
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+using Vocaluxe.Base;
+using VocaluxeLib;
+using VocaluxeLib.PartyModes.Challenge;
+
+namespace VocaluxeTests
+{
+ [TestClass]
+ public class CPartyModeTests
+ {
+ [TestMethod]
+ public void TestRoundBoundaries()
+ {
+ // ReSharper disable ObjectCreationAsStatement
+ new CChallengeRounds(1, 1, 1); // Should succeed
+ // ReSharper restore ObjectCreationAsStatement
+ for (int inv = -1; inv <= 0; inv++)
+ {
+ int invL = inv;
+ CTestHelpers.AssertFail(() => new CChallengeRounds(invL, 1, 1));
+ CTestHelpers.AssertFail(() => new CChallengeRounds(1, invL, 1));
+ CTestHelpers.AssertFail(() => new CChallengeRounds(1, 1, invL));
+ }
+ }
+
+ private static void _CheckRounds(CChallengeRounds rounds, int numPlayer)
+ {
+ List numSongs = new List(numPlayer);
+ for (int i = 0; i < numPlayer; i++)
+ numSongs.Add(0);
+ for (int i = 0; i < rounds.Count; i++)
+ {
+ foreach (int player in rounds[i].Players)
+ {
+ Assert.IsTrue(player >= 0 && player < numPlayer);
+ numSongs[player]++;
+ }
+ }
+ Assert.IsTrue(numSongs.Min() == numSongs.Max(), "Some players have more songs than others");
+ }
+
+ [TestMethod]
+ public void TestRoundGeneration()
+ {
+ CBase.Game = new CBGame();
+ CLog.Init();
+ CBase.Log = new CBlog();
+ for (int i = 0; i < 10; i++)
+ {
+ for (int numPlayer = 1; numPlayer <= 20; numPlayer++)
+ {
+ for (int numMic = 1; numMic <= 6; numMic++)
+ {
+ int roundFactor = (numPlayer % numMic == 0) ? numPlayer / numMic : numPlayer;
+ for (int numRounds = roundFactor; numRounds <= 100 && numRounds <= roundFactor * 5; numRounds += roundFactor)
+ {
+ CChallengeRounds rounds = new CChallengeRounds(numRounds, numPlayer, numMic);
+ Assert.IsTrue(rounds.Count >= numRounds);
+ _CheckRounds(rounds, numPlayer);
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/VocaluxeTests/VocaluxeTests.csproj b/VocaluxeTests/VocaluxeTests.csproj
index b3a0dade..88233b22 100644
--- a/VocaluxeTests/VocaluxeTests.csproj
+++ b/VocaluxeTests/VocaluxeTests.csproj
@@ -70,10 +70,17 @@
+
+
+
+
+ {5a4053f1-5ad5-441f-b254-d97a088127b6}
+ PartyModeChallenge
+
{d2b6ddef-e0e1-4ddf-a73a-e6acef5c95ec}
VocaluxeLib
diff --git a/VocaluxeTests/XmlSerializerTest.cs b/VocaluxeTests/XmlSerializerTest.cs
index 6b59e5ec..56e45410 100644
--- a/VocaluxeTests/XmlSerializerTest.cs
+++ b/VocaluxeTests/XmlSerializerTest.cs
@@ -91,8 +91,7 @@ namespace VocaluxeTests
private struct SDefaultSub
{
- [DefaultValue(111)]
- public int I;
+ [DefaultValue(111)] public int I;
}
private struct SDefault
@@ -107,23 +106,10 @@ namespace VocaluxeTests
#pragma warning restore 169
#pragma warning restore 649
- private static void _AssertFail(Action test) where T : Exception
- {
- try
- {
- test.Invoke();
- Assert.Fail("Exception " + typeof(T).Name + " not thrown!");
- }
- catch (Exception e)
- {
- Assert.IsInstanceOfType(e, typeof(T));
- }
- }
-
private static void _AssertFail(String xmlString) where T2 : Exception where T : new()
{
var deserializer = new CXmlDeserializer();
- _AssertFail(() => deserializer.DeserializeString(xmlString));
+ CTestHelpers.AssertFail(() => deserializer.DeserializeString(xmlString));
}
private static T _AssertSerDeserMatch(string xmlString) where T : new()
@@ -454,7 +440,7 @@ namespace VocaluxeTests
Assert.AreEqual(foo.D, 666);
Assert.AreEqual(foo.Sub.I, 111);
string newXml = new CXmlSerializer().Serialize(foo);
- Assert.AreEqual(_Head +@"
+ Assert.AreEqual(_Head + @"
", newXml);
}