Apply R# clean-up for reliability (#877)
* Apply R# clean-up for reliability - Migrate to NUnit4 Assert.That - Update dependencise versions - Fix LangVersion to 9.0 (until net core migration) - Reformat code - Apply 'var' style (easier for refactoring) - Remove redundant parentheses - Add braces on every condition blocks (1 line) - Uses new null checking patterns - Uses AutoProperties when possible - Uses string scalar type instead of class - Clean usings - Add .orig files in git ignore - Rename some properties to respect defined conventions and US format definition - ID -> Id - BPM -> Bpm - Finish -> End * Update R# settings according to the clean-up made
This commit is contained in:
1 parent
b9b0f7c8df
commit
6ffa63b923
236 files changed
+14194
-7278
No files matched your search
+3
-1
@@ -74,4 +74,6 @@ tx.exe
|
||||
/PitchTracker/bin
|
||||
/PitchTracker/obj
|
||||
/Logs
|
||||
/Tests/bin
|
||||
/Tests/bin
|
||||
*.orig
|
||||
*.DotSettings
|
||||
@@ -40,16 +40,20 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
public CChallengeRounds(int numRounds, int numPlayer, int playersPerRound)
|
||||
{
|
||||
if (numRounds < 1 || numPlayer < 1 || playersPerRound < 1)
|
||||
{
|
||||
throw new ArgumentException("Invalid paramters for the rounds");
|
||||
}
|
||||
|
||||
if (playersPerRound > numPlayer)
|
||||
{
|
||||
playersPerRound = numPlayer;
|
||||
}
|
||||
|
||||
_BuildRounds(numRounds, numPlayer, playersPerRound);
|
||||
if (Count > numRounds)
|
||||
{
|
||||
//Try again and take the better one
|
||||
List<CRound> old = new List<CRound>(_Rounds);
|
||||
var old = new List<CRound>(_Rounds);
|
||||
_Rounds.Clear();
|
||||
_BuildRounds(numRounds, numPlayer, playersPerRound);
|
||||
if (Count > old.Count)
|
||||
@@ -66,50 +70,60 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
/// <param name="numSung">List matching the playerIndex to the number of songs sung</param>
|
||||
private static List<int> _GetPlayersForRound(IList<int> numSung)
|
||||
{
|
||||
List<int> mustSing = new List<int>();
|
||||
int max = numSung.Max();
|
||||
for (int i = 0; i < numSung.Count; i++)
|
||||
var mustSing = new List<int>();
|
||||
var max = numSung.Max();
|
||||
for (var i = 0; i < numSung.Count; i++)
|
||||
{
|
||||
if (numSung[i] < max)
|
||||
{
|
||||
mustSing.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
return mustSing;
|
||||
}
|
||||
|
||||
private static void _AddCombinations(int numPlayer, int playersPerRound, List<CRound> combinations)
|
||||
{
|
||||
List<int> input = new List<int>(numPlayer);
|
||||
for (int i = 0; i < numPlayer; i++)
|
||||
var input = new List<int>(numPlayer);
|
||||
for (var i = 0; i < numPlayer; i++)
|
||||
{
|
||||
input.Add(i);
|
||||
CCombinations<int> combs = new CCombinations<int>(input, playersPerRound);
|
||||
}
|
||||
|
||||
var combs = new CCombinations<int>(input, playersPerRound);
|
||||
combinations.AddRange(combs.Select(combination => new CRound(combination)));
|
||||
combinations.Shuffle();
|
||||
}
|
||||
|
||||
private static CRound _GetMatchingCombination(List<int> playersInRound, List<int> numSung, List<CRound> combinations)
|
||||
{
|
||||
foreach (CRound round in combinations)
|
||||
foreach (var round in combinations)
|
||||
{
|
||||
int matching = round.Players.Count(playersInRound.Contains);
|
||||
var 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;
|
||||
}
|
||||
}
|
||||
|
||||
// It may happen, that there are only players that already sung against each other. So create a 2nd best option with the most number of players that should sing in it
|
||||
int maxMatching = combinations.Max(c => c.Players.Count(playersInRound.Contains));
|
||||
List<CRound> nextOptions = combinations.Where(c => c.Players.Count(playersInRound.Contains) == maxMatching).ToList();
|
||||
var maxMatching = combinations.Max(c => c.Players.Count(playersInRound.Contains));
|
||||
var nextOptions = combinations.Where(c => c.Players.Count(playersInRound.Contains) == maxMatching).ToList();
|
||||
// And select the combination that minimizes the sum of the number of songs sung (--> favor rounds with players that sung less than others)
|
||||
CRound result = null;
|
||||
int minSung = int.MaxValue;
|
||||
foreach (CRound round in nextOptions)
|
||||
var minSung = int.MaxValue;
|
||||
foreach (var round in nextOptions)
|
||||
{
|
||||
int curNumSung = round.Players.Sum(pl => numSung[pl]);
|
||||
var curNumSung = round.Players.Sum(pl => numSung[pl]);
|
||||
if (curNumSung < minSung)
|
||||
{
|
||||
minSung = curNumSung;
|
||||
result = round;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Assert(result != null);
|
||||
return result;
|
||||
}
|
||||
@@ -118,24 +132,35 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
{
|
||||
// What we want is that every player sung the same amount of songs
|
||||
// So we keep track how many songs each palyer sung
|
||||
List<int> numSung = new List<int>(numPlayer);
|
||||
for (int i = 0; i < numPlayer; i++)
|
||||
var numSung = new List<int>(numPlayer);
|
||||
for (var i = 0; i < numPlayer; i++)
|
||||
{
|
||||
numSung.Add(0);
|
||||
List<CRound> combinations = new List<CRound>();
|
||||
}
|
||||
|
||||
var combinations = new List<CRound>();
|
||||
// Posibly add more rounds than requested if the song count per player is unequal
|
||||
for (int i = 0; i < numRounds * 10; i++)
|
||||
for (var i = 0; i < numRounds * 10; i++)
|
||||
{
|
||||
if (combinations.Count == 0)
|
||||
{
|
||||
_AddCombinations(numPlayer, playersPerRound, combinations);
|
||||
List<int> playersInRound = _GetPlayersForRound(numSung);
|
||||
CRound curRound = _GetMatchingCombination(playersInRound, numSung, combinations);
|
||||
foreach (int player in curRound.Players)
|
||||
}
|
||||
|
||||
var playersInRound = _GetPlayersForRound(numSung);
|
||||
var curRound = _GetMatchingCombination(playersInRound, numSung, combinations);
|
||||
foreach (var player in curRound.Players)
|
||||
{
|
||||
numSung[player]++;
|
||||
}
|
||||
|
||||
_Rounds.Add(curRound);
|
||||
combinations.Remove(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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,12 +17,10 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using VocaluxeLib.Game;
|
||||
using VocaluxeLib.Menu;
|
||||
using VocaluxeLib.Songs;
|
||||
using VocaluxeLib.Utils;
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
@@ -31,7 +29,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
public class CResultTableRow : IComparable
|
||||
{
|
||||
public int Position;
|
||||
public Guid PlayerID;
|
||||
public Guid PlayerId;
|
||||
public int NumPlayed;
|
||||
public int NumWon;
|
||||
public int NumSingPoints;
|
||||
@@ -42,13 +40,16 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
var row = obj as CResultTableRow;
|
||||
if (row != null)
|
||||
{
|
||||
int res = row.NumGamePoints.CompareTo(NumGamePoints);
|
||||
var res = row.NumGamePoints.CompareTo(NumGamePoints);
|
||||
if (res == 0)
|
||||
{
|
||||
res = row.NumSingPoints.CompareTo(NumSingPoints);
|
||||
if (res == 0)
|
||||
{
|
||||
res = row.NumWon.CompareTo(NumWon);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -69,7 +70,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
|
||||
// ReSharper disable ClassNeverInstantiated.Global
|
||||
public sealed class CPartyModeChallenge : CPartyMode
|
||||
// ReSharper restore ClassNeverInstantiated.Global
|
||||
// ReSharper restore ClassNeverInstantiated.Global
|
||||
{
|
||||
public override int MinMics
|
||||
{
|
||||
@@ -123,12 +124,12 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
public int NumJokers;
|
||||
public bool RefillJokers;
|
||||
public int[] Jokers;
|
||||
public List<Guid> ProfileIDs;
|
||||
public List<Guid> ProfileIds;
|
||||
|
||||
public ESongSource SongSource;
|
||||
public ESongSorting Sorting;
|
||||
public int CategoryIndex;
|
||||
public int PlaylistID;
|
||||
public int PlaylistId;
|
||||
|
||||
public EGameMode GameMode;
|
||||
public int NumMedleySongs;
|
||||
@@ -144,7 +145,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
|
||||
private struct SStats
|
||||
{
|
||||
public Guid ProfileID;
|
||||
public Guid ProfileId;
|
||||
public int SingPoints;
|
||||
public int GamePoints;
|
||||
public int Won;
|
||||
@@ -158,13 +159,13 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
_ScreenSongOptions.Selection.RandomOnly = false;
|
||||
_ScreenSongOptions.Selection.PartyMode = true;
|
||||
_ScreenSongOptions.Selection.CategoryChangeAllowed = true;
|
||||
_ScreenSongOptions.Selection.NumJokers = new int[] {5, 5};
|
||||
_ScreenSongOptions.Selection.TeamNames = new string[] {"foo", "bar"};
|
||||
_ScreenSongOptions.Selection.NumJokers = new int[] { 5, 5 };
|
||||
_ScreenSongOptions.Selection.TeamNames = new string[] { "foo", "bar" };
|
||||
|
||||
_ScreenSongOptions.Sorting.SearchString = String.Empty;
|
||||
_ScreenSongOptions.Sorting.SearchString = string.Empty;
|
||||
_ScreenSongOptions.Sorting.SearchActive = false;
|
||||
_ScreenSongOptions.Sorting.DuetOptions = EDuetOptions.NoDuets;
|
||||
_ScreenSongOptions.Sorting.FilterPlaylistID = -1;
|
||||
_ScreenSongOptions.Sorting.FilterPlaylistId = -1;
|
||||
|
||||
GameData = new SData
|
||||
{
|
||||
@@ -174,10 +175,10 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
NumJokers = 5,
|
||||
RefillJokers = true,
|
||||
CurrentRoundNr = 1,
|
||||
ProfileIDs = new List<Guid>(),
|
||||
ProfileIds = new List<Guid>(),
|
||||
Sorting = CBase.Config.GetSongSorting(),
|
||||
SongSource = ESongSource.TR_SONGSOURCE_ALLSONGS,
|
||||
PlaylistID = 0,
|
||||
PlaylistId = 0,
|
||||
CategoryIndex = 0,
|
||||
GameMode = EGameMode.TR_GAMEMODE_NORMAL,
|
||||
NumMedleySongs = 5,
|
||||
@@ -197,7 +198,9 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
_ScreenSongOptions.Selection.CategoryIndex = -1;
|
||||
|
||||
if (CBase.Config.GetTabs() == EOffOn.TR_CONFIG_ON && _ScreenSongOptions.Sorting.SongSorting != ESongSorting.TR_CONFIG_NONE)
|
||||
{
|
||||
_ScreenSongOptions.Sorting.Tabs = EOffOn.TR_CONFIG_ON;
|
||||
}
|
||||
|
||||
GameData.ResultTable = new List<CResultTableRow>();
|
||||
}
|
||||
@@ -205,16 +208,15 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
public override bool Init()
|
||||
{
|
||||
if (!base.Init())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SetDefaults();
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void UpdateGame()
|
||||
{
|
||||
|
||||
}
|
||||
public override void UpdateGame() { }
|
||||
|
||||
private IMenu _GetNextScreen()
|
||||
{
|
||||
@@ -272,6 +274,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
_Stage = EStage.SongSelection;
|
||||
_PrepareSongSelection();
|
||||
}
|
||||
|
||||
break;
|
||||
case EStage.SongSelection:
|
||||
_Stage = EStage.Singing;
|
||||
@@ -284,6 +287,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
default:
|
||||
throw new ArgumentException("Invalid stage: " + _Stage);
|
||||
}
|
||||
|
||||
_FadeToScreen();
|
||||
}
|
||||
|
||||
@@ -306,6 +310,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
default: // Rest is not allowed
|
||||
throw new ArgumentException("Invalid stage: " + _Stage);
|
||||
}
|
||||
|
||||
_FadeToScreen();
|
||||
}
|
||||
|
||||
@@ -322,7 +327,9 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
public override void OnSongChange(int songIndex, ref SScreenSongOptions screenSongOptions)
|
||||
{
|
||||
if (_ScreenSongOptions.Selection.SelectNextRandomSong && songIndex != -1)
|
||||
{
|
||||
_ScreenSongOptions.Selection.SelectNextRandomSong = false;
|
||||
}
|
||||
|
||||
_ScreenSongOptions.Selection.SongIndex = songIndex;
|
||||
|
||||
@@ -358,24 +365,29 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
public override void JokerUsed(int teamNr)
|
||||
{
|
||||
if (_ScreenSongOptions.Selection.NumJokers == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (teamNr >= _ScreenSongOptions.Selection.NumJokers.Length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GameData.RefillJokers)
|
||||
{
|
||||
CRound round = GameData.Rounds[GameData.CurrentRoundNr - 1];
|
||||
var round = GameData.Rounds[GameData.CurrentRoundNr - 1];
|
||||
GameData.Jokers[round.Players[teamNr]]--;
|
||||
}
|
||||
|
||||
_ScreenSongOptions.Selection.NumJokers[teamNr]--;
|
||||
_ScreenSongOptions.Selection.RandomOnly = true;
|
||||
_ScreenSongOptions.Selection.CategoryChangeAllowed = false;
|
||||
}
|
||||
|
||||
public override void SongSelected(int songID)
|
||||
public override void SongSelected(int songId)
|
||||
{
|
||||
_PrepareRound(new int[] { songID });
|
||||
_PrepareRound(new int[] { songId });
|
||||
|
||||
Next();
|
||||
}
|
||||
@@ -383,8 +395,10 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
public override void LeavingHighscore()
|
||||
{
|
||||
//Remember sung songs, so they don't will be selected a second time
|
||||
for(int i = 0; i < CBase.Game.GetNumSongs(); i++)
|
||||
CBase.Songs.AddPartySongSung(CBase.Game.GetSong(i).ID);
|
||||
for (var i = 0; i < CBase.Game.GetNumSongs(); i++)
|
||||
{
|
||||
CBase.Songs.AddPartySongSung(CBase.Game.GetSong(i).Id);
|
||||
}
|
||||
|
||||
GameData.CurrentRoundNr++;
|
||||
|
||||
@@ -397,17 +411,19 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
private void _PrepareMedleyRound()
|
||||
{
|
||||
//Select songs for medley
|
||||
int[] songIDs = new int[GameData.NumMedleySongs];
|
||||
for (int i = 0; i < GameData.NumMedleySongs; i++)
|
||||
var songIds = new int[GameData.NumMedleySongs];
|
||||
for (var i = 0; i < GameData.NumMedleySongs; i++)
|
||||
{
|
||||
if (GameData.Songs.Count == 0)
|
||||
{
|
||||
_UpdateSongList();
|
||||
}
|
||||
|
||||
songIDs[i] = GameData.Songs[0];
|
||||
songIds[i] = GameData.Songs[0];
|
||||
GameData.Songs.RemoveAt(0);
|
||||
}
|
||||
|
||||
_PrepareRound(songIDs);
|
||||
_PrepareRound(songIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -425,7 +441,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
case ESongSource.TR_SONGSOURCE_ALLSONGS:
|
||||
_ScreenSongOptions.Sorting.SongSorting = CBase.Config.GetSongSorting();
|
||||
_ScreenSongOptions.Sorting.Tabs = CBase.Config.GetTabs();
|
||||
_ScreenSongOptions.Sorting.FilterPlaylistID = -1;
|
||||
_ScreenSongOptions.Sorting.FilterPlaylistId = -1;
|
||||
|
||||
_ScreenSongOptions.Selection.SongIndex = -1;
|
||||
_ScreenSongOptions.Selection.CategoryIndex = -1;
|
||||
@@ -435,7 +451,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
case ESongSource.TR_SONGSOURCE_CATEGORY:
|
||||
_ScreenSongOptions.Sorting.SongSorting = GameData.Sorting;
|
||||
_ScreenSongOptions.Sorting.Tabs = EOffOn.TR_CONFIG_ON;
|
||||
_ScreenSongOptions.Sorting.FilterPlaylistID = -1;
|
||||
_ScreenSongOptions.Sorting.FilterPlaylistId = -1;
|
||||
|
||||
_ScreenSongOptions.Selection.CategoryIndex = GameData.CategoryIndex;
|
||||
_ScreenSongOptions.Selection.CategoryChangeAllowed = false;
|
||||
@@ -444,7 +460,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
case ESongSource.TR_SONGSOURCE_PLAYLIST:
|
||||
_ScreenSongOptions.Sorting.SongSorting = CBase.Config.GetSongSorting();
|
||||
_ScreenSongOptions.Sorting.Tabs = EOffOn.TR_CONFIG_OFF;
|
||||
_ScreenSongOptions.Sorting.FilterPlaylistID = GameData.PlaylistID;
|
||||
_ScreenSongOptions.Sorting.FilterPlaylistId = GameData.PlaylistId;
|
||||
|
||||
_ScreenSongOptions.Selection.CategoryChangeAllowed = false;
|
||||
break;
|
||||
@@ -457,9 +473,9 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
/// <summary>
|
||||
/// Prepare next game and fill song queue based on configuration and given songs.
|
||||
/// </summary>
|
||||
/// <param name="songIDs">Array of SongIDs that are selected</param>
|
||||
/// <param name="songIds">Array of SongIds that are selected</param>
|
||||
/// <returns>false, if something can't setup correctly</returns>
|
||||
private bool _PrepareRound(int[] songIDs)
|
||||
private bool _PrepareRound(int[] songIds)
|
||||
{
|
||||
//Reset game
|
||||
CBase.Game.Reset();
|
||||
@@ -467,73 +483,86 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
|
||||
#region PlayerNames
|
||||
CBase.Game.SetNumPlayer(GameData.NumPlayerAtOnce);
|
||||
SPlayer[] players = CBase.Game.GetPlayers();
|
||||
var players = CBase.Game.GetPlayers();
|
||||
if (players == null || players.Length < GameData.NumPlayerAtOnce)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//Get current round
|
||||
CRound c = GameData.Rounds[GameData.CurrentRoundNr - 1];
|
||||
var c = GameData.Rounds[GameData.CurrentRoundNr - 1];
|
||||
|
||||
for (int i = 0; i < GameData.NumPlayerAtOnce; i++)
|
||||
for (var i = 0; i < GameData.NumPlayerAtOnce; i++)
|
||||
{
|
||||
//try to fill with correct player data
|
||||
if (c != null)
|
||||
players[i].ProfileID = GameData.ProfileIDs[c.Players[i]];
|
||||
{
|
||||
players[i].ProfileId = GameData.ProfileIds[c.Players[i]];
|
||||
}
|
||||
else
|
||||
players[i].ProfileID = Guid.Empty;
|
||||
{
|
||||
players[i].ProfileId = Guid.Empty;
|
||||
}
|
||||
}
|
||||
#endregion PlayerNames
|
||||
|
||||
#region SongQueue
|
||||
//Add all songs with configure game mode to song queue
|
||||
for (int i = 0; i < songIDs.Length; i++)
|
||||
CBase.Game.AddSong(songIDs[i], GameData.GameMode);
|
||||
for (var i = 0; i < songIds.Length; i++)
|
||||
{
|
||||
CBase.Game.AddSong(songIds[i], GameData.GameMode);
|
||||
}
|
||||
#endregion SongQueue
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
private void _SetNumJokers()
|
||||
{
|
||||
int[] jokers = new int[GameData.NumPlayerAtOnce];
|
||||
var jokers = new int[GameData.NumPlayerAtOnce];
|
||||
if (GameData.RefillJokers)
|
||||
{
|
||||
for (int i = 0; i < jokers.Length; i++)
|
||||
jokers[i] = GameData.NumJokers;
|
||||
{
|
||||
for (var i = 0; i < jokers.Length; i++)
|
||||
{
|
||||
jokers[i] = GameData.NumJokers;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GameData.Jokers == null)
|
||||
{
|
||||
GameData.Jokers = new int[GameData.NumPlayer];
|
||||
for (int i = 0; i < GameData.ProfileIDs.Count; i++)
|
||||
for (var i = 0; i < GameData.ProfileIds.Count; i++)
|
||||
{
|
||||
GameData.Jokers[i] = GameData.NumJokers;
|
||||
}
|
||||
}
|
||||
CRound round = GameData.Rounds[GameData.CurrentRoundNr - 1];
|
||||
for (int i = 0; i < GameData.NumPlayerAtOnce; i++)
|
||||
|
||||
var round = GameData.Rounds[GameData.CurrentRoundNr - 1];
|
||||
for (var i = 0; i < GameData.NumPlayerAtOnce; i++)
|
||||
{
|
||||
jokers[i] = GameData.Jokers[round.Players[i]];
|
||||
}
|
||||
}
|
||||
|
||||
_ScreenSongOptions.Selection.NumJokers = jokers;
|
||||
}
|
||||
|
||||
private void _SetTeamNames()
|
||||
{
|
||||
if (GameData.NumPlayerAtOnce < 1 || GameData.ProfileIDs.Count < GameData.NumPlayerAtOnce)
|
||||
if (GameData.NumPlayerAtOnce < 1 || GameData.ProfileIds.Count < GameData.NumPlayerAtOnce)
|
||||
{
|
||||
_ScreenSongOptions.Selection.TeamNames = new string[] {"foo", "bar"};
|
||||
_ScreenSongOptions.Selection.TeamNames = new string[] { "foo", "bar" };
|
||||
return;
|
||||
}
|
||||
|
||||
_ScreenSongOptions.Selection.TeamNames = new string[GameData.NumPlayerAtOnce];
|
||||
CRound c = GameData.Rounds[GameData.CurrentRoundNr - 1];
|
||||
var c = GameData.Rounds[GameData.CurrentRoundNr - 1];
|
||||
|
||||
for (int i = 0; i < GameData.NumPlayerAtOnce; i++)
|
||||
_ScreenSongOptions.Selection.TeamNames[i] = CBase.Profiles.GetPlayerName(GameData.ProfileIDs[c.Players[i]]);
|
||||
for (var i = 0; i < GameData.NumPlayerAtOnce; i++)
|
||||
{
|
||||
_ScreenSongOptions.Selection.TeamNames[i] = CBase.Profiles.GetPlayerName(GameData.ProfileIds[c.Players[i]]);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -543,37 +572,43 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
private void _UpdateSongList()
|
||||
{
|
||||
if (GameData.Songs.Count > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (GameData.SongSource)
|
||||
{
|
||||
case ESongSource.TR_SONGSOURCE_PLAYLIST:
|
||||
for (int i = 0; i < CBase.Playlist.GetSongCount(GameData.PlaylistID); i++)
|
||||
for (var 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(EGameMode.TR_GAMEMODE_MEDLEY))
|
||||
var id = CBase.Playlist.GetSong(GameData.PlaylistId, i).SongId;
|
||||
if (CBase.Songs.GetSongById(id).IsGameModeAvailable(EGameMode.TR_GAMEMODE_MEDLEY))
|
||||
{
|
||||
GameData.Songs.Add(id);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ESongSource.TR_SONGSOURCE_ALLSONGS:
|
||||
ReadOnlyCollection<CSong> avSongs = CBase.Songs.GetSongs();
|
||||
GameData.Songs.AddRange(avSongs.Where(song => song.AvailableGameModes.Contains(EGameMode.TR_GAMEMODE_MEDLEY)).Select(song => song.ID));
|
||||
var avSongs = CBase.Songs.GetSongs();
|
||||
GameData.Songs.AddRange(avSongs.Where(song => song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_MEDLEY)).Select(song => song.Id));
|
||||
break;
|
||||
|
||||
case ESongSource.TR_SONGSOURCE_CATEGORY:
|
||||
//Save old sorting to roll it back after getting songs for configured category
|
||||
ESongSorting oldSorting = CBase.Config.GetSongSorting();
|
||||
CBase.Songs.SortSongs(GameData.Sorting, EOffOn.TR_CONFIG_ON, CBase.Config.GetIgnoreArticles() ,String.Empty, EDuetOptions.NoDuets, -1);
|
||||
var oldSorting = CBase.Config.GetSongSorting();
|
||||
CBase.Songs.SortSongs(GameData.Sorting, EOffOn.TR_CONFIG_ON, CBase.Config.GetIgnoreArticles(), string.Empty, EDuetOptions.NoDuets, -1);
|
||||
|
||||
CBase.Songs.SetCategory(GameData.CategoryIndex);
|
||||
avSongs = CBase.Songs.GetVisibleSongs();
|
||||
GameData.Songs.AddRange(avSongs.Where(song => song.AvailableGameModes.Contains(EGameMode.TR_GAMEMODE_MEDLEY)).Select(song => song.ID));
|
||||
GameData.Songs.AddRange(avSongs.Where(song => song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_MEDLEY)).Select(song => song.Id));
|
||||
|
||||
CBase.Songs.SetCategory(-1);
|
||||
CBase.Songs.SortSongs(oldSorting, CBase.Config.GetTabs(), CBase.Config.GetIgnoreArticles(), String.Empty, EDuetOptions.NoDuets, -1);
|
||||
CBase.Songs.SortSongs(oldSorting, CBase.Config.GetTabs(), CBase.Config.GetIgnoreArticles(), string.Empty, EDuetOptions.NoDuets, -1);
|
||||
break;
|
||||
}
|
||||
|
||||
GameData.Songs.Shuffle();
|
||||
}
|
||||
|
||||
@@ -582,41 +617,46 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
//Prepare results table
|
||||
if (GameData.ResultTable.Count == 0)
|
||||
{
|
||||
for (int i = 0; i < GameData.NumPlayer; i++)
|
||||
for (var i = 0; i < GameData.NumPlayer; i++)
|
||||
{
|
||||
var row = new CResultTableRow { PlayerID = GameData.ProfileIDs[i], NumPlayed = 0, NumWon = 0, NumSingPoints = 0, NumGamePoints = 0 };
|
||||
var row = new CResultTableRow { PlayerId = GameData.ProfileIds[i], NumPlayed = 0, NumWon = 0, NumSingPoints = 0, NumGamePoints = 0 };
|
||||
GameData.ResultTable.Add(row);
|
||||
}
|
||||
|
||||
GameData.Results = new int[GameData.NumRounds, GameData.NumPlayerAtOnce];
|
||||
for (int i = 0; i < GameData.NumRounds; i++)
|
||||
for (var i = 0; i < GameData.NumRounds; i++)
|
||||
{
|
||||
for (int j = 0; j < GameData.NumPlayerAtOnce; j++)
|
||||
for (var j = 0; j < GameData.NumPlayerAtOnce; j++)
|
||||
{
|
||||
GameData.Results[i, j] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Get points from game
|
||||
CPoints points = CBase.Game.GetPoints();
|
||||
SPlayer[] players = CBase.Game.GetPlayers();
|
||||
var points = CBase.Game.GetPoints();
|
||||
var players = CBase.Game.GetPlayers();
|
||||
|
||||
//Go over all rounds and sum up points
|
||||
for (int round = 0; round < points.NumRounds; round++)
|
||||
for (var round = 0; round < points.NumRounds; round++)
|
||||
{
|
||||
SPlayer[] res = points.GetPlayer(round, GameData.NumPlayerAtOnce);
|
||||
var res = points.GetPlayer(round, GameData.NumPlayerAtOnce);
|
||||
|
||||
if (res == null || res.Length < GameData.NumPlayerAtOnce)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (int p = 0; p < GameData.NumPlayerAtOnce; p++)
|
||||
for (var p = 0; p < GameData.NumPlayerAtOnce; p++)
|
||||
{
|
||||
players[p].Points += res[p].Points;
|
||||
players[p].PointsGoldenNotes += res[p].PointsGoldenNotes;
|
||||
players[p].PointsLineBonus += res[p].PointsLineBonus;
|
||||
}
|
||||
}
|
||||
|
||||
//Calculate average points
|
||||
for (int p = 0; p < GameData.NumPlayerAtOnce; p++)
|
||||
for (var p = 0; p < GameData.NumPlayerAtOnce; p++)
|
||||
{
|
||||
players[p].Points /= points.NumRounds;
|
||||
players[p].PointsGoldenNotes /= points.NumRounds;
|
||||
@@ -626,15 +666,15 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
GameData.Results[GameData.CurrentRoundNr - 2, p] = (int)Math.Round(players[p].Points);
|
||||
}
|
||||
|
||||
List<SStats> stats = _GetPointsForPlayer(players);
|
||||
var stats = _GetPointsForPlayer(players);
|
||||
|
||||
for (int i = 0; i < GameData.NumPlayerAtOnce; i++)
|
||||
for (var i = 0; i < GameData.NumPlayerAtOnce; i++)
|
||||
{
|
||||
//Find matching row in results table
|
||||
int index = -1;
|
||||
for (int j = 0; j < GameData.ResultTable.Count; j++)
|
||||
var index = -1;
|
||||
for (var j = 0; j < GameData.ResultTable.Count; j++)
|
||||
{
|
||||
if (stats[i].ProfileID == GameData.ResultTable[j].PlayerID)
|
||||
if (stats[i].ProfileId == GameData.ResultTable[j].PlayerId)
|
||||
{
|
||||
index = j;
|
||||
break;
|
||||
@@ -642,8 +682,11 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
}
|
||||
|
||||
if (index == -1)
|
||||
{
|
||||
continue;
|
||||
CResultTableRow row = GameData.ResultTable[index];
|
||||
}
|
||||
|
||||
var row = GameData.ResultTable[index];
|
||||
|
||||
//Update results entry
|
||||
row.NumPlayed++;
|
||||
@@ -657,13 +700,16 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
GameData.ResultTable.Sort();
|
||||
|
||||
//Update position-number
|
||||
int pos = 1;
|
||||
int lastPoints = 0;
|
||||
int lastSingPoints = 0;
|
||||
foreach (CResultTableRow resultRow in GameData.ResultTable)
|
||||
var pos = 1;
|
||||
var lastPoints = 0;
|
||||
var lastSingPoints = 0;
|
||||
foreach (var resultRow in GameData.ResultTable)
|
||||
{
|
||||
if (lastPoints > resultRow.NumGamePoints || lastSingPoints > resultRow.NumSingPoints)
|
||||
{
|
||||
pos++;
|
||||
}
|
||||
|
||||
resultRow.Position = pos;
|
||||
lastPoints = resultRow.NumGamePoints;
|
||||
lastSingPoints = resultRow.NumSingPoints;
|
||||
@@ -673,21 +719,21 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
private List<SStats> _GetPointsForPlayer(SPlayer[] results)
|
||||
{
|
||||
var result = new List<SStats>();
|
||||
for (int i = 0; i < GameData.NumPlayerAtOnce; i++)
|
||||
for (var i = 0; i < GameData.NumPlayerAtOnce; i++)
|
||||
{
|
||||
var stat = new SStats {ProfileID = results[i].ProfileID, SingPoints = (int)Math.Round(results[i].Points), Won = 0, GamePoints = 0};
|
||||
var stat = new SStats { ProfileId = results[i].ProfileId, SingPoints = (int)Math.Round(results[i].Points), Won = 0, GamePoints = 0 };
|
||||
result.Add(stat);
|
||||
}
|
||||
|
||||
result.Sort((s1, s2) => s1.SingPoints.CompareTo(s2.SingPoints));
|
||||
|
||||
int current = result[result.Count - 1].SingPoints;
|
||||
int points = result.Count;
|
||||
bool wonset = false;
|
||||
var current = result[result.Count - 1].SingPoints;
|
||||
var points = result.Count;
|
||||
var wonset = false;
|
||||
|
||||
for (int i = result.Count - 1; i >= 0; i--)
|
||||
for (var i = result.Count - 1; i >= 0; i--)
|
||||
{
|
||||
SStats res = result[i];
|
||||
var res = result[i];
|
||||
|
||||
if (i < result.Count - 1)
|
||||
{
|
||||
@@ -700,7 +746,10 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
else
|
||||
{
|
||||
if (!wonset)
|
||||
{
|
||||
res.Won = 1;
|
||||
}
|
||||
|
||||
res.GamePoints = points;
|
||||
}
|
||||
}
|
||||
@@ -719,4 +768,4 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
{
|
||||
// ReSharper disable UnusedMember.Global
|
||||
public class CPartyScreenChallengeConfig : CPartyScreenChallenge
|
||||
// ReSharper restore UnusedMember.Global
|
||||
// ReSharper restore UnusedMember.Global
|
||||
{
|
||||
// Version number for theme files. Increment it, if you've changed something on the theme files!
|
||||
protected override int _ScreenVersion
|
||||
@@ -46,14 +46,14 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
base.Init();
|
||||
|
||||
_ThemeSelectSlides = new string[] { _SelectSlideNumPlayers, _SelectSlideNumMics, _SelectSlideNumRounds, _SelectSlideNumJokers, _SelectSlideRefillJokers };
|
||||
_ThemeButtons = new string[] {_ButtonNext, _ButtonBack};
|
||||
_ThemeButtons = new string[] { _ButtonNext, _ButtonBack };
|
||||
}
|
||||
|
||||
public override bool HandleInput(SKeyEvent keyEvent)
|
||||
{
|
||||
base.HandleInput(keyEvent);
|
||||
|
||||
if (keyEvent.KeyPressed) {}
|
||||
if (keyEvent.KeyPressed) { }
|
||||
else
|
||||
{
|
||||
switch (keyEvent.Key)
|
||||
@@ -67,10 +67,15 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
_UpdateSlides();
|
||||
|
||||
if (_Buttons[_ButtonBack].Selected)
|
||||
{
|
||||
_PartyMode.Back();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonNext].Selected)
|
||||
{
|
||||
_PartyMode.Next();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Keys.Left:
|
||||
@@ -82,6 +87,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -93,14 +99,20 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
{
|
||||
_UpdateSlides();
|
||||
if (_Buttons[_ButtonBack].Selected)
|
||||
{
|
||||
_PartyMode.Back();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonNext].Selected)
|
||||
{
|
||||
_PartyMode.Next();
|
||||
}
|
||||
}
|
||||
|
||||
if (mouseEvent.RB)
|
||||
{
|
||||
_PartyMode.Back();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -121,22 +133,26 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
{
|
||||
// build num player slide (min player ... max player);
|
||||
_SelectSlides[_SelectSlideNumPlayers].Clear();
|
||||
for (int i = _PartyMode.MinPlayers; i <= _PartyMode.MaxPlayers; i++)
|
||||
for (var i = _PartyMode.MinPlayers; i <= _PartyMode.MaxPlayers; i++)
|
||||
{
|
||||
_SelectSlides[_SelectSlideNumPlayers].AddValue(i.ToString());
|
||||
}
|
||||
|
||||
_SelectSlides[_SelectSlideNumPlayers].SelectedValue = _PartyMode.GameData.NumPlayer.ToString();
|
||||
|
||||
// build num joker slide 1 to 10
|
||||
_SelectSlides[_SelectSlideNumJokers].Clear();
|
||||
for (int i = 1; i <= 10; i++)
|
||||
for (var i = 1; i <= 10; i++)
|
||||
{
|
||||
_SelectSlides[_SelectSlideNumJokers].AddValue(i.ToString());
|
||||
}
|
||||
|
||||
_SelectSlides[_SelectSlideNumJokers].SelectedValue = "5";
|
||||
|
||||
//build joker config slide
|
||||
_SelectSlides[_SelectSlideRefillJokers].Clear();
|
||||
_SelectSlides[_SelectSlideRefillJokers].AddValue(CBase.Language.Translate("TR_BUTTON_NO", PartyModeID));
|
||||
_SelectSlides[_SelectSlideRefillJokers].AddValue(CBase.Language.Translate("TR_BUTTON_YES", PartyModeID));
|
||||
_SelectSlides[_SelectSlideRefillJokers].AddValue(CBase.Language.Translate("TR_BUTTON_NO", PartyModeId));
|
||||
_SelectSlides[_SelectSlideRefillJokers].AddValue(CBase.Language.Translate("TR_BUTTON_YES", PartyModeId));
|
||||
_SelectSlides[_SelectSlideRefillJokers].SelectLastValue();
|
||||
|
||||
_UpdateMicsAtOnce();
|
||||
@@ -146,22 +162,25 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
|
||||
private void _UpdateSlides()
|
||||
{
|
||||
int player = _PartyMode.GameData.NumPlayer;
|
||||
int mics = _PartyMode.GameData.NumPlayerAtOnce;
|
||||
var player = _PartyMode.GameData.NumPlayer;
|
||||
var mics = _PartyMode.GameData.NumPlayerAtOnce;
|
||||
_PartyMode.GameData.NumPlayer = _SelectSlides[_SelectSlideNumPlayers].Selection + _PartyMode.MinPlayers;
|
||||
_PartyMode.GameData.NumPlayerAtOnce = _SelectSlides[_SelectSlideNumMics].Selection + _PartyMode.MinPlayers;
|
||||
_PartyMode.GameData.NumRounds = (_SelectSlides[_SelectSlideNumRounds].Selection + 1) * _RoundSteps;
|
||||
_PartyMode.GameData.NumJokers = _SelectSlides[_SelectSlideNumJokers].Selection + 1;
|
||||
_PartyMode.GameData.RefillJokers = (_SelectSlides[_SelectSlideRefillJokers].Selection == 1) ? true : false;
|
||||
_PartyMode.GameData.RefillJokers = _SelectSlides[_SelectSlideRefillJokers].Selection == 1 ? true : false;
|
||||
|
||||
_UpdateMicsAtOnce();
|
||||
_SetRoundSteps();
|
||||
|
||||
if (player != _PartyMode.GameData.NumPlayer || mics != _PartyMode.GameData.NumPlayerAtOnce)
|
||||
{
|
||||
int num = CHelper.CombinationCount(_PartyMode.GameData.NumPlayer, _PartyMode.GameData.NumPlayerAtOnce);
|
||||
var num = CHelper.CombinationCount(_PartyMode.GameData.NumPlayer, _PartyMode.GameData.NumPlayerAtOnce);
|
||||
while (num > _MaxNumRounds)
|
||||
{
|
||||
num -= _RoundSteps;
|
||||
}
|
||||
|
||||
_PartyMode.GameData.NumRounds = num;
|
||||
}
|
||||
|
||||
@@ -170,15 +189,20 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
|
||||
private void _UpdateMicsAtOnce()
|
||||
{
|
||||
int maxNum = Math.Min(_PartyMode.MaxMics, _PartyMode.GameData.NumPlayer);
|
||||
var maxNum = Math.Min(_PartyMode.MaxMics, _PartyMode.GameData.NumPlayer);
|
||||
|
||||
if (_PartyMode.GameData.NumPlayerAtOnce > maxNum)
|
||||
{
|
||||
_PartyMode.GameData.NumPlayerAtOnce = maxNum;
|
||||
}
|
||||
|
||||
// build mics at once slide
|
||||
_SelectSlides[_SelectSlideNumMics].Clear();
|
||||
for (int i = 1; i <= maxNum; i++)
|
||||
for (var i = 1; i <= maxNum; i++)
|
||||
{
|
||||
_SelectSlides[_SelectSlideNumMics].AddValue(i.ToString());
|
||||
}
|
||||
|
||||
_SelectSlides[_SelectSlideNumMics].Selection = _PartyMode.GameData.NumPlayerAtOnce - _PartyMode.MinPlayers;
|
||||
}
|
||||
|
||||
@@ -186,8 +210,11 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
{
|
||||
// build num rounds slide
|
||||
_SelectSlides[_SelectSlideNumRounds].Clear();
|
||||
for (int i = _RoundSteps; i <= _MaxNumRounds; i += _RoundSteps)
|
||||
for (var i = _RoundSteps; i <= _MaxNumRounds; i += _RoundSteps)
|
||||
{
|
||||
_SelectSlides[_SelectSlideNumRounds].AddValue(i.ToString());
|
||||
}
|
||||
|
||||
_SelectSlides[_SelectSlideNumRounds].Selection = _PartyMode.GameData.NumRounds / _RoundSteps - 1;
|
||||
}
|
||||
|
||||
@@ -199,8 +226,8 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
return;
|
||||
}
|
||||
|
||||
int res = _PartyMode.GameData.NumPlayer / _PartyMode.GameData.NumPlayerAtOnce;
|
||||
int mod = _PartyMode.GameData.NumPlayer % _PartyMode.GameData.NumPlayerAtOnce;
|
||||
var res = _PartyMode.GameData.NumPlayer / _PartyMode.GameData.NumPlayerAtOnce;
|
||||
var mod = _PartyMode.GameData.NumPlayer % _PartyMode.GameData.NumPlayerAtOnce;
|
||||
|
||||
_RoundSteps = mod == 0 ? res : _PartyMode.GameData.NumPlayer;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
|
||||
// ReSharper disable UnusedMember.Global
|
||||
public class CPartyScreenChallengeMain : CPartyScreenChallenge
|
||||
// ReSharper restore UnusedMember.Global
|
||||
// ReSharper restore UnusedMember.Global
|
||||
{
|
||||
// Version number for theme files. Increment it, if you've changed something on the theme files!
|
||||
protected override int _ScreenVersion
|
||||
@@ -97,17 +97,17 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
base.Init();
|
||||
|
||||
_ThemeTexts = new string[]
|
||||
{
|
||||
_TextPosition, _TextPlayerName, _TextNumPlayed, _TextWon, _TextSingPoints, _TextGamePoints, _TextNextPlayer, _TextPopupReallyExit, _TextRoundNumber,
|
||||
_TextRoundPlayer,
|
||||
_TextRoundScore, _TextFinishMessage, _TextFinishPlayerWin, _TextNextPlayerMessage
|
||||
};
|
||||
{
|
||||
_TextPosition, _TextPlayerName, _TextNumPlayed, _TextWon, _TextSingPoints, _TextGamePoints, _TextNextPlayer, _TextPopupReallyExit, _TextRoundNumber,
|
||||
_TextRoundPlayer,
|
||||
_TextRoundScore, _TextFinishMessage, _TextFinishPlayerWin, _TextNextPlayerMessage
|
||||
};
|
||||
_ThemeButtons = new string[]
|
||||
{
|
||||
_ButtonNextRound, _ButtonBack, _ButtonExit, _ButtonPopupYes, _ButtonPopupNo, _ButtonPlayerScrollDown, _ButtonPlayerScrollUp, _ButtonRoundsScrollDown,
|
||||
_ButtonRoundsScrollUp
|
||||
};
|
||||
_ThemeStatics = new string[] {_StaticPopupBG, _StaticNextPlayer};
|
||||
{
|
||||
_ButtonNextRound, _ButtonBack, _ButtonExit, _ButtonPopupYes, _ButtonPopupNo, _ButtonPlayerScrollDown, _ButtonPlayerScrollUp, _ButtonRoundsScrollDown,
|
||||
_ButtonRoundsScrollUp
|
||||
};
|
||||
_ThemeStatics = new string[] { _StaticPopupBG, _StaticNextPlayer };
|
||||
}
|
||||
|
||||
public override void LoadTheme(string xmlPath)
|
||||
@@ -119,7 +119,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
_NextPlayerTexts = new List<CText>();
|
||||
_NextPlayerStatics = new List<CStatic>();
|
||||
|
||||
for (int i = 0; i < _PartyMode.MaxPlayers; i++)
|
||||
for (var i = 0; i < _PartyMode.MaxPlayers; i++)
|
||||
{
|
||||
_NextPlayerTexts.Add(GetNewText(_Texts[_TextNextPlayer]));
|
||||
_AddText(_NextPlayerTexts[_NextPlayerTexts.Count - 1]);
|
||||
@@ -127,6 +127,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
_AddStatic(_NextPlayerStatics[_NextPlayerStatics.Count - 1]);
|
||||
_NextPlayerStatics[_NextPlayerStatics.Count - 1].Aspect = EAspect.Crop;
|
||||
}
|
||||
|
||||
_Statics[_StaticNextPlayer].Visible = false;
|
||||
}
|
||||
|
||||
@@ -134,7 +135,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
{
|
||||
base.HandleInput(keyEvent);
|
||||
|
||||
if (keyEvent.KeyPressed) {}
|
||||
if (keyEvent.KeyPressed) { }
|
||||
else
|
||||
{
|
||||
switch (keyEvent.Key)
|
||||
@@ -144,42 +145,76 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
if (!_ExitPopupVisible)
|
||||
{
|
||||
if (_PartyMode.GameData.CurrentRoundNr == 1)
|
||||
{
|
||||
_PartyMode.Back();
|
||||
}
|
||||
else
|
||||
{
|
||||
_ShowPopup(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_ShowPopup(false);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Keys.Enter:
|
||||
if (!_ExitPopupVisible)
|
||||
{
|
||||
if (_Buttons[_ButtonNextRound].Selected)
|
||||
{
|
||||
_PartyMode.Next();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonBack].Selected && _PartyMode.GameData.CurrentRoundNr == 1)
|
||||
{
|
||||
_PartyMode.Back();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonExit].Selected && _PartyMode.GameData.CurrentRoundNr > 1)
|
||||
{
|
||||
_ShowPopup(true);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonPlayerScrollUp].Selected)
|
||||
{
|
||||
_ScrollPlayerTable(-1);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonPlayerScrollDown].Selected)
|
||||
{
|
||||
_ScrollPlayerTable(1);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonRoundsScrollUp].Selected)
|
||||
{
|
||||
_ScrollRoundsTable(-1);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonRoundsScrollDown].Selected)
|
||||
{
|
||||
_ScrollRoundsTable(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_Buttons[_ButtonPopupYes].Selected)
|
||||
{
|
||||
_EndParty();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonPopupNo].Selected)
|
||||
{
|
||||
_ShowPopup(false);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -192,26 +227,51 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
if (!_ExitPopupVisible)
|
||||
{
|
||||
if (_Buttons[_ButtonNextRound].Selected)
|
||||
{
|
||||
_PartyMode.Next();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonBack].Selected && _PartyMode.GameData.CurrentRoundNr == 1)
|
||||
{
|
||||
_PartyMode.Back();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonExit].Selected && _PartyMode.GameData.CurrentRoundNr > 1)
|
||||
{
|
||||
_ShowPopup(true);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonPlayerScrollUp].Selected)
|
||||
{
|
||||
_ScrollPlayerTable(-1);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonPlayerScrollDown].Selected)
|
||||
{
|
||||
_ScrollPlayerTable(1);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonRoundsScrollUp].Selected)
|
||||
{
|
||||
_ScrollRoundsTable(-1);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonRoundsScrollDown].Selected)
|
||||
{
|
||||
_ScrollRoundsTable(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_Buttons[_ButtonPopupYes].Selected)
|
||||
{
|
||||
_EndParty();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonPopupNo].Selected)
|
||||
{
|
||||
_ShowPopup(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -220,20 +280,31 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
if (!_ExitPopupVisible)
|
||||
{
|
||||
if (_PartyMode.GameData.CurrentRoundNr == 1)
|
||||
{
|
||||
_PartyMode.Back();
|
||||
}
|
||||
else
|
||||
{
|
||||
_ShowPopup(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_ShowPopup(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (mouseEvent.Wheel != 0)
|
||||
{
|
||||
if (CHelper.IsInBounds(_RoundsTableScrollArea, mouseEvent))
|
||||
{
|
||||
_ScrollRoundsTable(mouseEvent.Wheel);
|
||||
}
|
||||
|
||||
if (CHelper.IsInBounds(_PlayerTableScrollArea, mouseEvent))
|
||||
{
|
||||
_ScrollPlayerTable(mouseEvent.Wheel);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -250,9 +321,14 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
_UpdateNextPlayerPositions();
|
||||
_UpdateNextPlayerContents();
|
||||
if (_PartyMode.GameData.CurrentRoundNr == 1)
|
||||
{
|
||||
_BuildRoundsTable();
|
||||
}
|
||||
else
|
||||
{
|
||||
_ScrollRoundsTable(_PartyMode.GameData.CurrentRoundNr - 2);
|
||||
}
|
||||
|
||||
_UpdateRoundsTable();
|
||||
|
||||
if (_PartyMode.GameData.CurrentRoundNr == 1)
|
||||
@@ -305,16 +381,18 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
_Buttons[_ButtonPopupNo].Visible = _ExitPopupVisible;
|
||||
|
||||
if (_ExitPopupVisible)
|
||||
{
|
||||
_SelectElement(_Buttons[_ButtonPopupNo]);
|
||||
}
|
||||
}
|
||||
|
||||
private void _UpdateNextPlayerPositions()
|
||||
{
|
||||
float x = (float)CBase.Settings.GetRenderW() / 2 -
|
||||
((_PartyMode.GameData.NumPlayerAtOnce * _Statics[_StaticNextPlayer].Rect.W) + ((_PartyMode.GameData.NumPlayerAtOnce - 1) * 15)) / 2;
|
||||
var x = (float)CBase.Settings.GetRenderW() / 2 -
|
||||
(_PartyMode.GameData.NumPlayerAtOnce * _Statics[_StaticNextPlayer].Rect.W + (_PartyMode.GameData.NumPlayerAtOnce - 1) * 15) / 2;
|
||||
const float staticY = 885;
|
||||
const float textY = 825;
|
||||
for (int i = 0; i < _PartyMode.GameData.NumPlayerAtOnce; i++)
|
||||
for (var i = 0; i < _PartyMode.GameData.NumPlayerAtOnce; i++)
|
||||
{
|
||||
//static
|
||||
_NextPlayerStatics[i].X = x;
|
||||
@@ -327,7 +405,8 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
|
||||
x += _Statics[_StaticNextPlayer].Rect.W + 15;
|
||||
}
|
||||
for (int i = _PartyMode.GameData.NumPlayerAtOnce; i < _PartyMode.MaxPlayers; i++)
|
||||
|
||||
for (var i = _PartyMode.GameData.NumPlayerAtOnce; i < _PartyMode.MaxPlayers; i++)
|
||||
{
|
||||
_NextPlayerStatics[i].Visible = false;
|
||||
_NextPlayerTexts[i].Visible = false;
|
||||
@@ -339,9 +418,9 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
if (_PartyMode.GameData.CurrentRoundNr <= _PartyMode.GameData.Rounds.Count)
|
||||
{
|
||||
_Texts[_TextNextPlayerMessage].Visible = true;
|
||||
for (int i = 0; i < _PartyMode.GameData.NumPlayerAtOnce; i++)
|
||||
for (var i = 0; i < _PartyMode.GameData.NumPlayerAtOnce; i++)
|
||||
{
|
||||
Guid id = _PartyMode.GameData.ProfileIDs[_PartyMode.GameData.Rounds[_PartyMode.GameData.CurrentRoundNr - 1].Players[i]];
|
||||
var 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);
|
||||
@@ -350,7 +429,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
else
|
||||
{
|
||||
_Texts[_TextNextPlayerMessage].Visible = false;
|
||||
for (int i = 0; i < _PartyMode.GameData.NumPlayerAtOnce; i++)
|
||||
for (var i = 0; i < _PartyMode.GameData.NumPlayerAtOnce; i++)
|
||||
{
|
||||
_NextPlayerStatics[i].Visible = false;
|
||||
_NextPlayerTexts[i].Visible = false;
|
||||
@@ -362,21 +441,22 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
{
|
||||
//Create lists
|
||||
_RoundsTable = new List<CRoundsTableRow>();
|
||||
for (int i = 0; i < 5; i++)
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
var rtr = new CRoundsTableRow {TextPlayer = new List<CText>(), TextScores = new List<CText>()};
|
||||
var rtr = new CRoundsTableRow { TextPlayer = new List<CText>(), TextScores = new List<CText>() };
|
||||
_RoundsTable.Add(rtr);
|
||||
}
|
||||
|
||||
//Create statics and texts for rounds
|
||||
foreach (CRoundsTableRow roundRow in _RoundsTable)
|
||||
foreach (var roundRow in _RoundsTable)
|
||||
{
|
||||
//Round-number
|
||||
CText text = GetNewText(_Texts[_TextRoundNumber]);
|
||||
var text = GetNewText(_Texts[_TextRoundNumber]);
|
||||
_AddText(text);
|
||||
roundRow.Number = text;
|
||||
for (int row = 0; row < 2; row++)
|
||||
for (var row = 0; row < 2; row++)
|
||||
{
|
||||
for (int column = 0; column < 3; column++)
|
||||
for (var column = 0; column < 3; column++)
|
||||
{
|
||||
//Player
|
||||
text = GetNewText(_Texts[_TextRoundPlayer]);
|
||||
@@ -399,39 +479,42 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
_NumRoundsVisible = _PartyMode.GameData.NumPlayerAtOnce <= numPlayerInOneRow ? 5 : 3;
|
||||
|
||||
if (_NumRoundsVisible > _PartyMode.GameData.Rounds.Count)
|
||||
{
|
||||
_NumRoundsVisible = _PartyMode.GameData.Rounds.Count;
|
||||
}
|
||||
|
||||
float numberX = _Texts[_TextRoundNumber].X;
|
||||
float numberY = _Texts[_TextRoundNumber].Y;
|
||||
var numberX = _Texts[_TextRoundNumber].X;
|
||||
var numberY = _Texts[_TextRoundNumber].Y;
|
||||
|
||||
_RoundsTableScrollArea.X = numberX;
|
||||
_RoundsTableScrollArea.Y = numberY;
|
||||
_RoundsTableScrollArea.W = CBase.Settings.GetRenderW() - _Texts[_TextRoundNumber].X - 20;
|
||||
|
||||
float delta = _Texts[_TextRoundNumber].Rect.H;
|
||||
var delta = _Texts[_TextRoundNumber].Rect.H;
|
||||
|
||||
//Update statics and texts for rounds
|
||||
foreach (CRoundsTableRow roundRow in _RoundsTable)
|
||||
foreach (var roundRow in _RoundsTable)
|
||||
{
|
||||
//Round-number
|
||||
roundRow.Number.X = numberX;
|
||||
roundRow.Number.Y = numberY;
|
||||
var numInnerRows = (int)Math.Ceiling(_PartyMode.GameData.NumPlayerAtOnce / ((double)numPlayerInOneRow));
|
||||
for (int row = 0; row < numInnerRows; row++)
|
||||
var numInnerRows = (int)Math.Ceiling(_PartyMode.GameData.NumPlayerAtOnce / (double)numPlayerInOneRow);
|
||||
for (var row = 0; row < numInnerRows; row++)
|
||||
{
|
||||
int num = (row + 1) * numPlayerInOneRow;
|
||||
int numPlayerInThisRow = numPlayerInOneRow;
|
||||
var num = (row + 1) * numPlayerInOneRow;
|
||||
var numPlayerInThisRow = numPlayerInOneRow;
|
||||
if (num > _PartyMode.GameData.NumPlayerAtOnce)
|
||||
{
|
||||
num = _PartyMode.GameData.NumPlayerAtOnce;
|
||||
numPlayerInThisRow = _PartyMode.GameData.NumPlayerAtOnce - (row * numPlayerInOneRow);
|
||||
numPlayerInThisRow = _PartyMode.GameData.NumPlayerAtOnce - row * numPlayerInOneRow;
|
||||
}
|
||||
for (int column = row * numPlayerInOneRow; column < num; column++)
|
||||
|
||||
for (var column = row * numPlayerInOneRow; column < num; column++)
|
||||
{
|
||||
//Player
|
||||
float x = numberX + 15 + (CBase.Settings.GetRenderW() - _Texts[_TextRoundNumber].X - 20) / numPlayerInThisRow * (column - row * numPlayerInOneRow) +
|
||||
((CBase.Settings.GetRenderW() - _Texts[_TextRoundNumber].X - 20) / numPlayerInThisRow) / 2;
|
||||
float maxw = ((CBase.Settings.GetRenderW() - _Texts[_TextRoundNumber].X - 20) / numPlayerInThisRow) / 2 - 5;
|
||||
var x = numberX + 15 + (CBase.Settings.GetRenderW() - _Texts[_TextRoundNumber].X - 20) / numPlayerInThisRow * (column - row * numPlayerInOneRow) +
|
||||
(CBase.Settings.GetRenderW() - _Texts[_TextRoundNumber].X - 20) / numPlayerInThisRow / 2;
|
||||
var maxw = (CBase.Settings.GetRenderW() - _Texts[_TextRoundNumber].X - 20) / numPlayerInThisRow / 2 - 5;
|
||||
roundRow.TextPlayer[column].X = x;
|
||||
roundRow.TextPlayer[column].Y = numberY;
|
||||
roundRow.TextPlayer[column].W = maxw;
|
||||
@@ -440,33 +523,40 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
roundRow.TextScores[column].Y = numberY + delta;
|
||||
roundRow.TextScores[column].W = maxw;
|
||||
}
|
||||
|
||||
numberY = numberY + 2 * delta;
|
||||
}
|
||||
|
||||
numberY = numberY + delta / 2;
|
||||
}
|
||||
|
||||
_RoundsTableScrollArea.H = numberY - _RoundsTableScrollArea.Y;
|
||||
}
|
||||
|
||||
private void _UpdateRoundsTable()
|
||||
{
|
||||
for (int i = 0; i < _RoundsTable.Count; i++)
|
||||
for (var i = 0; i < _RoundsTable.Count; i++)
|
||||
{
|
||||
for (int p = 0; p < _RoundsTable[i].TextPlayer.Count; p++)
|
||||
for (var p = 0; p < _RoundsTable[i].TextPlayer.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].Number.Text = i + 1 + _RoundsTableOffset + ")";
|
||||
_RoundsTable[i].TextPlayer[p].Text =
|
||||
CBase.Profiles.GetPlayerName(_PartyMode.GameData.ProfileIDs[_PartyMode.GameData.Rounds[i + _RoundsTableOffset].Players[p]]);
|
||||
CBase.Profiles.GetPlayerName(_PartyMode.GameData.ProfileIds[_PartyMode.GameData.Rounds[i + _RoundsTableOffset].Players[p]]);
|
||||
// ReSharper disable ConvertIfStatementToConditionalTernaryExpression
|
||||
if ((_PartyMode.GameData.CurrentRoundNr - 1) > i + _RoundsTableOffset)
|
||||
if (_PartyMode.GameData.CurrentRoundNr - 1 > i + _RoundsTableOffset)
|
||||
// ReSharper restore ConvertIfStatementToConditionalTernaryExpression
|
||||
{
|
||||
_RoundsTable[i].TextScores[p].Text = _PartyMode.GameData.Results[i + _RoundsTableOffset, p].ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
_RoundsTable[i].TextScores[p].Text = "";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -474,10 +564,11 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
_RoundsTable[i].TextScores[p].Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (_PartyMode.GameData.Rounds.Count < i + _RoundsTableOffset || i + 1 > _NumRoundsVisible)
|
||||
{
|
||||
_RoundsTable[i].Number.Visible = false;
|
||||
for (int p = 0; p < _RoundsTable[i].TextPlayer.Count; p++)
|
||||
for (var p = 0; p < _RoundsTable[i].TextPlayer.Count; p++)
|
||||
{
|
||||
_RoundsTable[i].TextPlayer[p].Visible = false;
|
||||
_RoundsTable[i].TextScores[p].Visible = false;
|
||||
@@ -491,24 +582,24 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
|
||||
private void _BuildPlayerTable()
|
||||
{
|
||||
_PlayerTableScrollArea = new SRectF {X = _Texts[_TextPosition].X, Y = _Texts[_TextPosition].Y, W = _Texts[_TextGamePoints].X - _Texts[_TextPosition].X};
|
||||
_PlayerTableScrollArea = new SRectF { X = _Texts[_TextPosition].X, Y = _Texts[_TextPosition].Y, W = _Texts[_TextGamePoints].X - _Texts[_TextPosition].X };
|
||||
|
||||
_PlayerTable = new List<STableRow>();
|
||||
float delta = _Texts[_TextPosition].Rect.H * 1.2f;
|
||||
var delta = _Texts[_TextPosition].Rect.H * 1.2f;
|
||||
|
||||
float h = 0;
|
||||
|
||||
for (int i = 0; i < 10; i++)
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
var row = new STableRow
|
||||
{
|
||||
Pos = GetNewText(_Texts[_TextPosition]),
|
||||
Name = GetNewText(_Texts[_TextPlayerName]),
|
||||
Rounds = GetNewText(_Texts[_TextNumPlayed]),
|
||||
Won = GetNewText(_Texts[_TextWon]),
|
||||
SingPoints = GetNewText(_Texts[_TextSingPoints]),
|
||||
GamePoints = GetNewText(_Texts[_TextGamePoints])
|
||||
};
|
||||
{
|
||||
Pos = GetNewText(_Texts[_TextPosition]),
|
||||
Name = GetNewText(_Texts[_TextPlayerName]),
|
||||
Rounds = GetNewText(_Texts[_TextNumPlayed]),
|
||||
Won = GetNewText(_Texts[_TextWon]),
|
||||
SingPoints = GetNewText(_Texts[_TextSingPoints]),
|
||||
GamePoints = GetNewText(_Texts[_TextGamePoints])
|
||||
};
|
||||
|
||||
row.Pos.Y += delta * (i + 1);
|
||||
row.Name.Y += delta * (i + 1);
|
||||
@@ -517,7 +608,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
row.SingPoints.Y += delta * (i + 1);
|
||||
row.GamePoints.Y += delta * (i + 1);
|
||||
|
||||
row.Pos.Text = (i + 1) + ".";
|
||||
row.Pos.Text = i + 1 + ".";
|
||||
|
||||
row.Pos.Visible = false;
|
||||
row.Name.Visible = false;
|
||||
@@ -537,14 +628,15 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
|
||||
h = delta * (i + 1);
|
||||
}
|
||||
|
||||
_PlayerTableScrollArea.H = h + delta;
|
||||
}
|
||||
|
||||
private void _UpdatePlayerTable()
|
||||
{
|
||||
for (int i = 0; i < _PlayerTable.Count; i++)
|
||||
for (var i = 0; i < _PlayerTable.Count; i++)
|
||||
{
|
||||
STableRow row = _PlayerTable[i];
|
||||
var row = _PlayerTable[i];
|
||||
|
||||
if (i + _PlayerTableOffset < _PartyMode.GameData.ResultTable.Count)
|
||||
{
|
||||
@@ -556,7 +648,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
row.GamePoints.Visible = true;
|
||||
|
||||
row.Pos.Text = _PartyMode.GameData.ResultTable[i + _PlayerTableOffset].Position + ".";
|
||||
row.Name.Text = CBase.Profiles.GetPlayerName(_PartyMode.GameData.ResultTable[i + _PlayerTableOffset].PlayerID);
|
||||
row.Name.Text = CBase.Profiles.GetPlayerName(_PartyMode.GameData.ResultTable[i + _PlayerTableOffset].PlayerId);
|
||||
row.Rounds.Text = _PartyMode.GameData.ResultTable[i + _PlayerTableOffset].NumPlayed.ToString();
|
||||
row.Won.Text = _PartyMode.GameData.ResultTable[i + _PlayerTableOffset].NumWon.ToString();
|
||||
row.SingPoints.Text = _PartyMode.GameData.ResultTable[i + _PlayerTableOffset].NumSingPoints.ToString();
|
||||
@@ -574,21 +666,31 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
}
|
||||
|
||||
_Buttons[_ButtonPlayerScrollUp].Visible = _PlayerTableOffset > 0;
|
||||
_Buttons[_ButtonPlayerScrollDown].Visible = _PartyMode.GameData.ProfileIDs.Count - _NumPlayerVisible - _PlayerTableOffset > 0;
|
||||
_Buttons[_ButtonPlayerScrollDown].Visible = _PartyMode.GameData.ProfileIds.Count - _NumPlayerVisible - _PlayerTableOffset > 0;
|
||||
}
|
||||
|
||||
private void _ScrollPlayerTable(int offset)
|
||||
{
|
||||
if (_PartyMode.GameData.ProfileIDs.Count <= _NumPlayerVisible)
|
||||
if (_PartyMode.GameData.ProfileIds.Count <= _NumPlayerVisible)
|
||||
{
|
||||
_PlayerTableOffset = 0;
|
||||
}
|
||||
else if (offset < 0 && _PlayerTableOffset + offset >= 0)
|
||||
{
|
||||
_PlayerTableOffset += offset;
|
||||
}
|
||||
else if (offset < 0 && _PlayerTableOffset + offset < 0)
|
||||
{
|
||||
_PlayerTableOffset = 0;
|
||||
else if (offset > 0 && _PlayerTableOffset + offset <= _PartyMode.GameData.ProfileIDs.Count - _NumPlayerVisible)
|
||||
}
|
||||
else if (offset > 0 && _PlayerTableOffset + offset <= _PartyMode.GameData.ProfileIds.Count - _NumPlayerVisible)
|
||||
{
|
||||
_PlayerTableOffset += offset;
|
||||
else if (offset > 0 && _PlayerTableOffset + offset > _PartyMode.GameData.ProfileIDs.Count - _NumPlayerVisible)
|
||||
_PlayerTableOffset = _PartyMode.GameData.ProfileIDs.Count - _NumPlayerVisible;
|
||||
}
|
||||
else if (offset > 0 && _PlayerTableOffset + offset > _PartyMode.GameData.ProfileIds.Count - _NumPlayerVisible)
|
||||
{
|
||||
_PlayerTableOffset = _PartyMode.GameData.ProfileIds.Count - _NumPlayerVisible;
|
||||
}
|
||||
|
||||
_UpdatePlayerTable();
|
||||
}
|
||||
@@ -596,36 +698,51 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
private void _ScrollRoundsTable(int offset)
|
||||
{
|
||||
if (_PartyMode.GameData.Rounds.Count <= _NumRoundsVisible)
|
||||
{
|
||||
_RoundsTableOffset = 0;
|
||||
}
|
||||
else if (offset < 0 && _RoundsTableOffset + offset >= 0)
|
||||
{
|
||||
_RoundsTableOffset += offset;
|
||||
}
|
||||
else if (offset < 0 && _RoundsTableOffset + offset < 0)
|
||||
{
|
||||
_RoundsTableOffset = 0;
|
||||
}
|
||||
else if (offset > 0 && _RoundsTableOffset + offset <= _PartyMode.GameData.Rounds.Count - _NumRoundsVisible)
|
||||
{
|
||||
_RoundsTableOffset += offset;
|
||||
}
|
||||
else if (offset > 0 && _RoundsTableOffset + offset > _PartyMode.GameData.Rounds.Count - _NumRoundsVisible)
|
||||
{
|
||||
_RoundsTableOffset = _PartyMode.GameData.Rounds.Count - _NumRoundsVisible;
|
||||
}
|
||||
|
||||
_UpdateRoundsTable();
|
||||
}
|
||||
|
||||
private string _GetPlayerWinString()
|
||||
{
|
||||
string s = "";
|
||||
var s = "";
|
||||
|
||||
for (int i = 0; i < _PartyMode.GameData.ResultTable.Count; i++)
|
||||
for (var i = 0; i < _PartyMode.GameData.ResultTable.Count; i++)
|
||||
{
|
||||
if (_PartyMode.GameData.ResultTable[i].Position == 1)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
s += ", ";
|
||||
s += CBase.Profiles.GetPlayerName(_PartyMode.GameData.ResultTable[i].PlayerID);
|
||||
}
|
||||
|
||||
s += CBase.Profiles.GetPlayerName(_PartyMode.GameData.ResultTable[i].PlayerId);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
{
|
||||
// ReSharper disable UnusedMember.Global
|
||||
public class CPartyScreenChallengeNames : CMenuPartyNameSelection
|
||||
// ReSharper restore UnusedMember.Global
|
||||
// ReSharper restore UnusedMember.Global
|
||||
{
|
||||
// Version number for theme files. Increment it, if you've changed something on the theme files!
|
||||
protected override int _ScreenVersion
|
||||
@@ -45,24 +45,32 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
{
|
||||
base.OnShow();
|
||||
SetPartyModeData(_PartyMode.GameData.NumPlayer);
|
||||
while (_PartyMode.GameData.ProfileIDs.Count > _NumPlayer)
|
||||
_PartyMode.GameData.ProfileIDs.RemoveAt(_PartyMode.GameData.ProfileIDs.Count - 1);
|
||||
while (_PartyMode.GameData.ProfileIds.Count > _NumPlayer)
|
||||
{
|
||||
_PartyMode.GameData.ProfileIds.RemoveAt(_PartyMode.GameData.ProfileIds.Count - 1);
|
||||
}
|
||||
|
||||
List<Guid>[] ids = new List<Guid>[] {_PartyMode.GameData.ProfileIDs};
|
||||
var ids = new List<Guid>[] { _PartyMode.GameData.ProfileIds };
|
||||
SetPartyModeProfiles(ids);
|
||||
}
|
||||
|
||||
public override void Back()
|
||||
{
|
||||
if (_TeamList.Length == 1)
|
||||
_PartyMode.GameData.ProfileIDs = _TeamList[0];
|
||||
{
|
||||
_PartyMode.GameData.ProfileIds = _TeamList[0];
|
||||
}
|
||||
|
||||
_PartyMode.Back();
|
||||
}
|
||||
|
||||
public override void Next()
|
||||
{
|
||||
if (_TeamList.Length == 1)
|
||||
_PartyMode.GameData.ProfileIDs = _TeamList[0];
|
||||
{
|
||||
_PartyMode.GameData.ProfileIds = _TeamList[0];
|
||||
}
|
||||
|
||||
_PartyMode.Next();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using VocaluxeLib.Menu;
|
||||
using VocaluxeLib.Menu;
|
||||
|
||||
namespace VocaluxeLib.PartyModes.Challenge
|
||||
{
|
||||
@@ -26,7 +22,7 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
Source = _PartyMode.GameData.SongSource;
|
||||
Sorting = _PartyMode.GameData.Sorting;
|
||||
Category = _PartyMode.GameData.CategoryIndex;
|
||||
Playlist = _PartyMode.GameData.PlaylistID;
|
||||
Playlist = _PartyMode.GameData.PlaylistId;
|
||||
SongMode = _PartyMode.GameData.GameMode;
|
||||
NumMedleySongs = _PartyMode.GameData.NumMedleySongs;
|
||||
|
||||
@@ -62,9 +58,9 @@ namespace VocaluxeLib.PartyModes.Challenge
|
||||
_PartyMode.GameData.SongSource = Source;
|
||||
_PartyMode.GameData.Sorting = Sorting;
|
||||
_PartyMode.GameData.CategoryIndex = Category;
|
||||
_PartyMode.GameData.PlaylistID = Playlist;
|
||||
_PartyMode.GameData.PlaylistId = Playlist;
|
||||
_PartyMode.GameData.GameMode = SongMode;
|
||||
_PartyMode.GameData.NumMedleySongs = NumMedleySongs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<CodeAnalysisRuleSet>..\..\CheckingRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseWin|AnyCPU'">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@@ -40,6 +41,7 @@
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugLinux|AnyCPU'">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@@ -52,6 +54,7 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseLinux|AnyCPU'">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@@ -65,6 +68,7 @@
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'InstallerWin|AnyCPU'">
|
||||
<OutputPath>bin</OutputPath>
|
||||
@@ -78,6 +82,7 @@
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CChallengeRounds.cs" />
|
||||
@@ -119,4 +124,4 @@ rm -f "$(SolutionDir)Output\PartyModes\$(TargetName)\Code\GlobalSuppressions.cs"
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -17,12 +17,10 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using VocaluxeLib.Game;
|
||||
using VocaluxeLib.Menu;
|
||||
using VocaluxeLib.Songs;
|
||||
using VocaluxeLib.Utils;
|
||||
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
@@ -30,7 +28,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
{
|
||||
public class CRound
|
||||
{
|
||||
public int[] SongIDs;
|
||||
public int[] SongIds;
|
||||
public int SingerTeam1;
|
||||
public int SingerTeam2;
|
||||
public int PointsTeam1;
|
||||
@@ -90,7 +88,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
|
||||
public readonly EGameMode[] AvailableGameModes = { EGameMode.TR_GAMEMODE_NORMAL, EGameMode.TR_GAMEMODE_SHORTSONG, EGameMode.TR_GAMEMODE_DUET };
|
||||
|
||||
private enum EStage
|
||||
private enum EStage
|
||||
{
|
||||
Config,
|
||||
Songs,
|
||||
@@ -106,13 +104,13 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
public int NumFields;
|
||||
public int NumJockers;
|
||||
public int Team;
|
||||
public List<Guid> ProfileIDsTeam1;
|
||||
public List<Guid> ProfileIDsTeam2;
|
||||
public List<Guid> ProfileIdsTeam1;
|
||||
public List<Guid> ProfileIdsTeam2;
|
||||
|
||||
public ESongSource SongSource;
|
||||
public ESongSorting Sorting;
|
||||
public int CategoryIndex;
|
||||
public int PlaylistID;
|
||||
public int PlaylistId;
|
||||
|
||||
public EGameMode GameMode;
|
||||
public int NumMedleySongs;
|
||||
@@ -137,35 +135,35 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_ScreenSongOptions.Selection.RandomOnly = false;
|
||||
_ScreenSongOptions.Selection.PartyMode = true;
|
||||
_ScreenSongOptions.Selection.CategoryChangeAllowed = true;
|
||||
_ScreenSongOptions.Selection.NumJokers = new int[] {5, 5};
|
||||
_ScreenSongOptions.Selection.TeamNames = new string[] {"foo", "bar"};
|
||||
_ScreenSongOptions.Selection.NumJokers = new int[] { 5, 5 };
|
||||
_ScreenSongOptions.Selection.TeamNames = new string[] { "foo", "bar" };
|
||||
|
||||
_ScreenSongOptions.Sorting.SearchString = String.Empty;
|
||||
_ScreenSongOptions.Sorting.SearchString = string.Empty;
|
||||
_ScreenSongOptions.Sorting.SearchActive = false;
|
||||
_ScreenSongOptions.Sorting.DuetOptions = EDuetOptions.NoDuets;
|
||||
|
||||
GameData = new SData
|
||||
{
|
||||
NumPlayerTeam1 = 2,
|
||||
NumPlayerTeam2 = 2,
|
||||
NumFields = 9,
|
||||
NumJockers = 1,
|
||||
ProfileIDsTeam1 = new List<Guid>(),
|
||||
ProfileIDsTeam2 = new List<Guid>(),
|
||||
CurrentRoundNr = 0,
|
||||
FieldNr = 0,
|
||||
Sorting = CBase.Config.GetSongSorting(),
|
||||
SongSource = ESongSource.TR_SONGSOURCE_ALLSONGS,
|
||||
PlaylistID = 0,
|
||||
CategoryIndex = 0,
|
||||
GameMode = EGameMode.TR_GAMEMODE_NORMAL,
|
||||
NumMedleySongs = 5,
|
||||
Rounds = new List<CRound>(),
|
||||
Songs = new List<int>(),
|
||||
NumJokerRandom = new int[2],
|
||||
NumJokerRetry = new int[2],
|
||||
RefillJokers = EOffOn.TR_CONFIG_OFF
|
||||
};
|
||||
{
|
||||
NumPlayerTeam1 = 2,
|
||||
NumPlayerTeam2 = 2,
|
||||
NumFields = 9,
|
||||
NumJockers = 1,
|
||||
ProfileIdsTeam1 = new List<Guid>(),
|
||||
ProfileIdsTeam2 = new List<Guid>(),
|
||||
CurrentRoundNr = 0,
|
||||
FieldNr = 0,
|
||||
Sorting = CBase.Config.GetSongSorting(),
|
||||
SongSource = ESongSource.TR_SONGSOURCE_ALLSONGS,
|
||||
PlaylistId = 0,
|
||||
CategoryIndex = 0,
|
||||
GameMode = EGameMode.TR_GAMEMODE_NORMAL,
|
||||
NumMedleySongs = 5,
|
||||
Rounds = new List<CRound>(),
|
||||
Songs = new List<int>(),
|
||||
NumJokerRandom = new int[2],
|
||||
NumJokerRetry = new int[2],
|
||||
RefillJokers = EOffOn.TR_CONFIG_OFF
|
||||
};
|
||||
}
|
||||
|
||||
public override void SetDefaults()
|
||||
@@ -178,7 +176,9 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_ScreenSongOptions.Selection.SongIndex = -1;
|
||||
|
||||
if (CBase.Config.GetTabs() == EOffOn.TR_CONFIG_ON && _ScreenSongOptions.Sorting.SongSorting != ESongSorting.TR_CONFIG_NONE)
|
||||
{
|
||||
_ScreenSongOptions.Sorting.Tabs = EOffOn.TR_CONFIG_ON;
|
||||
}
|
||||
|
||||
GameData.Songs.Clear();
|
||||
GameData.Rounds.Clear();
|
||||
@@ -187,7 +187,9 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
public override bool Init()
|
||||
{
|
||||
if (!base.Init())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
SetDefaults();
|
||||
return true;
|
||||
@@ -224,7 +226,9 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
private void _FadeToScreen()
|
||||
{
|
||||
if (CBase.Graphics.GetNextScreen() != _GetNextScreen())
|
||||
{
|
||||
CBase.Graphics.FadeTo(_GetNextScreen());
|
||||
}
|
||||
}
|
||||
|
||||
public void Next()
|
||||
@@ -253,11 +257,15 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_Stage = EStage.Main;
|
||||
GameData.Team = GameData.Team == 1 ? 0 : 1;
|
||||
if (GameData.RefillJokers == EOffOn.TR_CONFIG_ON)
|
||||
{
|
||||
_SetNumJokers();
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException("Invalid stage: " + _Stage);
|
||||
}
|
||||
|
||||
_FadeToScreen();
|
||||
}
|
||||
|
||||
@@ -280,6 +288,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
default: // Rest is not allowed
|
||||
throw new ArgumentException("Invalid stage: " + _Stage);
|
||||
}
|
||||
|
||||
_FadeToScreen();
|
||||
}
|
||||
|
||||
@@ -308,16 +317,16 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
throw new ArgumentException("Not required!");
|
||||
}
|
||||
|
||||
public override void JokerUsed(int teamNr) {}
|
||||
public override void JokerUsed(int teamNr) { }
|
||||
|
||||
public override void SongSelected(int songID)
|
||||
public override void SongSelected(int songId)
|
||||
{
|
||||
throw new ArgumentException("Not required!");
|
||||
}
|
||||
|
||||
public override void LeavingHighscore()
|
||||
{
|
||||
CBase.Songs.AddPartySongSung(CBase.Game.GetSong(0).ID);
|
||||
CBase.Songs.AddPartySongSung(CBase.Game.GetSong(0).Id);
|
||||
_UpdateScores();
|
||||
Next();
|
||||
}
|
||||
@@ -325,7 +334,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
private void _CreateRounds()
|
||||
{
|
||||
GameData.Rounds = new List<CRound>();
|
||||
for (int i = 0; i < GameData.NumFields; i++)
|
||||
for (var i = 0; i < GameData.NumFields; i++)
|
||||
{
|
||||
var r = new CRound();
|
||||
GameData.Rounds.Add(r);
|
||||
@@ -335,33 +344,39 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
public void UpdateSongList()
|
||||
{
|
||||
if (GameData.Songs.Count > 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (GameData.SongSource)
|
||||
{
|
||||
case ESongSource.TR_SONGSOURCE_PLAYLIST:
|
||||
for (int i = 0; i < CBase.Playlist.GetSongCount(GameData.PlaylistID); i++)
|
||||
for (var 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(GameData.GameMode))
|
||||
var id = CBase.Playlist.GetSong(GameData.PlaylistId, i).SongId;
|
||||
if (CBase.Songs.GetSongById(id).IsGameModeAvailable(GameData.GameMode))
|
||||
{
|
||||
GameData.Songs.Add(id);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case ESongSource.TR_SONGSOURCE_ALLSONGS:
|
||||
ReadOnlyCollection<CSong> avSongs = CBase.Songs.GetSongs();
|
||||
GameData.Songs.AddRange(avSongs.Where(song => song.AvailableGameModes.Contains(GameData.GameMode)).Select(song => song.ID));
|
||||
var avSongs = CBase.Songs.GetSongs();
|
||||
GameData.Songs.AddRange(avSongs.Where(song => song.IsGameModeAvailable(GameData.GameMode)).Select(song => song.Id));
|
||||
break;
|
||||
|
||||
case ESongSource.TR_SONGSOURCE_CATEGORY:
|
||||
CBase.Songs.SortSongs(GameData.Sorting, EOffOn.TR_CONFIG_ON, CBase.Config.GetIgnoreArticles(), "", EDuetOptions.All, -1);
|
||||
CBase.Songs.SetCategory(GameData.CategoryIndex);
|
||||
avSongs = CBase.Songs.GetVisibleSongs();
|
||||
GameData.Songs.AddRange(avSongs.Where(song => song.AvailableGameModes.Contains(GameData.GameMode)).Select(song => song.ID));
|
||||
GameData.Songs.AddRange(avSongs.Where(song => song.IsGameModeAvailable(GameData.GameMode)).Select(song => song.Id));
|
||||
|
||||
CBase.Songs.SetCategory(-1);
|
||||
break;
|
||||
}
|
||||
|
||||
GameData.Songs.Shuffle();
|
||||
}
|
||||
|
||||
@@ -372,32 +387,37 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
|
||||
CBase.Game.SetNumPlayer(2);
|
||||
|
||||
SPlayer[] players = CBase.Game.GetPlayers();
|
||||
var players = CBase.Game.GetPlayers();
|
||||
if (players == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (players.Length < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CRound round = GameData.Rounds[roundNr];
|
||||
var round = GameData.Rounds[roundNr];
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
//default values
|
||||
players[i].ProfileID = Guid.Empty;
|
||||
players[i].ProfileId = Guid.Empty;
|
||||
}
|
||||
|
||||
//try to fill with the right data
|
||||
players[0].ProfileID = GameData.ProfileIDsTeam1[round.SingerTeam1];
|
||||
players[1].ProfileID = GameData.ProfileIDsTeam2[round.SingerTeam2];
|
||||
players[0].ProfileId = GameData.ProfileIdsTeam1[round.SingerTeam1];
|
||||
players[1].ProfileId = GameData.ProfileIdsTeam2[round.SingerTeam2];
|
||||
|
||||
foreach(int song in round.SongIDs)
|
||||
foreach (var song in round.SongIds)
|
||||
{
|
||||
CBase.Game.AddSong(song, GameData.GameMode);
|
||||
}
|
||||
}
|
||||
|
||||
private void _SetNumJokers()
|
||||
{
|
||||
|
||||
GameData.NumJokerRandom[0] = GameData.NumJockers;
|
||||
GameData.NumJokerRandom[1] = GameData.NumJockers;
|
||||
|
||||
@@ -423,19 +443,23 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
private void _UpdateScores()
|
||||
{
|
||||
if (!GameData.Rounds[GameData.FieldNr].Finished)
|
||||
{
|
||||
GameData.CurrentRoundNr++;
|
||||
}
|
||||
|
||||
CPoints points = CBase.Game.GetPoints();
|
||||
SPlayer[] results = CBase.Game.GetPlayers();
|
||||
var points = CBase.Game.GetPoints();
|
||||
var results = CBase.Game.GetPlayers();
|
||||
|
||||
if (results == null || results.Length < 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Sum up all points
|
||||
for (int r = 0; r < points.NumRounds; r++)
|
||||
for (var r = 0; r < points.NumRounds; r++)
|
||||
{
|
||||
SPlayer[] player = points.GetPlayer(r, 2);
|
||||
for (int i = 0; i < 2; i++)
|
||||
var player = points.GetPlayer(r, 2);
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
results[i].Points += player[i].Points;
|
||||
results[i].PointsGoldenNotes += player[i].PointsGoldenNotes;
|
||||
@@ -444,7 +468,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
}
|
||||
|
||||
//Calc average of points
|
||||
for (int i = 0; i < 2; i++)
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
results[i].Points /= points.NumRounds;
|
||||
results[i].PointsGoldenNotes /= points.NumRounds;
|
||||
@@ -456,9 +480,13 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
GameData.Rounds[GameData.FieldNr].PointsTeam2 = (int)Math.Round(results[1].Points);
|
||||
GameData.Rounds[GameData.FieldNr].Finished = true;
|
||||
if (GameData.Rounds[GameData.FieldNr].PointsTeam1 < GameData.Rounds[GameData.FieldNr].PointsTeam2)
|
||||
{
|
||||
GameData.Rounds[GameData.FieldNr].Winner = 2;
|
||||
}
|
||||
else if (GameData.Rounds[GameData.FieldNr].PointsTeam1 > GameData.Rounds[GameData.FieldNr].PointsTeam2)
|
||||
{
|
||||
GameData.Rounds[GameData.FieldNr].Winner = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
GameData.Rounds[GameData.FieldNr].Finished = false;
|
||||
|
||||
@@ -16,11 +16,8 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using VocaluxeLib.Songs;
|
||||
|
||||
namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
{
|
||||
@@ -71,10 +68,15 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_UpdateSlides();
|
||||
|
||||
if (_Buttons[_ButtonBack].Selected)
|
||||
{
|
||||
_PartyMode.Back();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonNext].Selected)
|
||||
{
|
||||
_PartyMode.Next();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Keys.Left:
|
||||
@@ -86,6 +88,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -97,14 +100,20 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
{
|
||||
_UpdateSlides();
|
||||
if (_Buttons[_ButtonBack].Selected)
|
||||
{
|
||||
_PartyMode.Back();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonNext].Selected)
|
||||
{
|
||||
_PartyMode.Next();
|
||||
}
|
||||
}
|
||||
|
||||
if (mouseEvent.RB)
|
||||
{
|
||||
_PartyMode.Back();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -135,8 +144,10 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_SelectSlides[_SelectSlideNumFields].SelectedTag = _PartyMode.GameData.NumFields;
|
||||
|
||||
_SelectSlides[_SelectSlideNumJockers].Clear();
|
||||
for (int i = 0; i <= 3; i++)
|
||||
for (var i = 0; i <= 3; i++)
|
||||
{
|
||||
_SelectSlides[_SelectSlideNumJockers].AddValue(i);
|
||||
}
|
||||
|
||||
_SelectSlides[_SelectSlideNumJockers].SelectedTag = _PartyMode.GameData.NumJockers;
|
||||
|
||||
|
||||
@@ -17,10 +17,8 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using VocaluxeLib.Menu;
|
||||
using VocaluxeLib.Songs;
|
||||
|
||||
namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
{
|
||||
@@ -71,7 +69,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
private const string _StaticTeam2 = "StaticTeam2";
|
||||
|
||||
private readonly string[] _EqualizerTeam = new string[]
|
||||
{"EqualizerTeam1", "EqualizerTeam2"};
|
||||
{ "EqualizerTeam1", "EqualizerTeam2" };
|
||||
|
||||
private bool _ExitPopupVisible;
|
||||
|
||||
@@ -97,12 +95,12 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
base.Init();
|
||||
|
||||
_ThemeTexts = new string[]
|
||||
{_TextPopupReallyExit, _TextTeamChoosing, _TextFinishMessage, _TextNextPlayerT1, _TextNextPlayerT2, _TextNextPlayerNameT1, _TextNextPlayerNameT2};
|
||||
{ _TextPopupReallyExit, _TextTeamChoosing, _TextFinishMessage, _TextNextPlayerT1, _TextNextPlayerT2, _TextNextPlayerNameT1, _TextNextPlayerNameT2 };
|
||||
_ThemeButtons = new string[]
|
||||
{
|
||||
_ButtonNextRound, _ButtonBack, _ButtonExit, _ButtonPopupYes, _ButtonPopupNo, _ButtonField, _ButtonJokerRandomT1, _ButtonJokerRandomT2, _ButtonJokerRetryT1,
|
||||
_ButtonJokerRetryT2, _ButtonSwitchPlayerT1, _ButtonSwitchPlayerT2
|
||||
};
|
||||
{
|
||||
_ButtonNextRound, _ButtonBack, _ButtonExit, _ButtonPopupYes, _ButtonPopupNo, _ButtonField, _ButtonJokerRandomT1, _ButtonJokerRandomT2, _ButtonJokerRetryT1,
|
||||
_ButtonJokerRetryT2, _ButtonSwitchPlayerT1, _ButtonSwitchPlayerT2
|
||||
};
|
||||
_ThemeStatics = new string[] { _StaticPopupBG, _StaticAvatarT1, _StaticAvatarT2, _StaticTeam1, _StaticTeam2 };
|
||||
|
||||
var texts = new List<string>();
|
||||
@@ -135,28 +133,48 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
if (!_ExitPopupVisible)
|
||||
{
|
||||
if (_PartyMode.GameData.CurrentRoundNr == 1 && _Status != EStatus.FieldSelected)
|
||||
{
|
||||
_Back();
|
||||
}
|
||||
else if (_Status == EStatus.None)
|
||||
{
|
||||
_EndParty();
|
||||
}
|
||||
else
|
||||
{
|
||||
_ShowPopup(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_ShowPopup(false);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Keys.Enter:
|
||||
if (!_ExitPopupVisible)
|
||||
{
|
||||
if (_Buttons[_ButtonNextRound].Selected)
|
||||
{
|
||||
_NextRound();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonBack].Selected && _PartyMode.GameData.CurrentRoundNr == 1 && _Status != EStatus.FieldSelected)
|
||||
{
|
||||
_Back();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonExit].Selected && (_PartyMode.GameData.CurrentRoundNr > 1 || _Status == EStatus.FieldSelected) && _Status != EStatus.None)
|
||||
{
|
||||
_ShowPopup(true);
|
||||
}
|
||||
else if (_Status == EStatus.None)
|
||||
{
|
||||
_EndParty();
|
||||
for (int i = 0; i < _PartyMode.GameData.NumFields; i++)
|
||||
}
|
||||
|
||||
for (var i = 0; i < _PartyMode.GameData.NumFields; i++)
|
||||
{
|
||||
switch (_Status)
|
||||
{
|
||||
@@ -166,6 +184,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_PartyMode.GameData.FieldNr = i;
|
||||
_FieldSelected();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EStatus.JokerRetry:
|
||||
@@ -174,35 +193,61 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_PartyMode.GameData.FieldNr = i;
|
||||
_FieldSelectedAgain();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_Status == EStatus.FieldSelected)
|
||||
{
|
||||
if (_Buttons[_ButtonJokerRandomT1].Selected)
|
||||
{
|
||||
_UseJoker(0, 0);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonJokerRandomT2].Selected)
|
||||
{
|
||||
_UseJoker(1, 0);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonJokerRetryT1].Selected)
|
||||
{
|
||||
_UseJoker(0, 1);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonJokerRetryT2].Selected)
|
||||
{
|
||||
_UseJoker(1, 1);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonSwitchPlayerT1].Selected)
|
||||
{
|
||||
_ChangePlayer(0, true);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonSwitchPlayerT2].Selected)
|
||||
{
|
||||
_ChangePlayer(1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_Buttons[_ButtonPopupYes].Selected)
|
||||
{
|
||||
_EndParty();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonPopupNo].Selected)
|
||||
{
|
||||
_ShowPopup(false);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -215,17 +260,28 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
if (!_ExitPopupVisible)
|
||||
{
|
||||
if (_Buttons[_ButtonNextRound].Selected)
|
||||
{
|
||||
_NextRound();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonBack].Selected)
|
||||
{
|
||||
_Back();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonExit].Selected)
|
||||
{
|
||||
if (_Status == EStatus.None)
|
||||
{
|
||||
_EndParty();
|
||||
}
|
||||
else
|
||||
{
|
||||
_ShowPopup(true);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < _PartyMode.GameData.NumFields; i++)
|
||||
|
||||
for (var i = 0; i < _PartyMode.GameData.NumFields; i++)
|
||||
{
|
||||
switch (_Status)
|
||||
{
|
||||
@@ -235,6 +291,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_PartyMode.GameData.FieldNr = i;
|
||||
_FieldSelected();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case EStatus.JokerRetry:
|
||||
@@ -243,31 +300,55 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_PartyMode.GameData.FieldNr = i;
|
||||
_FieldSelectedAgain();
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_Status == EStatus.FieldSelected)
|
||||
{
|
||||
if (_Buttons[_ButtonJokerRandomT1].Selected)
|
||||
{
|
||||
_UseJoker(0, 0);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonJokerRandomT2].Selected)
|
||||
{
|
||||
_UseJoker(1, 0);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonJokerRetryT1].Selected)
|
||||
{
|
||||
_UseJoker(0, 1);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonJokerRetryT2].Selected)
|
||||
{
|
||||
_UseJoker(1, 1);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonSwitchPlayerT1].Selected)
|
||||
{
|
||||
_ChangePlayer(0, true);
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonSwitchPlayerT2].Selected)
|
||||
{
|
||||
_ChangePlayer(1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_Buttons[_ButtonPopupYes].Selected)
|
||||
{
|
||||
_EndParty();
|
||||
}
|
||||
|
||||
if (_Buttons[_ButtonPopupNo].Selected)
|
||||
{
|
||||
_ShowPopup(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,14 +357,22 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
if (!_ExitPopupVisible)
|
||||
{
|
||||
if (_PartyMode.GameData.CurrentRoundNr == 1 && _Status != EStatus.FieldSelected)
|
||||
{
|
||||
_Back();
|
||||
}
|
||||
else if (_Status == EStatus.None)
|
||||
{
|
||||
_EndParty();
|
||||
}
|
||||
else
|
||||
{
|
||||
_ShowPopup(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_ShowPopup(false);
|
||||
}
|
||||
}
|
||||
|
||||
if (mouseEvent.Wheel != 0) { }
|
||||
@@ -322,7 +411,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_UpdateFields();
|
||||
_UpdateFieldContents();
|
||||
|
||||
int winner = _GetWinner();
|
||||
var winner = _GetWinner();
|
||||
if (_PartyMode.GameData.CurrentRoundNr <= _PartyMode.GameData.NumFields && winner == 0)
|
||||
{
|
||||
_UpdateTeamChoosingMessage();
|
||||
@@ -354,14 +443,15 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
if (winner > 0)
|
||||
{
|
||||
_Texts[_TextFinishMessage].Color = CBase.Themes.GetPlayerColor(winner);
|
||||
_Texts[_TextFinishMessage].Text = CBase.Language.Translate("TR_SCREENMAIN_WINNER", PartyModeID) + " " + CBase.Language.Translate("TR_TEAM", PartyModeID) + " " +
|
||||
_Texts[_TextFinishMessage].Text = CBase.Language.Translate("TR_SCREENMAIN_WINNER", PartyModeId) + " " + CBase.Language.Translate("TR_TEAM", PartyModeId) + " " +
|
||||
winner;
|
||||
}
|
||||
else
|
||||
{
|
||||
_Texts[_TextFinishMessage].Color = new SColorF(1, 1, 1, 1);
|
||||
_Texts[_TextFinishMessage].Text = CBase.Language.Translate("TR_SCREENMAIN_NOWINNER", PartyModeID);
|
||||
_Texts[_TextFinishMessage].Text = CBase.Language.Translate("TR_SCREENMAIN_NOWINNER", PartyModeId);
|
||||
}
|
||||
|
||||
_SelectElement(_Buttons[_ButtonExit]);
|
||||
}
|
||||
|
||||
@@ -371,9 +461,11 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
public override bool UpdateGame()
|
||||
{
|
||||
if (!_Equalizers[_EqualizerTeam[0]].Visible)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
for (var i = 0; i < 2; i++)
|
||||
{
|
||||
CBase.Record.AnalyzeBuffer(i);
|
||||
_Equalizers["EqualizerTeam" + (i + 1)].Update(CBase.Record.ToneWeigth(i), CBase.Record.GetMaxVolume(i));
|
||||
@@ -384,9 +476,9 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
|
||||
private void _CreateFields()
|
||||
{
|
||||
for (int i = 0; i < 25; i++)
|
||||
for (var i = 0; i < 25; i++)
|
||||
{
|
||||
CButton f = GetNewButton(_Buttons[_ButtonField]);
|
||||
var f = GetNewButton(_Buttons[_ButtonField]);
|
||||
f.Visible = false;
|
||||
_AddButton(f);
|
||||
_Fields.Add(f);
|
||||
@@ -396,16 +488,16 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
private void _UpdateFields()
|
||||
{
|
||||
var numOneRow = (int)Math.Sqrt(_PartyMode.GameData.NumFields);
|
||||
float fieldSizeY = ((float)CBase.Settings.GetRenderH() - 150 - numOneRow * _FieldSpace) / numOneRow;
|
||||
float fieldSizeX = ((float)CBase.Settings.GetRenderW() - 300 - numOneRow * _FieldSpace) / numOneRow;
|
||||
var fieldSizeY = ((float)CBase.Settings.GetRenderH() - 150 - numOneRow * _FieldSpace) / numOneRow;
|
||||
var fieldSizeX = ((float)CBase.Settings.GetRenderW() - 300 - numOneRow * _FieldSpace) / numOneRow;
|
||||
_FieldSize = Math.Min(fieldSizeX, fieldSizeY);
|
||||
_FieldFirstX = (float)CBase.Settings.GetRenderW() / 2 - (numOneRow * _FieldSize + (numOneRow - 1) * _FieldSpace) / 2;
|
||||
_FieldFirstY = 140 + (CBase.Settings.GetRenderH() - 140) / 2 - (numOneRow * _FieldSize + numOneRow * _FieldSpace) / 2;
|
||||
int row = 0;
|
||||
int column = 0;
|
||||
float x = _FieldFirstX;
|
||||
float y = _FieldFirstY;
|
||||
for (int i = 0; i < _Fields.Count; i++)
|
||||
var row = 0;
|
||||
var column = 0;
|
||||
var x = _FieldFirstX;
|
||||
var y = _FieldFirstY;
|
||||
for (var i = 0; i < _Fields.Count; i++)
|
||||
{
|
||||
if (i < _PartyMode.GameData.NumFields)
|
||||
{
|
||||
@@ -416,7 +508,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_Fields[i].Visible = true;
|
||||
_Fields[i].Selectable = true;
|
||||
column++;
|
||||
if ((i + 1) >= numOneRow * (row + 1))
|
||||
if (i + 1 >= numOneRow * (row + 1))
|
||||
{
|
||||
column = 0;
|
||||
row++;
|
||||
@@ -424,7 +516,9 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
x = _FieldFirstX;
|
||||
}
|
||||
else
|
||||
{
|
||||
x = _FieldFirstX + _FieldSize * column + _FieldSpace * column;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -436,7 +530,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
|
||||
private void _UpdateFieldContents()
|
||||
{
|
||||
for (int i = 0; i < _PartyMode.GameData.Rounds.Count; i++)
|
||||
for (var i = 0; i < _PartyMode.GameData.Rounds.Count; i++)
|
||||
{
|
||||
_Fields[i].Selectable = true;
|
||||
_Fields[i].Texture = _Buttons[_ButtonField].Texture;
|
||||
@@ -445,26 +539,34 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
if (_PartyMode.GameData.Rounds[i].Finished)
|
||||
{
|
||||
_Fields[i].Selectable = false;
|
||||
_Fields[i].Texture = CBase.Songs.GetSongByID(_PartyMode.GameData.Rounds[i].SongIDs[0]).CoverTextureBig;
|
||||
_Fields[i].Texture = CBase.Songs.GetSongById(_PartyMode.GameData.Rounds[i].SongIds[0]).CoverTextureBig;
|
||||
_Fields[i].Color = CBase.Themes.GetPlayerColor(_PartyMode.GameData.Rounds[i].Winner);
|
||||
_Fields[i].SelColor = CBase.Themes.GetPlayerColor(_PartyMode.GameData.Rounds[i].Winner);
|
||||
}
|
||||
|
||||
if (_Status == EStatus.FieldSelected && _PartyMode.GameData.FieldNr == i)
|
||||
{
|
||||
_Fields[i].Texture = CBase.Songs.GetSongByID(_PartyMode.GameData.Rounds[i].SongIDs[0]).CoverTextureBig;
|
||||
_Fields[i].Texture = CBase.Songs.GetSongById(_PartyMode.GameData.Rounds[i].SongIds[0]).CoverTextureBig;
|
||||
_Fields[i].Color = new SColorF(1, 1, 1, 1);
|
||||
_Fields[i].SelColor = new SColorF(1, 1, 1, 1);
|
||||
_Fields[i].Selectable = false;
|
||||
}
|
||||
|
||||
if (_Status == EStatus.JokerRetry && _PartyMode.GameData.Rounds[i].Finished)
|
||||
{
|
||||
_Fields[i].SelColor = CBase.Themes.GetPlayerColor(_PartyMode.GameData.Team + 1);
|
||||
_Fields[i].Selectable = true;
|
||||
}
|
||||
|
||||
if (_Status == EStatus.JokerRetry && !_PartyMode.GameData.Rounds[i].Finished)
|
||||
{
|
||||
_Fields[i].Selectable = false;
|
||||
}
|
||||
|
||||
if (_Status == EStatus.FieldSelected)
|
||||
{
|
||||
_Fields[i].Selectable = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -474,17 +576,18 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
{
|
||||
_ChangePlayer();
|
||||
}
|
||||
|
||||
_PartyMode.UpdateSongList();
|
||||
int[] songIDs = new int[_PartyMode.GameData.GameMode == EGameMode.TR_GAMEMODE_MEDLEY ? _PartyMode.GameData.NumMedleySongs : 1];
|
||||
for (int i = 0; i < songIDs.Length; i++)
|
||||
var songIds = new int[_PartyMode.GameData.GameMode == EGameMode.TR_GAMEMODE_MEDLEY ? _PartyMode.GameData.NumMedleySongs : 1];
|
||||
for (var i = 0; i < songIds.Length; i++)
|
||||
{
|
||||
songIDs[i] = _PartyMode.GameData.Songs[0];
|
||||
songIds[i] = _PartyMode.GameData.Songs[0];
|
||||
_PartyMode.GameData.Songs.RemoveAt(0);
|
||||
}
|
||||
|
||||
_StartPreview(songIDs[0]);
|
||||
_StartPreview(songIds[0]);
|
||||
_Status = EStatus.FieldSelected;
|
||||
_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SongIDs = songIDs;
|
||||
_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SongIds = songIds;
|
||||
_UpdateFieldContents();
|
||||
_UpdateJokerButtons();
|
||||
_UpdateSwitchPlayerButtons();
|
||||
@@ -498,10 +601,10 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
|
||||
private void _FieldSelectedAgain()
|
||||
{
|
||||
int[] songIDs = _PartyMode.GameData.Rounds[_OldSelectedField].SongIDs;
|
||||
_StartPreview(songIDs[0]);
|
||||
var songIds = _PartyMode.GameData.Rounds[_OldSelectedField].SongIds;
|
||||
_StartPreview(songIds[0]);
|
||||
_Status = EStatus.FieldSelected;
|
||||
_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SongIDs = songIDs;
|
||||
_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SongIds = songIds;
|
||||
_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam1 = _PartyMode.GameData.Rounds[_OldSelectedField].SingerTeam1;
|
||||
_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam2 = _PartyMode.GameData.Rounds[_OldSelectedField].SingerTeam2;
|
||||
_UpdateFieldContents();
|
||||
@@ -516,32 +619,31 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_SelectElement(_Buttons[_ButtonNextRound]);
|
||||
}
|
||||
|
||||
private void _StartPreview(int songID)
|
||||
private void _StartPreview(int songId)
|
||||
{
|
||||
CSong song = CBase.Songs.GetSongByID(songID);
|
||||
var song = CBase.Songs.GetSongById(songId);
|
||||
CBase.BackgroundMusic.LoadPreview(song);
|
||||
}
|
||||
|
||||
private int _GetRamdom(int max)
|
||||
{
|
||||
lock (syncLock)
|
||||
{
|
||||
return random.Next(max+1);
|
||||
{
|
||||
return random.Next(max + 1);
|
||||
}
|
||||
}
|
||||
|
||||
private void _ChangePlayer(int teamNr = -1, bool next = false)
|
||||
{
|
||||
|
||||
if (_PartyMode.GameData.ProfileIDsTeam1.Count > 0 && (teamNr == 0 || teamNr == -1))
|
||||
if (_PartyMode.GameData.ProfileIdsTeam1.Count > 0 && (teamNr == 0 || teamNr == -1))
|
||||
{
|
||||
idPlayer1 = _GetTeamPlayer(idPlayer1, _PartyMode.GameData.ProfileIDsTeam1.Count, next);
|
||||
idPlayer1 = _GetTeamPlayer(idPlayer1, _PartyMode.GameData.ProfileIdsTeam1.Count, next);
|
||||
_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam1 = idPlayer1;
|
||||
}
|
||||
|
||||
if (_PartyMode.GameData.ProfileIDsTeam2.Count > 0 && (teamNr == 1 || teamNr == -1))
|
||||
if (_PartyMode.GameData.ProfileIdsTeam2.Count > 0 && (teamNr == 1 || teamNr == -1))
|
||||
{
|
||||
idPlayer2 = _GetTeamPlayer(idPlayer2, _PartyMode.GameData.ProfileIDsTeam2.Count, next);
|
||||
idPlayer2 = _GetTeamPlayer(idPlayer2, _PartyMode.GameData.ProfileIdsTeam2.Count, next);
|
||||
_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam2 = idPlayer2;
|
||||
}
|
||||
|
||||
@@ -553,15 +655,16 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
if (next)
|
||||
{
|
||||
idPlayer++;
|
||||
if (idPlayer >= _PartyMode.GameData.ProfileIDsTeam1.Count)
|
||||
if (idPlayer >= _PartyMode.GameData.ProfileIdsTeam1.Count)
|
||||
{
|
||||
idPlayer = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
idPlayer = _GetRamdom(_PartyMode.GameData.ProfileIDsTeam1.Count - 1);
|
||||
idPlayer = _GetRamdom(_PartyMode.GameData.ProfileIdsTeam1.Count - 1);
|
||||
}
|
||||
|
||||
return idPlayer;
|
||||
}
|
||||
|
||||
@@ -572,13 +675,13 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_Texts[_TextNextPlayerNameT1].Visible = true;
|
||||
_Texts[_TextNextPlayerNameT2].Visible = true;
|
||||
_Texts[_TextNextPlayerNameT1].Text =
|
||||
CBase.Profiles.GetPlayerName(_PartyMode.GameData.ProfileIDsTeam1[_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam1]);
|
||||
CBase.Profiles.GetPlayerName(_PartyMode.GameData.ProfileIdsTeam1[_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam1]);
|
||||
_Texts[_TextNextPlayerNameT2].Text =
|
||||
CBase.Profiles.GetPlayerName(_PartyMode.GameData.ProfileIDsTeam2[_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam2]);
|
||||
CBase.Profiles.GetPlayerName(_PartyMode.GameData.ProfileIdsTeam2[_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam2]);
|
||||
_Statics[_StaticAvatarT1].Visible = true;
|
||||
_Statics[_StaticAvatarT2].Visible = true;
|
||||
_Statics[_StaticAvatarT1].Texture = CBase.Profiles.GetAvatar(_PartyMode.GameData.ProfileIDsTeam1[_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam1]);
|
||||
_Statics[_StaticAvatarT2].Texture = CBase.Profiles.GetAvatar(_PartyMode.GameData.ProfileIDsTeam2[_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam2]);
|
||||
_Statics[_StaticAvatarT1].Texture = CBase.Profiles.GetAvatar(_PartyMode.GameData.ProfileIdsTeam1[_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam1]);
|
||||
_Statics[_StaticAvatarT2].Texture = CBase.Profiles.GetAvatar(_PartyMode.GameData.ProfileIdsTeam2[_PartyMode.GameData.Rounds[_PartyMode.GameData.FieldNr].SingerTeam2]);
|
||||
_Statics[_StaticTeam1].Visible = true;
|
||||
_Statics[_StaticTeam2].Visible = true;
|
||||
_Equalizers[_EqualizerTeam[0]].Visible = true;
|
||||
@@ -596,6 +699,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_PartyMode.GameData.NumJokerRandom[teamNr]--;
|
||||
_FieldSelected(true);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
//Retry-Joker
|
||||
@@ -610,20 +714,26 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_UpdateFieldContents();
|
||||
_Buttons[_ButtonNextRound].Visible = false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
_UpdateJokerButtons();
|
||||
}
|
||||
|
||||
private void _UpdateTeamChoosingMessage()
|
||||
{
|
||||
_Texts[_TextTeamChoosing].Color = CBase.Themes.GetPlayerColor(_PartyMode.GameData.Team + 1);
|
||||
_Texts[_TextTeamChoosing].Text = CBase.Language.Translate("TR_TEAM", PartyModeID) + " " + (_PartyMode.GameData.Team + 1) + "! " +
|
||||
CBase.Language.Translate("TR_SCREENMAIN_TEAM_CHOOSE", PartyModeID);
|
||||
_Texts[_TextTeamChoosing].Text = CBase.Language.Translate("TR_TEAM", PartyModeId) + " " + (_PartyMode.GameData.Team + 1) + "! " +
|
||||
CBase.Language.Translate("TR_SCREENMAIN_TEAM_CHOOSE", PartyModeId);
|
||||
if (_Status == EStatus.JokerRetry || _Status == EStatus.FieldChoosing)
|
||||
{
|
||||
_Texts[_TextTeamChoosing].Visible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_Texts[_TextTeamChoosing].Visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void _UpdateJokerButtons()
|
||||
@@ -649,7 +759,6 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_Buttons[_ButtonSwitchPlayerT1].Visible = true;
|
||||
_Buttons[_ButtonSwitchPlayerT2].Visible = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void _NextRound()
|
||||
@@ -672,7 +781,9 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_Buttons[_ButtonPopupNo].Visible = _ExitPopupVisible;
|
||||
|
||||
if (_ExitPopupVisible)
|
||||
{
|
||||
_SelectElement(_Buttons[_ButtonPopupNo]);
|
||||
}
|
||||
}
|
||||
|
||||
private void _Back()
|
||||
@@ -683,51 +794,71 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
private void _BuildWinnerPossibilities()
|
||||
{
|
||||
var numOneRow = (int)Math.Sqrt(_PartyMode.GameData.NumFields);
|
||||
_Possibilities = new int[(numOneRow * 2) + 2, numOneRow];
|
||||
for (int i = 0; i < _Possibilities.GetLength(0); i++)
|
||||
_Possibilities = new int[numOneRow * 2 + 2, numOneRow];
|
||||
for (var i = 0; i < _Possibilities.GetLength(0); i++)
|
||||
{
|
||||
if (i < numOneRow)
|
||||
{
|
||||
for (int c = 0; c < numOneRow; c++)
|
||||
for (var c = 0; c < numOneRow; c++)
|
||||
{
|
||||
_Possibilities[i, c] = i * numOneRow + c;
|
||||
}
|
||||
}
|
||||
else if (i < numOneRow * 2)
|
||||
{
|
||||
for (int c = 0; c < numOneRow; c++)
|
||||
_Possibilities[i, c] = (i - numOneRow) + (c * numOneRow);
|
||||
for (var c = 0; c < numOneRow; c++)
|
||||
{
|
||||
_Possibilities[i, c] = i - numOneRow + c * numOneRow;
|
||||
}
|
||||
}
|
||||
else if (i == _Possibilities.GetLength(0) - 2)
|
||||
{
|
||||
for (int c = 0; c < numOneRow; c++)
|
||||
for (var c = 0; c < numOneRow; c++)
|
||||
{
|
||||
_Possibilities[i, c] = (numOneRow + 1) * c;
|
||||
}
|
||||
}
|
||||
else if (i == _Possibilities.GetLength(0) - 1)
|
||||
{
|
||||
for (int c = 0; c < numOneRow; c++)
|
||||
for (var c = 0; c < numOneRow; c++)
|
||||
{
|
||||
_Possibilities[i, c] = (numOneRow - 1) * c + (numOneRow - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int _GetWinner()
|
||||
{
|
||||
for (int i = 0; i < _Possibilities.GetLength(0); i++)
|
||||
for (var i = 0; i < _Possibilities.GetLength(0); i++)
|
||||
{
|
||||
var check = new List<int>();
|
||||
for (int j = 0; j < _Possibilities.GetLength(1); j++)
|
||||
for (var j = 0; j < _Possibilities.GetLength(1); j++)
|
||||
{
|
||||
if (_PartyMode.GameData.Rounds[_Possibilities[i, j]].Winner > 0)
|
||||
{
|
||||
check.Add(_PartyMode.GameData.Rounds[_Possibilities[i, j]].Winner);
|
||||
}
|
||||
}
|
||||
|
||||
if (check.Count != _Possibilities.GetLength(1))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
//Check for winner
|
||||
if (check.Contains(1) && !check.Contains(2))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (check.Contains(2) && !check.Contains(1))
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,14 +17,13 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using VocaluxeLib.Menu;
|
||||
|
||||
namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
{
|
||||
// ReSharper disable UnusedMember.Global
|
||||
public class CPartyScreenTicTacToeNames : CMenuPartyNameSelection
|
||||
// ReSharper restore UnusedMember.Global
|
||||
// ReSharper restore UnusedMember.Global
|
||||
{
|
||||
// Version number for theme files. Increment it, if you've changed something on the theme files!
|
||||
protected override int _ScreenVersion
|
||||
@@ -44,14 +43,19 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
{
|
||||
base.OnShow();
|
||||
|
||||
while (_PartyMode.GameData.ProfileIDsTeam1.Count > _PartyMode.GameData.NumPlayerTeam1)
|
||||
_PartyMode.GameData.ProfileIDsTeam1.RemoveAt(_PartyMode.GameData.ProfileIDsTeam1.Count - 1);
|
||||
while (_PartyMode.GameData.ProfileIDsTeam2.Count > _PartyMode.GameData.NumPlayerTeam2)
|
||||
_PartyMode.GameData.ProfileIDsTeam2.RemoveAt(_PartyMode.GameData.ProfileIDsTeam2.Count - 1);
|
||||
while (_PartyMode.GameData.ProfileIdsTeam1.Count > _PartyMode.GameData.NumPlayerTeam1)
|
||||
{
|
||||
_PartyMode.GameData.ProfileIdsTeam1.RemoveAt(_PartyMode.GameData.ProfileIdsTeam1.Count - 1);
|
||||
}
|
||||
|
||||
while (_PartyMode.GameData.ProfileIdsTeam2.Count > _PartyMode.GameData.NumPlayerTeam2)
|
||||
{
|
||||
_PartyMode.GameData.ProfileIdsTeam2.RemoveAt(_PartyMode.GameData.ProfileIdsTeam2.Count - 1);
|
||||
}
|
||||
|
||||
SetPartyModeData(2, _PartyMode.GameData.NumPlayerTeam1 + _PartyMode.GameData.NumPlayerTeam2,
|
||||
new int[] {_PartyMode.GameData.NumPlayerTeam1, _PartyMode.GameData.NumPlayerTeam2});
|
||||
List<Guid>[] ids = new List<Guid>[] {_PartyMode.GameData.ProfileIDsTeam1, _PartyMode.GameData.ProfileIDsTeam2};
|
||||
new int[] { _PartyMode.GameData.NumPlayerTeam1, _PartyMode.GameData.NumPlayerTeam2 });
|
||||
var ids = new List<Guid>[] { _PartyMode.GameData.ProfileIdsTeam1, _PartyMode.GameData.ProfileIdsTeam2 };
|
||||
SetPartyModeProfiles(ids);
|
||||
}
|
||||
|
||||
@@ -59,14 +63,16 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
{
|
||||
if (_TeamList.Length == 2)
|
||||
{
|
||||
_PartyMode.GameData.ProfileIDsTeam1 = _TeamList[0];
|
||||
_PartyMode.GameData.ProfileIDsTeam2 = _TeamList[1];
|
||||
_PartyMode.GameData.ProfileIdsTeam1 = _TeamList[0];
|
||||
_PartyMode.GameData.ProfileIdsTeam2 = _TeamList[1];
|
||||
}
|
||||
|
||||
if (_NumPlayerTeams.Length == 2)
|
||||
{
|
||||
_PartyMode.GameData.NumPlayerTeam1 = _NumPlayerTeams[0];
|
||||
_PartyMode.GameData.NumPlayerTeam2 = _NumPlayerTeams[1];
|
||||
}
|
||||
|
||||
_PartyMode.Back();
|
||||
}
|
||||
|
||||
@@ -74,13 +80,14 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
{
|
||||
if (_TeamList.Length == 2)
|
||||
{
|
||||
_PartyMode.GameData.ProfileIDsTeam1 = _TeamList[0];
|
||||
_PartyMode.GameData.ProfileIDsTeam2 = _TeamList[1];
|
||||
_PartyMode.GameData.ProfileIdsTeam1 = _TeamList[0];
|
||||
_PartyMode.GameData.ProfileIdsTeam2 = _TeamList[1];
|
||||
}
|
||||
_PartyMode.GameData.NumPlayerTeam1 = _PartyMode.GameData.ProfileIDsTeam1.Count;
|
||||
_PartyMode.GameData.NumPlayerTeam2 = _PartyMode.GameData.ProfileIDsTeam2.Count;
|
||||
|
||||
_PartyMode.GameData.NumPlayerTeam1 = _PartyMode.GameData.ProfileIdsTeam1.Count;
|
||||
_PartyMode.GameData.NumPlayerTeam2 = _PartyMode.GameData.ProfileIdsTeam2.Count;
|
||||
|
||||
_PartyMode.Next();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@
|
||||
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using VocaluxeLib.Menu;
|
||||
|
||||
namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
@@ -40,7 +39,7 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
Source = _PartyMode.GameData.SongSource;
|
||||
Sorting = _PartyMode.GameData.Sorting;
|
||||
Category = _PartyMode.GameData.CategoryIndex;
|
||||
Playlist = _PartyMode.GameData.PlaylistID;
|
||||
Playlist = _PartyMode.GameData.PlaylistId;
|
||||
SongMode = _PartyMode.GameData.GameMode;
|
||||
NumMedleySongs = _PartyMode.GameData.NumMedleySongs;
|
||||
|
||||
@@ -76,9 +75,9 @@ namespace VocaluxeLib.PartyModes.TicTacToe
|
||||
_PartyMode.GameData.SongSource = Source;
|
||||
_PartyMode.GameData.Sorting = Sorting;
|
||||
_PartyMode.GameData.CategoryIndex = Category;
|
||||
_PartyMode.GameData.PlaylistID = Playlist;
|
||||
_PartyMode.GameData.PlaylistId = Playlist;
|
||||
_PartyMode.GameData.GameMode = SongMode;
|
||||
_PartyMode.GameData.NumMedleySongs = NumMedleySongs;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,6 +27,7 @@
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<CodeAnalysisRuleSet>..\..\CheckingRules.ruleset</CodeAnalysisRuleSet>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseWin|AnyCPU'">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@@ -40,6 +41,7 @@
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'DebugLinux|AnyCPU'">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@@ -52,6 +54,7 @@
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'ReleaseLinux|AnyCPU'">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
@@ -65,6 +68,7 @@
|
||||
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'InstallerWin|AnyCPU'">
|
||||
<OutputPath>bin</OutputPath>
|
||||
@@ -78,6 +82,7 @@
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CPartyScreenTicTacToeSongs.cs" />
|
||||
@@ -119,4 +124,4 @@ rm -f "$(SolutionDir)Output\PartyModes\$(TargetName)\Code\GlobalSuppressions.cs"
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -20,9 +20,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Vocaluxe.Base;
|
||||
using Vocaluxe.Reporting;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Log;
|
||||
using VocaluxeLib.PartyModes.Challenge;
|
||||
|
||||
namespace Tests.PartyModeChallenge
|
||||
@@ -31,20 +29,19 @@ namespace Tests.PartyModeChallenge
|
||||
public class CPartyModeChallangeTest
|
||||
{
|
||||
#region Tests
|
||||
|
||||
[Test]
|
||||
public void TestRoundBoundaries()
|
||||
{
|
||||
// ReSharper disable ObjectCreationAsStatement
|
||||
new CChallengeRounds(1, 1, 1); // Should succeed
|
||||
// ReSharper restore ObjectCreationAsStatement
|
||||
for (int inv = -1; inv <= 0; inv++)
|
||||
for (var inv = -1; inv <= 0; inv++)
|
||||
{
|
||||
int invL = inv;
|
||||
var invL = inv;
|
||||
// ReSharper disable ObjectCreationAsStatement
|
||||
Assert.Throws<ArgumentException>(() => new CChallengeRounds(invL, 1, 1));
|
||||
Assert.Throws<ArgumentException>(() => new CChallengeRounds(1, invL, 1));
|
||||
Assert.Throws<ArgumentException>(() => new CChallengeRounds(1, 1, invL));
|
||||
Assert.Throws<ArgumentException>(new Action(() => new CChallengeRounds(invL, 1, 1)));
|
||||
Assert.Throws<ArgumentException>(new Action(() => new CChallengeRounds(1, invL, 1)));
|
||||
Assert.Throws<ArgumentException>(new Action(() => new CChallengeRounds(1, 1, invL)));
|
||||
// ReSharper restore ObjectCreationAsStatement
|
||||
}
|
||||
}
|
||||
@@ -54,36 +51,38 @@ namespace Tests.PartyModeChallenge
|
||||
{
|
||||
CBase.Game = new CBGame();
|
||||
|
||||
int roundFactor = (numPlayer % numMic == 0) ? numPlayer / numMic : numPlayer;
|
||||
for (int numRounds = roundFactor; numRounds <= 100 && numRounds <= roundFactor * 5; numRounds += roundFactor)
|
||||
var roundFactor = numPlayer % numMic == 0 ? numPlayer / numMic : numPlayer;
|
||||
for (var numRounds = roundFactor; numRounds <= 100 && numRounds <= roundFactor * 5; numRounds += roundFactor)
|
||||
{
|
||||
CChallengeRounds rounds = new CChallengeRounds(numRounds, numPlayer, numMic);
|
||||
Assert.IsTrue(rounds.Count >= numRounds);
|
||||
var rounds = new CChallengeRounds(numRounds, numPlayer, numMic);
|
||||
Assert.That(rounds.Count >= numRounds, Is.True);
|
||||
_CheckRounds(rounds, numPlayer);
|
||||
Assert.That(rounds.Count, Is.GreaterThanOrEqualTo(numRounds),
|
||||
Assert.That(rounds.Count, Is.GreaterThanOrEqualTo(numRounds),
|
||||
$"Number of rounds should be >= {numRounds}, is {rounds.Count} for {numPlayer}/{numMic}");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper methods
|
||||
private static void _CheckRounds(CChallengeRounds rounds, int numPlayer)
|
||||
{
|
||||
List<int> numSongs = new List<int>(numPlayer);
|
||||
for (int i = 0; i < numPlayer; i++)
|
||||
numSongs.Add(0);
|
||||
for (int i = 0; i < rounds.Count; i++)
|
||||
var numSongs = new List<int>(numPlayer);
|
||||
for (var i = 0; i < numPlayer; i++)
|
||||
{
|
||||
foreach (int player in rounds[i].Players)
|
||||
numSongs.Add(0);
|
||||
}
|
||||
|
||||
for (var i = 0; i < rounds.Count; i++)
|
||||
{
|
||||
foreach (var player in rounds[i].Players)
|
||||
{
|
||||
Assert.IsTrue(player >= 0 && player < numPlayer);
|
||||
Assert.That(player >= 0 && player < numPlayer, Is.True);
|
||||
numSongs[player]++;
|
||||
}
|
||||
}
|
||||
Assert.IsTrue(numSongs.Min() == numSongs.Max(), "Some players have more songs than others");
|
||||
}
|
||||
|
||||
Assert.That(numSongs.Min() == numSongs.Max(), Is.True, "Some players have more songs than others");
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
@@ -30,4 +29,4 @@ using System.Runtime.InteropServices;
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
+7
-3
@@ -28,6 +28,7 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -37,6 +38,7 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x86</PlatformTarget>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
@@ -47,6 +49,7 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
@@ -56,14 +59,15 @@
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<LangVersion>9.0</LangVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="NUnit" Version="3.10.1" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.10.0" PrivateAssets="all" />
|
||||
<PackageReference Include="NUnit" Version="4.6.1" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="6.2.0" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="PartyModeChallenge\CPartyModeChallangeTest.cs" />
|
||||
@@ -117,4 +121,4 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
@@ -15,7 +15,6 @@
|
||||
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using VocaluxeLib.Log;
|
||||
@@ -28,7 +27,6 @@ namespace Tests.VocaluxeLib.Log
|
||||
private string _TestFolder;
|
||||
|
||||
#region Setup methods
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
@@ -40,18 +38,16 @@ namespace Tests.VocaluxeLib.Log
|
||||
{
|
||||
Directory.Delete(_TestFolder, true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tests
|
||||
|
||||
[Test]
|
||||
public void BenchmarkTimeTest()
|
||||
{
|
||||
const string testMessage = "BenchmarkTime Test";
|
||||
string testFileName = Path.GetRandomFileName();
|
||||
string testFileSongName = Path.GetRandomFileName();
|
||||
string testFileMarkerName = Path.GetRandomFileName();
|
||||
var testFileName = Path.GetRandomFileName();
|
||||
var testFileSongName = Path.GetRandomFileName();
|
||||
var testFileMarkerName = Path.GetRandomFileName();
|
||||
const string versionTag = "Test Version (1.2.4)";
|
||||
|
||||
// Init Log
|
||||
@@ -68,59 +64,59 @@ namespace Tests.VocaluxeLib.Log
|
||||
CLog.Close();
|
||||
|
||||
// Check log
|
||||
Assert.IsTrue(File.Exists(Path.Combine(_TestFolder, testFileName)), "Mainlog file is missing.");
|
||||
Assert.IsTrue(File.Exists(Path.Combine(_TestFolder, testFileSongName)), "Songlog file is missing.");
|
||||
Assert.That(File.Exists(Path.Combine(_TestFolder, testFileName)), Is.True, "Mainlog file is missing.");
|
||||
Assert.That(File.Exists(Path.Combine(_TestFolder, testFileSongName)), Is.True, "Songlog file is missing.");
|
||||
|
||||
string mainLogContent = File.ReadAllText(Path.Combine(_TestFolder, testFileName));
|
||||
string songLogContent = File.ReadAllText(Path.Combine(_TestFolder, testFileSongName));
|
||||
var mainLogContent = File.ReadAllText(Path.Combine(_TestFolder, testFileName));
|
||||
var songLogContent = File.ReadAllText(Path.Combine(_TestFolder, testFileSongName));
|
||||
|
||||
StringAssert.Contains($"[Information] Started \"{ testMessage }\"", mainLogContent, "Start entry wrong");
|
||||
StringAssert.Contains($"[Information] Finished \"{ testMessage }\" successfully in ", mainLogContent, "Finish entry wrong");
|
||||
StringAssert.AreEqualIgnoringCase("", songLogContent, "Benchmark should not create song log entries");
|
||||
Assert.That(mainLogContent, Contains.Substring($"[Information] Started \"{testMessage}\""), "Start entry wrong");
|
||||
Assert.That(mainLogContent, Contains.Substring($"[Information] Finished \"{testMessage}\" successfully in "), "Finish entry wrong");
|
||||
Assert.That(songLogContent, Is.Empty, "Benchmark should not create song log entries");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BenchmarkBeginTest()
|
||||
{
|
||||
const string testMessage = "BenchmarkBegin Test";
|
||||
string testFileName = Path.GetRandomFileName();
|
||||
string testFileSongName = Path.GetRandomFileName();
|
||||
string testFileMarkerName = Path.GetRandomFileName();
|
||||
var testFileName = Path.GetRandomFileName();
|
||||
var testFileSongName = Path.GetRandomFileName();
|
||||
var testFileMarkerName = Path.GetRandomFileName();
|
||||
const string versionTag = "Test Version (1.2.4)";
|
||||
|
||||
// Init Log
|
||||
CLog.Init(_TestFolder, testFileName, testFileSongName, testFileMarkerName, versionTag,
|
||||
(crash, cont, tag, log, error) => { Assert.Fail("Benchmarks should not show the reporter."); },
|
||||
ELogLevel.Verbose);
|
||||
|
||||
|
||||
using (var token = CBenchmark.Begin(testMessage))
|
||||
{
|
||||
System.Threading.Thread.Sleep(1);
|
||||
token.End();
|
||||
}
|
||||
|
||||
|
||||
// Close logfile
|
||||
CLog.Close();
|
||||
|
||||
// Check log
|
||||
Assert.IsTrue(File.Exists(Path.Combine(_TestFolder, testFileName)), "Mainlog file is missing.");
|
||||
Assert.IsTrue(File.Exists(Path.Combine(_TestFolder, testFileSongName)), "Songlog file is missing.");
|
||||
Assert.That(File.Exists(Path.Combine(_TestFolder, testFileName)), Is.True, "Mainlog file is missing.");
|
||||
Assert.That(File.Exists(Path.Combine(_TestFolder, testFileSongName)), Is.True, "Songlog file is missing.");
|
||||
|
||||
string mainLogContent = File.ReadAllText(Path.Combine(_TestFolder, testFileName));
|
||||
string songLogContent = File.ReadAllText(Path.Combine(_TestFolder, testFileSongName));
|
||||
var mainLogContent = File.ReadAllText(Path.Combine(_TestFolder, testFileName));
|
||||
var songLogContent = File.ReadAllText(Path.Combine(_TestFolder, testFileSongName));
|
||||
|
||||
StringAssert.Contains($"[Information] Started \"{ testMessage }\"", mainLogContent, "Start entry wrong");
|
||||
StringAssert.Contains($"[Information] Finished \"{ testMessage }\" successfully in ", mainLogContent, "Finish entry wrong");
|
||||
StringAssert.AreEqualIgnoringCase("", songLogContent, "Benchmark should not create song log entries");
|
||||
Assert.That(mainLogContent, Contains.Substring($"[Information] Started \"{testMessage}\""), "Start entry wrong");
|
||||
Assert.That(mainLogContent, Contains.Substring($"[Information] Finished \"{testMessage}\" successfully in "), "Finish entry wrong");
|
||||
Assert.That(songLogContent, Is.Empty, "Benchmark should not create song log entries");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BenchmarkBeginWithoutEndTest()
|
||||
{
|
||||
const string testMessage = "BenchmarkBegin Test";
|
||||
string testFileName = Path.GetRandomFileName();
|
||||
string testFileSongName = Path.GetRandomFileName();
|
||||
string testFileMarkerName = Path.GetRandomFileName();
|
||||
var testFileName = Path.GetRandomFileName();
|
||||
var testFileSongName = Path.GetRandomFileName();
|
||||
var testFileMarkerName = Path.GetRandomFileName();
|
||||
const string versionTag = "Test Version (1.2.4)";
|
||||
|
||||
// Init Log
|
||||
@@ -137,28 +133,25 @@ namespace Tests.VocaluxeLib.Log
|
||||
CLog.Close();
|
||||
|
||||
// Check log
|
||||
Assert.IsTrue(File.Exists(Path.Combine(_TestFolder, testFileName)), "Mainlog file is missing.");
|
||||
Assert.IsTrue(File.Exists(Path.Combine(_TestFolder, testFileSongName)), "Songlog file is missing.");
|
||||
Assert.That(File.Exists(Path.Combine(_TestFolder, testFileName)), Is.True, "Mainlog file is missing.");
|
||||
Assert.That(File.Exists(Path.Combine(_TestFolder, testFileSongName)), Is.True, "Songlog file is missing.");
|
||||
|
||||
string mainLogContent = File.ReadAllText(Path.Combine(_TestFolder, testFileName));
|
||||
string songLogContent = File.ReadAllText(Path.Combine(_TestFolder, testFileSongName));
|
||||
var mainLogContent = File.ReadAllText(Path.Combine(_TestFolder, testFileName));
|
||||
var songLogContent = File.ReadAllText(Path.Combine(_TestFolder, testFileSongName));
|
||||
|
||||
StringAssert.Contains($"[Information] Started \"{ testMessage }\"", mainLogContent, "Start entry wrong");
|
||||
StringAssert.Contains($"[Information] Failed \"{ testMessage }\" in ", mainLogContent, "Finish entry wrong");
|
||||
StringAssert.AreEqualIgnoringCase("", songLogContent, "Benchmark should not create song log entries");
|
||||
Assert.That(mainLogContent, Contains.Substring($"[Information] Started \"{testMessage}\""), "Start entry wrong");
|
||||
Assert.That(mainLogContent, Contains.Substring($"[Information] Failed \"{testMessage}\" in "), "Finish entry wrong");
|
||||
Assert.That(songLogContent, Is.Empty, "Benchmark should not create song log entries");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper methods
|
||||
|
||||
private string _GetTemporaryDirectory()
|
||||
{
|
||||
string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
||||
var tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
||||
Directory.CreateDirectory(tempDirectory);
|
||||
return tempDirectory;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
+566
-579
File diff suppressed because it is too large.
Load diff
@@ -92,16 +92,16 @@ namespace Tests.VocaluxeLib.Log
|
||||
(crash, cont, tag, log, error) =>
|
||||
{
|
||||
messageShown = true;
|
||||
Assert.IsTrue(show);
|
||||
Assert.IsFalse(crash);
|
||||
Assert.IsTrue(cont);
|
||||
Assert.AreEqual(versionTag, tag);
|
||||
Assert.That(show, Is.True);
|
||||
Assert.That(crash, Is.False);
|
||||
Assert.That(cont, Is.True);
|
||||
Assert.That(tag, Is.EqualTo(versionTag));
|
||||
|
||||
StringAssert.Contains("[Information] Starting to log", log, "Main log start entry wrong");
|
||||
StringAssert.Contains("Version = " + versionTag, log, "Main log version tag entry wrong");
|
||||
StringAssert.Contains("[<#= LogLevel #>] " + <#= WithData?"_TestMessageWithResolvedData":"_TestMessage" #>, log, "Main log entry wrong");
|
||||
Assert.That(log, Contains.Substring("[Information] Starting to log"), "Main log start entry wrong");
|
||||
Assert.That(log, Contains.Substring("Version = " + versionTag), "Main log version tag entry wrong");
|
||||
Assert.That(log, Contains.Substring("[<#= LogLevel #>] " + <#= WithData?"_TestMessageWithResolvedData":"_TestMessage" #>), "Main log entry wrong");
|
||||
|
||||
StringAssert.Contains(<#= WithData?"_TestMessageWithResolvedData":"_TestMessage" #>, error, "Error message wrong");
|
||||
Assert.That(error, Contains.Substring(<#= WithData?"_TestMessageWithResolvedData":"_TestMessage" #>), "Error message wrong");
|
||||
},
|
||||
ELogLevel.Verbose);
|
||||
|
||||
@@ -115,27 +115,27 @@ namespace Tests.VocaluxeLib.Log
|
||||
CLog.Close();
|
||||
|
||||
// Check log
|
||||
Assert.IsTrue(File.Exists(Path.Combine(_TestFolder, testFileName)), "Mainlog file is missing.");
|
||||
Assert.IsTrue(File.Exists(Path.Combine(_TestFolder, testFileSongName)), "Songlog file is missing.");
|
||||
Assert.That(File.Exists(Path.Combine(_TestFolder, testFileName)), Is.True, "Mainlog file is missing.");
|
||||
Assert.That(File.Exists(Path.Combine(_TestFolder, testFileSongName)), Is.True, "Songlog file is missing.");
|
||||
|
||||
string mainLogContent = File.ReadAllText(Path.Combine(_TestFolder, testFileName));
|
||||
string songLogContent = File.ReadAllText(Path.Combine(_TestFolder, testFileSongName));
|
||||
|
||||
StringAssert.Contains("[Information] Starting to log", mainLogContent, "Main log start entry wrong");
|
||||
StringAssert.Contains("Version = " + versionTag, mainLogContent, "Main log version tag entry wrong");
|
||||
StringAssert.Contains("[<#= LogLevel #>] " +<#= WithData?"_TestMessageWithResolvedData":"_TestMessage" #>, mainLogContent, "Main log entry wrong");
|
||||
Assert.That(mainLogContent, Contains.Substring("[Information] Starting to log"), "Main log start entry wrong");
|
||||
Assert.That(mainLogContent, Contains.Substring("Version = " + versionTag), "Main log version tag entry wrong");
|
||||
Assert.That(mainLogContent, Contains.Substring("[<#= LogLevel #>] " +<#= WithData?"_TestMessageWithResolvedData":"_TestMessage" #>), "Main log entry wrong");
|
||||
<# if(WithException) { #>
|
||||
StringAssert.Contains(_TestExceptionMessage, mainLogContent, "Exception is missing");
|
||||
Assert.That(mainLogContent, Contains.Substring(_TestExceptionMessage), "Exception is missing");
|
||||
<# } #>
|
||||
<# if(WithData) { #>
|
||||
StringAssert.Contains(_SecondParam, mainLogContent, "Second data field is missing");
|
||||
Assert.That(mainLogContent, Contains.Substring(_SecondParam), "Second data field is missing");
|
||||
<# } #>
|
||||
<# if(LogLevel!="Fatal") { #>
|
||||
StringAssert.Contains(<#= WithData?"_TestMessageWithResolvedData":"_TestMessage" #>, songLogContent, "Song log entry wrong");
|
||||
Assert.That(songLogContent, Contains.Substring(<#= WithData?"_TestMessageWithResolvedData":"_TestMessage" #>), "Song log entry wrong");
|
||||
<# } #>
|
||||
if(!show)
|
||||
{
|
||||
Assert.IsFalse(messageShown);
|
||||
Assert.That(messageShown, Is.False);
|
||||
}
|
||||
}
|
||||
<# } #>
|
||||
|
||||
@@ -29,7 +29,6 @@ namespace Tests.VocaluxeLib.Log.Rolling
|
||||
private string _TestFolder;
|
||||
|
||||
#region Setup methods
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
@@ -41,20 +40,18 @@ namespace Tests.VocaluxeLib.Log.Rolling
|
||||
{
|
||||
Directory.Delete(_TestFolder, true);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tests
|
||||
|
||||
[Test]
|
||||
public void RollFilesTest([Range(0,4)] int numFilesExisting, [Range(0, 3)] int numOldFilesToKeep)
|
||||
public void RollFilesTest([Range(0, 4)] int numFilesExisting, [Range(0, 3)] int numOldFilesToKeep)
|
||||
{
|
||||
// Create existing files
|
||||
if (numFilesExisting > 0)
|
||||
{
|
||||
CreateFile(_TestFolder, _TestFileName, 0);
|
||||
}
|
||||
|
||||
|
||||
for (var i = 1; i < numFilesExisting; i++)
|
||||
{
|
||||
CreateFile(_TestFolder, GetFileName(i), i);
|
||||
@@ -63,33 +60,31 @@ namespace Tests.VocaluxeLib.Log.Rolling
|
||||
|
||||
// Roll the files
|
||||
CLogFileRoller.RollLogs(Path.Combine(_TestFolder, _TestFileName), numOldFilesToKeep);
|
||||
|
||||
|
||||
|
||||
// Check main file
|
||||
Assert.IsFalse(File.Exists(Path.Combine(_TestFolder, _TestFileName)), "Main file was not deleted.");
|
||||
Assert.That(File.Exists(Path.Combine(_TestFolder, _TestFileName)), Is.False, "Main file was not deleted.");
|
||||
//Check other files
|
||||
for (int i = 1; i <= Math.Max(numOldFilesToKeep, numFilesExisting); i++)
|
||||
for (var i = 1; i <= Math.Max(numOldFilesToKeep, numFilesExisting); i++)
|
||||
{
|
||||
var fileToCheck = Path.Combine(_TestFolder, GetFileName(i));
|
||||
if (i <= Math.Min(numFilesExisting,numOldFilesToKeep))
|
||||
if (i <= Math.Min(numFilesExisting, numOldFilesToKeep))
|
||||
{
|
||||
Assert.IsTrue(File.Exists(fileToCheck), $"File {GetFileName(i)} is missing.");
|
||||
Assert.AreEqual((i - 1).ToString(), File.ReadAllText(fileToCheck), "Rotation is wrong");
|
||||
Assert.That(File.Exists(fileToCheck), Is.True, $"File {GetFileName(i)} is missing.");
|
||||
Assert.That(File.ReadAllText(fileToCheck), Is.EqualTo((i - 1).ToString()), "Rotation is wrong");
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.IsFalse(File.Exists(fileToCheck));
|
||||
Assert.That(File.Exists(fileToCheck), Is.False);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper methods
|
||||
|
||||
private string _GetTemporaryDirectory()
|
||||
{
|
||||
string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
||||
var tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
|
||||
Directory.CreateDirectory(tempDirectory);
|
||||
return tempDirectory;
|
||||
}
|
||||
@@ -103,8 +98,6 @@ namespace Tests.VocaluxeLib.Log.Rolling
|
||||
{
|
||||
return _TestFileName.Replace(".", $"_{i}.");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,72 +27,82 @@ namespace Tests.VocaluxeLib.Utils.Combinatorics
|
||||
public class CCombinationsTest
|
||||
{
|
||||
#region Tests
|
||||
|
||||
[Test]
|
||||
public void TestCount()
|
||||
{
|
||||
Assert.AreEqual(4, CCombinations<int>.Count(4, 3));
|
||||
Assert.AreEqual(6, CCombinations<int>.Count(4, 2));
|
||||
Assert.AreEqual(66, CCombinations<int>.Count(12, 2));
|
||||
Assert.That(CCombinations<int>.Count(4, 3), Is.EqualTo(4));
|
||||
Assert.That(CCombinations<int>.Count(4, 2), Is.EqualTo(6));
|
||||
Assert.That(CCombinations<int>.Count(12, 2), Is.EqualTo(66));
|
||||
// Corner cases
|
||||
for (int i = 1; i < 12; i++)
|
||||
for (var i = 1; i < 12; i++)
|
||||
{
|
||||
Assert.AreEqual(1, CCombinations<int>.Count(i, 0));
|
||||
Assert.AreEqual(1, CCombinations<int>.Count(i, i));
|
||||
Assert.AreEqual(0, CCombinations<int>.Count(i, i + 1));
|
||||
Assert.That(CCombinations<int>.Count(i, 0), Is.EqualTo(1));
|
||||
Assert.That(CCombinations<int>.Count(i, i), Is.EqualTo(1));
|
||||
Assert.That(CCombinations<int>.Count(i, i + 1), Is.EqualTo(0));
|
||||
}
|
||||
|
||||
// Check identity (n k) = (n n-k)
|
||||
for (int i = 0; i <= 12; i++)
|
||||
Assert.AreEqual(CCombinations<int>.Count(12, i), CCombinations<int>.Count(12, 12 - i));
|
||||
Assert.That(() => CCombinations<int>.Count(-1, -1), Throws.TypeOf<ArgumentException>());
|
||||
Assert.That(() => CCombinations<int>.Count(-1, 1), Throws.TypeOf<ArgumentException>());
|
||||
Assert.That(() => CCombinations<int>.Count(1, -1), Throws.TypeOf<ArgumentException>());
|
||||
for (var i = 0; i <= 12; i++)
|
||||
{
|
||||
Assert.That(CCombinations<int>.Count(12, 12 - i), Is.EqualTo(CCombinations<int>.Count(12, i)));
|
||||
}
|
||||
|
||||
Assert.Throws<ArgumentException>(new Action(() => CCombinations<int>.Count(-1, -1)));
|
||||
Assert.Throws<ArgumentException>(new Action(() => CCombinations<int>.Count(-1, 1)));
|
||||
Assert.Throws<ArgumentException>(new Action(() => CCombinations<int>.Count(1, -1)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestResults([Range(0, 8, 1)] int n)
|
||||
{
|
||||
Random rand = new Random();
|
||||
|
||||
for (int k = 0; k <= n; k++)
|
||||
var rand = new Random();
|
||||
|
||||
for (var k = 0; k <= n; k++)
|
||||
{
|
||||
List<int> collection = new List<int>(n);
|
||||
int r = rand.Next(1000);
|
||||
for (int i = 0; i < n; i++)
|
||||
var collection = new List<int>(n);
|
||||
var r = rand.Next(1000);
|
||||
for (var i = 0; i < n; i++)
|
||||
{
|
||||
collection.Add(i + r);
|
||||
CCombinations<int> combs = new CCombinations<int>(collection, k);
|
||||
Assert.AreEqual(CCombinations<int>.Count(n, k), combs.Count());
|
||||
}
|
||||
|
||||
var combs = new CCombinations<int>(collection, k);
|
||||
Assert.That(combs.Count(), Is.EqualTo(CCombinations<int>.Count(n, k)));
|
||||
_CheckResults(combs, collection);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper methods
|
||||
|
||||
// ReSharper disable UnusedParameter.Local
|
||||
private static void _CheckResults<T>(CCombinations<T> combs, List<T> input)
|
||||
// ReSharper restore UnusedParameter.Local
|
||||
// ReSharper restore UnusedParameter.Local
|
||||
{
|
||||
List<List<T>> results = new List<List<T>>();
|
||||
foreach (List<T> comb in combs)
|
||||
var results = new List<List<T>>();
|
||||
foreach (var comb in combs)
|
||||
{
|
||||
foreach (List<T> other in results)
|
||||
Assert.IsFalse(other.SequenceEqual(comb), "Result must be unique");
|
||||
for (int i = 0; i < comb.Count - 1; i++)
|
||||
foreach (var other in results)
|
||||
{
|
||||
Assert.IsTrue(comb.IndexOf(comb[i], i + 1) < 0, "Repetition not allowed");
|
||||
Assert.IsTrue(input.Contains(comb[i]), "Output must be in input sequence");
|
||||
Assert.That(other.SequenceEqual(comb), Is.False, "Result must be unique");
|
||||
}
|
||||
|
||||
for (var i = 0; i < comb.Count - 1; i++)
|
||||
{
|
||||
Assert.That(comb.IndexOf(comb[i], i + 1), Is.LessThan(0),"Repetition not allowed");
|
||||
Assert.That(input.Contains(comb[i]), Is.True, "Output must be in input sequence");
|
||||
}
|
||||
|
||||
results.Add(comb);
|
||||
}
|
||||
Assert.AreEqual(combs.Count(), results.Count);
|
||||
List<List<T>> results2 = combs.GetAll();
|
||||
Assert.AreEqual(results.Count, results2.Count);
|
||||
for (int i = 0; i < results2.Count; i++)
|
||||
Assert.IsTrue(results[i].SequenceEqual(results2[i]));
|
||||
}
|
||||
|
||||
Assert.That(results, Has.Count.EqualTo(combs.Count()));
|
||||
var results2 = combs.GetAll();
|
||||
Assert.That(results, Has.Count.EqualTo(results2.Count));
|
||||
for (var i = 0; i < results2.Count; i++)
|
||||
{
|
||||
Assert.That(results[i], Is.EquivalentTo(results2[i]));
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,9 +21,9 @@ using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Xml.Serialization;
|
||||
using NUnit.Framework;
|
||||
using Vocaluxe.Base;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Xml;
|
||||
using Vocaluxe.Base;
|
||||
|
||||
namespace Tests.VocaluxeLib.XML
|
||||
{
|
||||
@@ -34,7 +34,6 @@ namespace Tests.VocaluxeLib.XML
|
||||
private const string _Empty = _Head + @"<root />";
|
||||
|
||||
#region Tests
|
||||
|
||||
[Test]
|
||||
public void TestBasic()
|
||||
{
|
||||
@@ -51,67 +50,76 @@ namespace Tests.VocaluxeLib.XML
|
||||
<S>2</S>
|
||||
</root>";
|
||||
var xml = new CXmlDeserializer();
|
||||
SBasic foo = xml.DeserializeString<SBasic>(s);
|
||||
Assert.AreEqual(1, foo.I);
|
||||
Assert.AreEqual("2", foo.S);
|
||||
Assert.AreEqual(3, foo.F, 0.0001);
|
||||
Assert.AreEqual(4, foo.D, 0.0001);
|
||||
var foo = xml.DeserializeString<SBasic>(s);
|
||||
Assert.That(foo.I, Is.EqualTo(1));
|
||||
Assert.That(foo.S, Is.EqualTo("2"));
|
||||
Assert.That(foo.F, Is.EqualTo(3).Within(0.0001));
|
||||
Assert.That(foo.D, Is.EqualTo(4).Within(0.0001));
|
||||
foo = xml.DeserializeString<SBasic>(sUnordered);
|
||||
Assert.AreEqual(1, foo.I);
|
||||
Assert.AreEqual("2", foo.S);
|
||||
Assert.AreEqual(3, foo.F, 0.0001);
|
||||
Assert.AreEqual(4, foo.D, 0.0001);
|
||||
Assert.That(foo.I, Is.EqualTo(1));
|
||||
Assert.That(foo.S, Is.EqualTo("2"));
|
||||
Assert.That(foo.F, Is.EqualTo(3).Within(0.0001));
|
||||
Assert.That(foo.D, Is.EqualTo(4).Within(0.0001));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMissingXmlElement()
|
||||
{
|
||||
string[] s = new string[] { @"<root>
|
||||
<S>2</S>
|
||||
<F>3</F>
|
||||
<D>4</D>
|
||||
</root>", @"<root>
|
||||
<I>1</I>
|
||||
<F>3</F>
|
||||
<D>4</D>
|
||||
</root>", @"<root>
|
||||
<I>1</I>
|
||||
<S>2</S>
|
||||
<F>3</F>
|
||||
</root>" };
|
||||
foreach (string s1 in s)
|
||||
var s = new string[]
|
||||
{
|
||||
string sTmp = s1;
|
||||
_AssertFail<SBasic, CXmlException>(sTmp);
|
||||
@"<root>
|
||||
<S>2</S>
|
||||
<F>3</F>
|
||||
<D>4</D>
|
||||
</root>",
|
||||
@"<root>
|
||||
<I>1</I>
|
||||
<F>3</F>
|
||||
<D>4</D>
|
||||
</root>",
|
||||
@"<root>
|
||||
<I>1</I>
|
||||
<S>2</S>
|
||||
<F>3</F>
|
||||
</root>"
|
||||
};
|
||||
foreach (var s1 in s)
|
||||
{
|
||||
_AssertXmlSerializeFailWithMissingElement<SBasic, CXmlMissingElementException>(s1);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestMissingStructElement()
|
||||
{
|
||||
string[] s = new string[] { @"<root>
|
||||
<Foo>1</Foo>
|
||||
<I>1</I>
|
||||
<S>2</S>
|
||||
<F>3</F>
|
||||
<D>4</D>
|
||||
</root>", @"<root>
|
||||
<I>1</I>
|
||||
<Foo>1</Foo>
|
||||
<S>2</S>
|
||||
<F>3</F>
|
||||
<D>4</D>
|
||||
</root>", @"<root>
|
||||
<I>1</I>
|
||||
<S>2</S>
|
||||
<F>3</F>
|
||||
<D>4</D>
|
||||
<Foo>1</Foo>
|
||||
</root>" };
|
||||
foreach (string s1 in s)
|
||||
var s = new string[]
|
||||
{
|
||||
string sTmp = s1;
|
||||
_AssertFail<SBasic, CXmlException>(sTmp);
|
||||
@"<root>
|
||||
<Foo>1</Foo>
|
||||
<I>1</I>
|
||||
<S>2</S>
|
||||
<F>3</F>
|
||||
<D>4</D>
|
||||
</root>",
|
||||
@"<root>
|
||||
<I>1</I>
|
||||
<Foo>1</Foo>
|
||||
<S>2</S>
|
||||
<F>3</F>
|
||||
<D>4</D>
|
||||
</root>",
|
||||
@"<root>
|
||||
<I>1</I>
|
||||
<S>2</S>
|
||||
<F>3</F>
|
||||
<D>4</D>
|
||||
<Foo>1</Foo>
|
||||
</root>"
|
||||
};
|
||||
foreach (var s1 in s)
|
||||
{
|
||||
var sTmp = s1;
|
||||
_AssertXmlSerializeFailWithMissingElement<SBasic, CXmlException>(sTmp);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +135,7 @@ namespace Tests.VocaluxeLib.XML
|
||||
_AssertSerDeserMatch<SBasic>(s);
|
||||
}
|
||||
|
||||
private readonly string[] _XmlList = new string[]
|
||||
private readonly string[] _XmlList =
|
||||
{
|
||||
_Head + @"<root>
|
||||
<Ints>
|
||||
@@ -153,22 +161,22 @@ namespace Tests.VocaluxeLib.XML
|
||||
{
|
||||
var xml = new CXmlDeserializer();
|
||||
var ser = new CXmlSerializer();
|
||||
SList foo = xml.DeserializeString<SList>(_XmlList[0]);
|
||||
Assert.AreEqual(foo.Ints.Count, 2, "Deserialization failed");
|
||||
Assert.AreEqual(foo.Ints[0].I, 1, "Deserialization failed");
|
||||
Assert.AreEqual(foo.Ints[1].I, 1, "Deserialization failed");
|
||||
string res = ser.Serialize(foo);
|
||||
Assert.AreEqual(_XmlList[0], res, "Serialization failed");
|
||||
var foo = xml.DeserializeString<SList>(_XmlList[0]);
|
||||
Assert.That(foo.Ints, Has.Count.EqualTo(2), "Deserialization failed");
|
||||
Assert.That(foo.Ints[0].I, Is.EqualTo(1), "Deserialization failed");
|
||||
Assert.That(foo.Ints[1].I, Is.EqualTo(1), "Deserialization failed");
|
||||
var res = ser.Serialize(foo);
|
||||
Assert.That(res, Is.EqualTo(_XmlList[0]), "Serialization failed");
|
||||
foo = xml.DeserializeString<SList>(_XmlList[1]);
|
||||
Assert.AreEqual(foo.Ints.Count, 0, "Deserialization2 failed");
|
||||
Assert.That(foo.Ints, Is.Empty, "Deserialization2 failed");
|
||||
res = ser.Serialize(foo);
|
||||
Assert.AreEqual(_XmlList[2], res, "Serialization2 failed");
|
||||
Assert.That(_XmlList[2], Is.EqualTo(res), "Serialization2 failed");
|
||||
foo = xml.DeserializeString<SList>(_XmlList[2]);
|
||||
Assert.AreEqual(foo.Ints.Count, 0, "Deserialization2 failed");
|
||||
Assert.That(foo.Ints, Is.Empty, "Deserialization2 failed");
|
||||
_AssertSerDeserMatch<SList>(_XmlList[2]);
|
||||
res = ser.Serialize(foo);
|
||||
Assert.AreEqual(_XmlList[2], res, "Serialization2 failed");
|
||||
_AssertFail<SList, CXmlException>(_Empty);
|
||||
Assert.That(_XmlList[2], Is.EqualTo(res), "Serialization2 failed");
|
||||
_AssertXmlSerializeFailWithMissingElement<SList, CXmlMissingElementException>(_Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -176,21 +184,21 @@ namespace Tests.VocaluxeLib.XML
|
||||
{
|
||||
var xml = new CXmlDeserializer();
|
||||
var ser = new CXmlSerializer();
|
||||
SArray foo = xml.DeserializeString<SArray>(_XmlList[0]);
|
||||
Assert.AreEqual(foo.Ints.Length, 2, "Deserialization failed");
|
||||
Assert.AreEqual(foo.Ints[0].I, 1, "Deserialization failed");
|
||||
Assert.AreEqual(foo.Ints[1].I, 1, "Deserialization failed");
|
||||
string res = ser.Serialize(foo);
|
||||
Assert.AreEqual(_XmlList[0], res, "Serialization failed");
|
||||
var foo = xml.DeserializeString<SArray>(_XmlList[0]);
|
||||
Assert.That(foo.Ints, Has.Length.EqualTo(2), "Deserialization failed");
|
||||
Assert.That(foo.Ints[0].I, Is.EqualTo(1), "Deserialization failed");
|
||||
Assert.That(foo.Ints[1].I, Is.EqualTo(1), "Deserialization failed");
|
||||
var res = ser.Serialize(foo);
|
||||
Assert.That(res, Is.EqualTo(_XmlList[0]), "Serialization failed");
|
||||
foo = xml.DeserializeString<SArray>(_XmlList[1]);
|
||||
Assert.AreEqual(foo.Ints.Length, 0, "Deserialization2 failed");
|
||||
Assert.That(foo.Ints, Is.Empty, "Deserialization2 failed");
|
||||
res = ser.Serialize(foo);
|
||||
Assert.AreEqual(_XmlList[2], res, "Serialization2 failed");
|
||||
Assert.That(_XmlList[2], Is.EqualTo(res), "Serialization2 failed");
|
||||
foo = xml.DeserializeString<SArray>(_XmlList[2]);
|
||||
Assert.AreEqual(foo.Ints.Length, 0, "Deserialization2 failed");
|
||||
Assert.That(foo.Ints, Is.Empty, "Deserialization2 failed");
|
||||
res = ser.Serialize(foo);
|
||||
Assert.AreEqual(_XmlList[2], res, "Serialization2 failed");
|
||||
_AssertFail<SArray, CXmlException>(_Empty);
|
||||
Assert.That(_XmlList[2], Is.EqualTo(res), "Serialization2 failed");
|
||||
_AssertXmlSerializeFailWithMissingElement<SArray, CXmlMissingElementException>(_Empty);
|
||||
}
|
||||
|
||||
private const string _XmlListEmb = _Head + @"<root>
|
||||
@@ -225,25 +233,25 @@ namespace Tests.VocaluxeLib.XML
|
||||
{
|
||||
var xml = new CXmlDeserializer();
|
||||
var ser = new CXmlSerializer();
|
||||
SListEmb foo = xml.DeserializeString<SListEmb>(_XmlListEmb);
|
||||
Assert.AreEqual(foo.Ints.Count, 1, "Deserialization failed");
|
||||
Assert.AreEqual(foo.Ints[0].I, 1, "Deserialization failed");
|
||||
string res = ser.Serialize(foo);
|
||||
Assert.AreEqual(_XmlListEmb, res, "Serialization failed");
|
||||
var foo = xml.DeserializeString<SListEmb>(_XmlListEmb);
|
||||
Assert.That(foo.Ints, Has.Count.EqualTo(1), "Deserialization failed");
|
||||
Assert.That(foo.Ints[0].I, Is.EqualTo(1), "Deserialization failed");
|
||||
var res = ser.Serialize(foo);
|
||||
Assert.That(res, Is.EqualTo(_XmlListEmb), "Serialization failed");
|
||||
foo = xml.DeserializeString<SListEmb>(_XmlListEmb2);
|
||||
Assert.AreEqual(foo.Ints.Count, 2, "Deserialization failed");
|
||||
Assert.AreEqual(foo.Ints[1].I, 2, "Deserialization failed");
|
||||
Assert.That(foo.Ints, Has.Count.EqualTo(2), "Deserialization failed");
|
||||
Assert.That(foo.Ints[1].I, Is.EqualTo(2) , "Deserialization failed");
|
||||
res = ser.Serialize(foo);
|
||||
Assert.AreEqual(_XmlListEmb2, res, "Serialization failed");
|
||||
Assert.That(res, Is.EqualTo(_XmlListEmb2), "Serialization failed");
|
||||
foo = xml.DeserializeString<SListEmb>(_XmlListEmb3);
|
||||
Assert.AreEqual(foo.Ints.Count, 0, "Deserialization failed");
|
||||
Assert.That(foo.Ints, Is.Empty, "Deserialization failed");
|
||||
res = ser.Serialize(foo);
|
||||
Assert.AreEqual(_XmlListEmb3, res, "Serialization failed");
|
||||
Assert.That(res, Is.EqualTo(_XmlListEmb3), "Serialization failed");
|
||||
ser = new CXmlSerializer(true);
|
||||
foo.Ints.Clear();
|
||||
res = ser.Serialize(foo);
|
||||
Assert.AreEqual(_XmlListEmb4, res, "Serialization failed");
|
||||
_AssertFail<SListEmb, CXmlException>(_Empty);
|
||||
Assert.That(res, Is.EqualTo(_XmlListEmb4), "Serialization failed");
|
||||
_AssertXmlSerializeFailWithMissingElement<SListEmb, CXmlMissingElementException>(_Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -251,25 +259,25 @@ namespace Tests.VocaluxeLib.XML
|
||||
{
|
||||
var xml = new CXmlDeserializer();
|
||||
var ser = new CXmlSerializer();
|
||||
SArrayEmb foo = xml.DeserializeString<SArrayEmb>(_XmlListEmb);
|
||||
Assert.AreEqual(foo.Ints.Length, 1, "Deserialization failed");
|
||||
Assert.AreEqual(foo.Ints[0].I, 1, "Deserialization failed");
|
||||
string res = ser.Serialize(foo);
|
||||
Assert.AreEqual(_XmlListEmb, res, "Serialization failed");
|
||||
var foo = xml.DeserializeString<SArrayEmb>(_XmlListEmb);
|
||||
Assert.That(foo.Ints, Has.Length.EqualTo(1), "Deserialization failed");
|
||||
Assert.That(foo.Ints[0].I, Is.EqualTo(1), "Deserialization failed");
|
||||
var res = ser.Serialize(foo);
|
||||
Assert.That(res, Is.EqualTo(_XmlListEmb), "Serialization failed");
|
||||
foo = xml.DeserializeString<SArrayEmb>(_XmlListEmb2);
|
||||
Assert.AreEqual(foo.Ints.Length, 2, "Deserialization failed");
|
||||
Assert.AreEqual(foo.Ints[1].I, 2, "Deserialization failed");
|
||||
Assert.That(foo.Ints, Has.Length.EqualTo(2), "Deserialization failed");
|
||||
Assert.That(foo.Ints[1].I, Is.EqualTo(2), "Deserialization failed");
|
||||
res = ser.Serialize(foo);
|
||||
Assert.AreEqual(_XmlListEmb2, res, "Serialization failed");
|
||||
Assert.That(res, Is.EqualTo(_XmlListEmb2), "Serialization failed");
|
||||
foo = xml.DeserializeString<SArrayEmb>(_XmlListEmb3);
|
||||
Assert.AreEqual(foo.Ints.Length, 0, "Deserialization failed");
|
||||
Assert.That(foo.Ints, Is.Empty, "Deserialization failed");
|
||||
res = ser.Serialize(foo);
|
||||
Assert.AreEqual(_XmlListEmb3, res, "Serialization failed");
|
||||
Assert.That(res, Is.EqualTo(_XmlListEmb3), "Serialization failed");
|
||||
ser = new CXmlSerializer(true);
|
||||
foo.Ints = new SEntry[0];
|
||||
foo.Ints = Array.Empty<SEntry>();
|
||||
res = ser.Serialize(foo);
|
||||
Assert.AreEqual(_XmlListEmb4, res, "Serialization failed");
|
||||
_AssertFail<SArrayEmb, CXmlException>(_Empty);
|
||||
Assert.That(res, Is.EqualTo(_XmlListEmb4), "Serialization failed");
|
||||
_AssertXmlSerializeFailWithMissingElement<SArrayEmb, CXmlMissingElementException>(_Empty);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -279,9 +287,9 @@ namespace Tests.VocaluxeLib.XML
|
||||
<Public>2</Public>
|
||||
<Auto>3</Auto>
|
||||
</root>";
|
||||
SProperty foo = _AssertSerDeserMatch<SProperty>(xmlString);
|
||||
Assert.AreEqual(3, foo.Private);
|
||||
Assert.AreEqual(3, foo.Auto);
|
||||
var foo = _AssertSerDeserMatch<SProperty>(xmlString);
|
||||
Assert.That(foo.Private, Is.EqualTo(3));
|
||||
Assert.That(foo.Auto, Is.EqualTo(3));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -305,7 +313,7 @@ namespace Tests.VocaluxeLib.XML
|
||||
public void TestIgnore()
|
||||
{
|
||||
_AssertSerDeserMatch<SIgnore>(_XmlIgnore);
|
||||
_AssertFail<SIgnore, CXmlException>(_XmlIgnore2);
|
||||
_AssertXmlSerializeFailWithMissingElement<SIgnore, CXmlException>(_XmlIgnore2);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -314,15 +322,15 @@ namespace Tests.VocaluxeLib.XML
|
||||
var foo = new SIgnore { I = 1 };
|
||||
var xml = new CXmlDeserializer();
|
||||
var ser = new CXmlSerializer();
|
||||
SIgnore bar = xml.DeserializeString(_XmlIgnore, foo);
|
||||
Assert.AreEqual(1, bar.I);
|
||||
Assert.AreEqual(_XmlIgnore, ser.Serialize(bar));
|
||||
var bar = xml.DeserializeString(_XmlIgnore, foo);
|
||||
Assert.That(bar.I, Is.EqualTo(1));
|
||||
Assert.That(ser.Serialize(bar), Is.EqualTo(_XmlIgnore));
|
||||
|
||||
var foo2 = new CIgnore { I = 1 };
|
||||
CIgnore bar2 = xml.DeserializeString(_XmlIgnore, foo2);
|
||||
Assert.AreEqual(1, bar2.I);
|
||||
Assert.AreEqual(foo2.J, bar2.J, "Original classes should be modified by the deserialization");
|
||||
Assert.AreEqual(_XmlIgnore, ser.Serialize(bar2));
|
||||
var bar2 = xml.DeserializeString(_XmlIgnore, foo2);
|
||||
Assert.That(bar2.I, Is.EqualTo(1));
|
||||
Assert.That(bar2.J, Is.EqualTo(foo2.J), "Original classes should be modified by the deserialization");
|
||||
Assert.That(ser.Serialize(bar2), Is.EqualTo(_XmlIgnore));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -359,16 +367,16 @@ namespace Tests.VocaluxeLib.XML
|
||||
</root>";
|
||||
_AssertSerDeserMatch<SDefault>(s);
|
||||
var xml = new CXmlDeserializer(new CXmlErrorHandler(exception => { }));
|
||||
SDefault foo = xml.DeserializeString<SDefault>(@"<root />");
|
||||
Assert.AreEqual(foo.I, 1337);
|
||||
Assert.AreEqual(foo.F, null);
|
||||
Assert.AreEqual(foo.S, "Foo");
|
||||
Assert.AreEqual(foo.D, 666);
|
||||
Assert.AreEqual(foo.Sub.I, 111);
|
||||
string newXml = new CXmlSerializer().Serialize(foo);
|
||||
Assert.AreEqual(_Head + @"<root>
|
||||
var foo = xml.DeserializeString<SDefault>(@"<root />");
|
||||
Assert.That(foo.I, Is.EqualTo(1337));
|
||||
Assert.That(foo.F, Is.Null);
|
||||
Assert.That(foo.S, Is.EqualTo("Foo"));
|
||||
Assert.That(foo.D, Is.EqualTo(666));
|
||||
Assert.That(foo.Sub.I, Is.EqualTo(111));
|
||||
var newXml = new CXmlSerializer().Serialize(foo);
|
||||
Assert.That(newXml, Is.EqualTo(_Head + @"<root>
|
||||
<Sub />
|
||||
</root>", newXml);
|
||||
</root>"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -382,9 +390,9 @@ namespace Tests.VocaluxeLib.XML
|
||||
</root>";
|
||||
_AssertSerDeserMatch<SUnescaping>(s);
|
||||
var xml = new CXmlDeserializer(new CXmlErrorHandler(exception => { }));
|
||||
SUnescaping foo = xml.DeserializeString<SUnescaping>(@"<root />");
|
||||
Assert.AreEqual(foo.S, "Foo\'Bar");
|
||||
Assert.AreEqual(foo.Sub.S, "Foo\'Bar");
|
||||
var foo = xml.DeserializeString<SUnescaping>(@"<root />");
|
||||
Assert.That(foo.S, Is.EqualTo("Foo\'Bar"));
|
||||
Assert.That(foo.Sub.S, Is.EqualTo("Foo\'Bar"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -398,37 +406,38 @@ namespace Tests.VocaluxeLib.XML
|
||||
</root>";
|
||||
_AssertSerDeserMatch<SUnescaping>(s);
|
||||
var xml = new CXmlDeserializer(new CXmlErrorHandler(exception => { }), true);
|
||||
SUnescaping foo = xml.DeserializeString<SUnescaping>(@"<root />");
|
||||
Assert.AreEqual(foo.S, "Foo'Bar");
|
||||
Assert.AreEqual(foo.Sub.S, "Foo'Bar");
|
||||
var foo = xml.DeserializeString<SUnescaping>(@"<root />");
|
||||
Assert.That(foo.S, Is.EqualTo("Foo'Bar"));
|
||||
Assert.That(foo.Sub.S, Is.EqualTo("Foo'Bar"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestRealFiles([Values(typeof(SThemeCover), typeof(CConfig.SConfig), /*typeof(SThemeScreen),*/ typeof(SDefaultFonts), typeof(SSkin), typeof(STheme), typeof(Dictionary<string, string>))] Type type)
|
||||
public void TestRealFiles(
|
||||
[Values(typeof(SThemeCover), typeof(CConfig.SConfig), /*typeof(SThemeScreen),*/ typeof(SDefaultFonts), typeof(SSkin), typeof(STheme),
|
||||
typeof(Dictionary<string, string>))]
|
||||
Type type)
|
||||
{
|
||||
string filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..", "..", "VocaluxeLib", "XML", "TestFiles");
|
||||
var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "..", "..", "VocaluxeLib", "XML", "TestFiles");
|
||||
|
||||
string xmlPath = Path.Combine(filePath, type.Name + ".xml");
|
||||
var xmlPath = Path.Combine(filePath, type.Name + ".xml");
|
||||
var deser = new CXmlDeserializer();
|
||||
|
||||
object foo = deser.Deserialize(xmlPath, Activator.CreateInstance(type));
|
||||
var foo = deser.Deserialize(xmlPath, Activator.CreateInstance(type));
|
||||
|
||||
Assert.IsInstanceOf(type, foo, "Wrong type with " + type.Name);
|
||||
Assert.That(foo, Is.InstanceOf(type), "Wrong type with " + type.Name);
|
||||
var ser = new CXmlSerializer(type == typeof(CConfig.SConfig));
|
||||
string newXml = ser.Serialize(foo, type == typeof(Dictionary<string, string>) ? "resources" : null);
|
||||
var newXml = ser.Serialize(foo, type == typeof(Dictionary<string, string>) ? "resources" : null);
|
||||
// Typename will be uppercase but input is lowercase
|
||||
newXml = newXml.Replace("<String", "<string").Replace("</String", "</string");
|
||||
string oldXml = File.ReadAllText(xmlPath);
|
||||
var oldXml = File.ReadAllText(xmlPath);
|
||||
// Trim trailing whitespace/newlines
|
||||
oldXml = oldXml.TrimEnd('\r', '\n', ' ', '\t');
|
||||
newXml = newXml.TrimEnd('\r', '\n', ' ', '\t');
|
||||
Assert.AreEqual(oldXml, newXml, "Reconstructed XML has differences.");
|
||||
Assert.That(newXml, Is.EqualTo(oldXml), "Reconstructed XML has differences.");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Helper
|
||||
|
||||
#pragma warning disable 649
|
||||
#pragma warning disable 169
|
||||
private struct SBasic
|
||||
@@ -539,29 +548,26 @@ namespace Tests.VocaluxeLib.XML
|
||||
public string S;
|
||||
}
|
||||
|
||||
|
||||
#pragma warning restore 169
|
||||
#pragma warning restore 649
|
||||
|
||||
private static void _AssertFail<T, T2>(String xmlString) where T2 : Exception where T : new()
|
||||
private static void _AssertXmlSerializeFailWithMissingElement<TSerializeType, TXmlException>(string xmlString)
|
||||
where TSerializeType : new()
|
||||
where TXmlException : CXmlException
|
||||
{
|
||||
var deserializer = new CXmlDeserializer();
|
||||
|
||||
Exception exception =
|
||||
Assert.Catch(() => deserializer.DeserializeString<T>(xmlString));
|
||||
Assert.IsInstanceOf(typeof(T2), exception);
|
||||
Assert.Throws<TXmlException>(new Action(() => deserializer.DeserializeString<TSerializeType>(xmlString)));
|
||||
}
|
||||
|
||||
private static T _AssertSerDeserMatch<T>(string xmlString) where T : new()
|
||||
{
|
||||
var deserializer = new CXmlDeserializer();
|
||||
var serializer = new CXmlSerializer();
|
||||
T foo = deserializer.DeserializeString<T>(xmlString);
|
||||
string xmlNew = serializer.Serialize(foo);
|
||||
Assert.AreEqual(xmlString, xmlNew);
|
||||
var foo = deserializer.DeserializeString<T>(xmlString);
|
||||
var xmlNew = serializer.Serialize(foo);
|
||||
Assert.That(xmlString, Is.EqualTo(xmlNew));
|
||||
return foo;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,10 +10,15 @@
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SpecifyACultureInStringConversionExplicitly/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestUseVarKeywordEverywhere/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestUseVarKeywordEvident/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Cleanup/@EntryIndexedValue"><?xml version="1.0" encoding="utf-16"?><Profile name="Cleanup"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSRemoveCodeRedundancies>True</CSRemoveCodeRedundancies><CSUseVar><BehavourStyle>CAN_CHANGE_TO_EXPLICIT</BehavourStyle><LocalVariableStyle>IMPLICIT_WHEN_INITIALIZER_HAS_TYPE</LocalVariableStyle><ForeachVariableStyle>ALWAYS_EXPLICIT</ForeachVariableStyle></CSUseVar><CSOptimizeUsings><OptimizeUsings>False</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><CSharpFormatDocComments>True</CSharpFormatDocComments><CSShortenReferences>True</CSShortenReferences><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>False</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>False</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>False</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>False</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>False</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>False</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>False</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>False</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>False</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>Ignore</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>False</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>False</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>False</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><StyleCop.Layout><SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine>False</SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine><SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine>True</SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine><SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine>True</SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine><SA1511WhileDoFooterMustNotBePrecededByBlankLine>True</SA1511WhileDoFooterMustNotBePrecededByBlankLine><SA1512SingleLineCommentsMustNotBeFollowedByBlankLine>True</SA1512SingleLineCommentsMustNotBeFollowedByBlankLine><SA1513ClosingCurlyBracketMustBeFollowedByBlankLine>False</SA1513ClosingCurlyBracketMustBeFollowedByBlankLine><SA1514ElementDocumentationHeaderMustBePrecededByBlankLine>False</SA1514ElementDocumentationHeaderMustBePrecededByBlankLine><SA1515SingleLineCommentMustBeProceededByBlankLine>False</SA1515SingleLineCommentMustBeProceededByBlankLine></StyleCop.Layout><StyleCop.Readability><SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists>True</SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists><SA1106CodeMustNotContainEmptyStatements>True</SA1106CodeMustNotContainEmptyStatements><SA1108BlockStatementsMustNotContainEmbeddedComments>True</SA1108BlockStatementsMustNotContainEmbeddedComments><SA1109BlockStatementsMustNotContainEmbeddedRegions>True</SA1109BlockStatementsMustNotContainEmbeddedRegions><SA1120CommentsMustContainText>False</SA1120CommentsMustContainText><SA1121UseBuiltInTypeAlias>False</SA1121UseBuiltInTypeAlias><SA1122UseStringEmptyForEmptyStrings>False</SA1122UseStringEmptyForEmptyStrings><SA1123DoNotPlaceRegionsWithinElements>False</SA1123DoNotPlaceRegionsWithinElements><SA1124CodeMustNotContainEmptyRegions>True</SA1124CodeMustNotContainEmptyRegions></StyleCop.Readability><StyleCop.Spacing><SA1001CommasMustBeSpacedCorrectly>False</SA1001CommasMustBeSpacedCorrectly><SA1005SingleLineCommentsMustBeginWithSingleSpace>False</SA1005SingleLineCommentsMustBeginWithSingleSpace><SA1006PreprocessorKeywordsMustNotBePrecededBySpace>True</SA1006PreprocessorKeywordLine truncated
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Cleanup/@EntryIndexedValue"><?xml version="1.0" encoding="utf-16"?><Profile name="Cleanup"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSRemoveCodeRedundancies>True</CSRemoveCodeRedundancies><CSUseVar><BehavourStyle>CAN_CHANGE_TO_EXPLICIT</BehavourStyle><LocalVariableStyle>IMPLICIT_WHEN_INITIALIZER_HAS_TYPE</LocalVariableStyle><ForeachVariableStyle>ALWAYS_EXPLICIT</ForeachVariableStyle></CSUseVar><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>False</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>False</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>False</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>False</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>False</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>False</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>False</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>False</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>False</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>Ignore</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>False</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>False</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>False</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><StyleCop.Layout><SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine>False</SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine><SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine>True</SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine><SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine>True</SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine><SA1511WhileDoFooterMustNotBePrecededByBlankLine>True</SA1511WhileDoFooterMustNotBePrecededByBlankLine><SA1512SingleLineCommentsMustNotBeFollowedByBlankLine>True</SA1512SingleLineCommentsMustNotBeFollowedByBlankLine><SA1513ClosingCurlyBracketMustBeFollowedByBlankLine>False</SA1513ClosingCurlyBracketMustBeFollowedByBlankLine><SA1514ElementDocumentationHeaderMustBePrecededByBlankLine>False</SA1514ElementDocumentationHeaderMustBePrecededByBlankLine><SA1515SingleLineCommentMustBeProceededByBlankLine>False</SA1515SingleLineCommentMustBeProceededByBlankLine></StyleCop.Layout><StyleCop.Readability><SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists>True</SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists><SA1106CodeMustNotContainEmptyStatements>True</SA1106CodeMustNotContainEmptyStatements><SA1108BlockStatementsMustNotContainEmbeddedComments>True</SA1108BlockStatementsMustNotContainEmbeddedComments><SA1109BlockStatementsMustNotContainEmbeddedRegions>True</SA1109BlockStatementsMustNotContainEmbeddedRegions><SA1120CommentsMustContainText>False</SA1120CommentsMustContainText><SA1121UseBuiltInTypeAlias>False</SA1121UseBuiltInTypeAlias><SA1122UseStringEmptyForEmptyStrings>False</SA1122UseStringEmptyForEmptyStrings><SA1123DoNotPlaceRegionsWithinElements>False</SA1123DoNotPlaceRegionsWithinElements><SA1124CodeMustNotContainEmptyRegions>True</SA1124CodeMustNotContainEmptyRegions></StyleCop.Readability><StyleCop.Spacing><SA1001CommasMustBeSpacedCorrectly>False</SA1001CommasMustBeSpacedCorrectly><SA1005SingleLineCommentsMustBeginWithSingleSpace>False</SA1005SingleLineCommentsMustBeginWithSingleSpace><SA1006PreprocessorKeywordsMustNotBePrecededBySpace>True</SA1006PreprocessorKeywordsMustNotBePrecededBySpace><SA1021NegativeSignsMustBeSpacedCorrectly>True</SA1021NegativeSignsMustBeSpacedCorrectly><SA1022PositiveSignsMustBeSpacedCorrectly>True</SA1022PositiveSignsMustBeSpacLine truncated
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Simple_0020Reformat/@EntryIndexedValue"><?xml version="1.0" encoding="utf-16"?><Profile name="Simple Reformat"><CSOptimizeUsings><OptimizeUsings>False</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSReformatCode>True</CSReformatCode><StyleCop.Documentation><SA1600ElementsMustBeDocumented>False</SA1600ElementsMustBeDocumented><SA1604ElementDocumentationMustHaveSummary>False</SA1604ElementDocumentationMustHaveSummary><SA1609PropertyDocumentationMustHaveValueDocumented>False</SA1609PropertyDocumentationMustHaveValueDocumented><SA1611ElementParametersMustBeDocumented>False</SA1611ElementParametersMustBeDocumented><SA1615ElementReturnValueMustBeDocumented>False</SA1615ElementReturnValueMustBeDocumented><SA1617VoidReturnValueMustNotBeDocumented>False</SA1617VoidReturnValueMustNotBeDocumented><SA1618GenericTypeParametersMustBeDocumented>False</SA1618GenericTypeParametersMustBeDocumented><SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes>False</SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes><SA1628DocumentationTextMustBeginWithACapitalLetter>False</SA1628DocumentationTextMustBeginWithACapitalLetter><SA1629DocumentationTextMustEndWithAPeriod>False</SA1629DocumentationTextMustEndWithAPeriod><SA1633SA1641UpdateFileHeader>Ignore</SA1633SA1641UpdateFileHeader><SA1639FileHeaderMustHaveSummary>False</SA1639FileHeaderMustHaveSummary><SA1642ConstructorSummaryDocumentationMustBeginWithStandardText>False</SA1642ConstructorSummaryDocumentationMustBeginWithStandardText><SA1643DestructorSummaryDocumentationMustBeginWithStandardText>False</SA1643DestructorSummaryDocumentationMustBeginWithStandardText><SA1644DocumentationHeadersMustNotContainBlankLines>False</SA1644DocumentationHeadersMustNotContainBlankLines></StyleCop.Documentation><StyleCop.Spacing><SA1001CommasMustBeSpacedCorrectly>False</SA1001CommasMustBeSpacedCorrectly><SA1005SingleLineCommentsMustBeginWithSingleSpace>False</SA1005SingleLineCommentsMustBeginWithSingleSpace><SA1006PreprocessorKeywordsMustNotBePrecededBySpace>True</SA1006PreprocessorKeywordsMustNotBePrecededBySpace><SA1021NegativeSignsMustBeSpacedCorrectly>True</SA1021NegativeSignsMustBeSpacedCorrectly><SA1022PositiveSignsMustBeSpacedCorrectly>True</SA1022PositiveSignsMustBeSpacedCorrectly><SA1025CodeMustNotContainMultipleWhitespaceInARow>True</SA1025CodeMustNotContainMultipleWhitespaceInARow></StyleCop.Spacing><StyleCop.Readability><SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists>True</SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists><SA1106CodeMustNotContainEmptyStatements>True</SA1106CodeMustNotContainEmptyStatements><SA1108BlockStatementsMustNotContainEmbeddedComments>True</SA1108BlockStatementsMustNotContainEmbeddedComments><SA1109BlockStatementsMustNotContainEmbeddedRegions>True</SA1109BlockStatementsMustNotContainEmbeddedRegions><SA1120CommentsMustContainText>False</SA1120CommentsMustContainText><SA1121UseBuiltInTypeAlias>False</SA1121UseBuiltInTypeAlias><SA1122UseStringEmptyForEmptyStrings>False</SA1122UseStringEmptyForEmptyStrings><SA1123DoNotPlaceRegionsWithinElements>False</SA1123DoNotPlaceRegionsWithinElements><SA1124CodeMustNotContainEmptyRegions>True</SA1124CodeMustNotContainEmptyRegions></StyleCop.Readability><StyleCop.Layout><SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine>False</SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine><SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine>True</SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine><SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine>True</SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine><SA1511WhileDoFooterMustNotBePrecededByBlankLine>True</SA1511WhileDoFooterMustNotBePrecededByBlankLine><SA1512SingleLineCommentsMustNotBeFollowedByBlankLine>True</SA1512SingleLineCommentsMustNotBeFollowedByBlankLine><SA1513ClosingCurlyBracketMustBeFollowedByBlankLine>False</SA1513ClosingCurlyBracketMustBeFollowedByBlankLine><SA1514ElementDocumentationHeaderMustBePrecededByBlankLine>False</SA1514ElementDocumentationHeaderMustBePrecededByBlankLine><SA1515SingleLineCommentMustBeProceededByBlankLine>False</SA1515SingleLineCommentMustBeProceededByBlankLine></StyleCop.Layout><StyleCop.Ordering><AlphabeticalUsingDirectives>Ignore</AlphabeticalUsingDirectives><ExpandUsingDirectiLine truncated
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/RecentlyUsedProfile/@EntryValue">Cleanup</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/SilentCleanupProfile/@EntryValue">Simple Reformat</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOR/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/NAMESPACE_BODY/@EntryValue">BlockScoped</s:String>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AROUND_AUTO_PROPERTY/@EntryValue">0</s:Int64>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AROUND_FIELD/@EntryValue">0</s:Int64>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/BLANK_LINES_AROUND_PROPERTY/@EntryValue">0</s:Int64>
|
||||
@@ -29,9 +34,11 @@
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/FORCE_WHILE_BRACES_STYLE/@EntryValue">ONLY_FOR_MULTILINE</s:String>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_BLANK_LINES_IN_DECLARATIONS/@EntryValue">1</s:Int64>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/KEEP_USER_LINEBREAKS/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">ALWAYS</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSORHOLDER_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_COMPLEX_ACCESSOR_ATTRIBUTE_ON_SAME_LINE/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_RECORD_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_SIMPLE_EMBEDDED_STATEMENT_ON_SAME_LINE/@EntryValue">NEVER</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SIMPLE_EMBEDDED_STATEMENT_STYLE/@EntryValue">LINE_BREAK</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/SPACE_AFTER_TYPECAST_PARENTHESES/@EntryValue">False</s:Boolean>
|
||||
@@ -43,24 +50,34 @@
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_LIMIT/@EntryValue">180</s:Int64>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_MULTIPLE_DECLARATION_STYLE/@EntryValue">WRAP_IF_LONG</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/WRAP_TERNARY_EXPR_STYLE/@EntryValue">WRAP_IF_LONG</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CSharpFileLayoutPatterns/Pattern/@EntryValue"><Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns" /></s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/AddImportsToDeepestScope/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/AllowAlias/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CSharpUsing/QualifiedUsingAtNestedScope/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderRegionName/@EntryValue">license</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderText/@EntryValue">This file is part of $SOLUTION$.
|
||||
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderText/@EntryValue">This file is part of ${File.SolutionName}.
|
||||

|
||||
$SOLUTION$ is free software: you can redistribute it and/or modify
|
||||
${File.SolutionName} is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||

|
||||
$SOLUTION$ is distributed in the hope that it will be useful,
|
||||
${File.SolutionName} is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||

|
||||
You should have received a copy of the GNU General Public License
|
||||
along with $SOLUTION$. If not, see <http://www.gnu.org/licenses/>.</s:String>
|
||||
along with ${File.SolutionName}. If not, see <http://www.gnu.org/licenses/>.</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/Generate/=EqualityMembers/@KeyIndexDefined">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=EqualityMembers/Options/=EqualityOperators/@EntryIndexedValue">False</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=EqualityMembers/Options/=ImplementIEquatable/@EntryIndexedValue">False</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/Generate/=Implementations/@KeyIndexDefined">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=Async/@EntryIndexedValue">False</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=Implementations/Options/=Mutable/@EntryIndexedValue">False</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/Generate/=Overrides/@KeyIndexDefined">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/Generate/=Overrides/Options/=Async/@EntryIndexedValue">False</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/Naming/CSharpAutoNaming/IsNotificationDisabled/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AA/@EntryIndexedValue">AA</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AC/@EntryIndexedValue">AC</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AL/@EntryIndexedValue">AL</s:String>
|
||||
@@ -116,19 +133,34 @@ along with $SOLUTION$. If not, see <http://www.gnu.org/licenses/>.</s:Stri
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PublicFields/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypeParameters/@EntryIndexedValue"><Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=15b5b1f1_002D457c_002D4ca6_002Db278_002D5615aedc07d3/@EntryIndexedValue"><Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"><ElementKinds><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="_" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=236f7aa5_002D7b06_002D43ca_002Dbf2a_002D9b31bfcff09a/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"><ElementKinds><Kind Name="CONSTANT_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="_" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=27c8359b_002D97bf_002D4e1d_002Db126_002D4f613028bcc5/@EntryIndexedValue"><Policy><Descriptor Staticness="Static, Instance" AccessRightKinds="Private, Protected, ProtectedInternal, Internal, Public" Description="Enums"><ElementKinds><Kind Name="ENUM" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="E" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=2c62818f_002D621b_002D4425_002Dadc9_002D78611099bfcb/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Type parameters"><ElementKinds><Kind Name="TYPE_PARAMETER" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="T" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue"><Policy><Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="_" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=53eecf85_002Dd821_002D40e8_002Dac97_002Dfdb734542b84/@EntryIndexedValue"><Policy><Descriptor Staticness="Instance" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Instance fields (not private)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=669e5282_002Dfb4b_002D4e90_002D91e7_002D07d269d04b60/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Constant fields (not private)"><ElementKinds><Kind Name="CONSTANT_FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=70345118_002D4b40_002D4ece_002D937c_002Dbbeb7a0b2e70/@EntryIndexedValue"><Policy><Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static fields (not private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8a85b61a_002D1024_002D4f87_002Db9ef_002D1fdae19930a1/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Parameters"><ElementKinds><Kind Name="PARAMETER" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8b8504e3_002Df0be_002D4c14_002D9103_002Dc732f2bddc15/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Enum members"><ElementKinds><Kind Name="ENUM_MEMBER" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8cff90ce_002Def0d_002D436d_002Db8f2_002D5b5bdb923d3b/@EntryIndexedValue"><Policy><Descriptor Staticness="Static, Instance" AccessRightKinds="Private, Protected, ProtectedInternal, Internal, Public" Description="Classes"><ElementKinds><Kind Name="CLASS" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="C" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=9aa707ae_002Dd4fb_002D4760_002Da649_002Dffcedfabd5dc/@EntryIndexedValue"><Policy><Descriptor Staticness="Static, Instance" AccessRightKinds="Private, Protected" Description="Fields (not public)"><ElementKinds><Kind Name="FIELD" /><Kind Name="READONLY_FIELD" /><Kind Name="METHOD" /><Kind Name="PROPERTY" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="_" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a0b4bc4d_002Dd13b_002D4a37_002Db37e_002Dc9c6864e4302/@EntryIndexedValue"><Policy><Descriptor Staticness="Any" AccessRightKinds="Any" Description="Types and namespaces"><ElementKinds><Kind Name="NAMESPACE" /><Kind Name="CLASS" /><Kind Name="STRUCT" /><Kind Name="ENUM" /><Kind Name="DELEGATE" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=da335a8d_002D4b6e_002D4df6_002D8434_002D29ffe5e2547b/@EntryIndexedValue"><Policy><Descriptor Staticness="Static, Instance" AccessRightKinds="Private, Protected, ProtectedInternal, Internal, Public" Description="Structs"><ElementKinds><Kind Name="STRUCT" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="S" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=f9fce829_002De6f4_002D4cb2_002D80f1_002D5497c44f51df/@EntryIndexedValue"><Policy><Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"><ElementKinds><Kind Name="FIELD" /></ElementKinds></Descriptor><Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="_" Suffix="" Style="AaBb" /></Policy></s:String>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002ECodeCleanup_002EFileHeader_002EFileHeaderSettingsMigrate/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpRenamePlacementToArrangementMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EAddAccessorOwnerDeclarationBracesMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002ECSharpPlaceAttributeOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateThisQualifierSettings/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/UnitTesting/DisabledProviders/=MSTest/@EntryIndexedValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EUnitTestFramework_002EMigrations_002EEnableDisabledProvidersMigration/@EntryIndexedValue">True</s:Boolean>
|
||||
|
||||
<s:String x:Key="/Default/Environment/UnitTesting/MsTestProvider/RunConfigurationFilename/@EntryValue">Vocaluxe.testsettings</s:String>
|
||||
<s:Boolean x:Key="/Default/Environment/UnitTesting/MsTestProvider/UseLegacyRunner/@EntryValue">True</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/UnitTesting/MsTestProvider/UseTestRunConfigFromMetadataFile/@EntryValue">False</s:Boolean>
|
||||
|
||||
@@ -20,8 +20,8 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading.Tasks;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Songs;
|
||||
using VocaluxeLib.Draw;
|
||||
using VocaluxeLib.Songs;
|
||||
using VocaluxeLib.Utils.Player;
|
||||
|
||||
namespace Vocaluxe.Base
|
||||
@@ -64,7 +64,10 @@ namespace Vocaluxe.Base
|
||||
get
|
||||
{
|
||||
if (IsPlayingPreview)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return !_BGMusicFiles.Contains(_CurrentPlaylistElement);
|
||||
}
|
||||
}
|
||||
@@ -75,12 +78,19 @@ namespace Vocaluxe.Base
|
||||
set
|
||||
{
|
||||
if (Disabled == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Disabled = value;
|
||||
if (_Disabled)
|
||||
{
|
||||
Pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,9 +103,9 @@ namespace Vocaluxe.Base
|
||||
set { _BGPlayer.Loop = value; }
|
||||
}
|
||||
|
||||
public static int SongID
|
||||
public static int SongId
|
||||
{
|
||||
get { return _CurPlayer.SongID; }
|
||||
get { return _CurPlayer.SongId; }
|
||||
}
|
||||
|
||||
public static bool SongHasVideo
|
||||
@@ -114,7 +124,10 @@ namespace Vocaluxe.Base
|
||||
set
|
||||
{
|
||||
if (IsPlayingPreview == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Pause();
|
||||
_CurPlayer = value ? _PreviewPlayer : _BGPlayer;
|
||||
Play();
|
||||
@@ -144,7 +157,9 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
_OwnSongsAvailable = value;
|
||||
if (_OwnSongsAvailable && _MusicSource != EBackgroundMusicSource.TR_CONFIG_NO_OWN_MUSIC)
|
||||
{
|
||||
_AddOwnMusic();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,12 +170,17 @@ namespace Vocaluxe.Base
|
||||
public static void Init()
|
||||
{
|
||||
if (_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IEnumerable<string> soundFiles = CHelper.ListSoundFiles(CSettings.FolderNameBackgroundMusic, true, true);
|
||||
var soundFiles = CHelper.ListSoundFiles(CSettings.FolderNameBackgroundMusic, true, true);
|
||||
|
||||
foreach (string path in soundFiles)
|
||||
foreach (var path in soundFiles)
|
||||
{
|
||||
_BGMusicFiles.Add(new CPlaylistElement(path));
|
||||
}
|
||||
|
||||
_CurPlayer = _BGPlayer;
|
||||
//Set a default to have a consistent starting point, use SetMusicSource afterwards
|
||||
_MusicSource = EBackgroundMusicSource.TR_CONFIG_NO_OWN_MUSIC;
|
||||
@@ -185,19 +205,27 @@ namespace Vocaluxe.Base
|
||||
public static void Play()
|
||||
{
|
||||
if (!IsPlayingPreview && CConfig.Config.Sound.BackgroundMusic != EBackgroundMusicOffOn.TR_CONFIG_ON)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsPlayingPreview || _BGPlayer.SoundLoaded)
|
||||
{
|
||||
_CurPlayer.Play();
|
||||
}
|
||||
else
|
||||
{
|
||||
Next();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Stop()
|
||||
{
|
||||
_CurPlayer.Stop();
|
||||
if (!IsPlayingPreview)
|
||||
{
|
||||
_CurrentPlaylistElement = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Pause()
|
||||
@@ -208,7 +236,9 @@ namespace Vocaluxe.Base
|
||||
public static void Next()
|
||||
{
|
||||
if (IsPlayingPreview)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Stop(); //stop last song if any
|
||||
if (_PreviousMusicIndex < _PreviousFiles.Count - 2)
|
||||
@@ -223,7 +253,10 @@ namespace Vocaluxe.Base
|
||||
if (_NotPlayedFiles.Count == 0)
|
||||
{
|
||||
if (_PreviousFiles.Count == 0)
|
||||
{
|
||||
return; //No songs to play
|
||||
}
|
||||
|
||||
_NotPlayedFiles.AddRange(_PreviousFiles);
|
||||
}
|
||||
|
||||
@@ -233,15 +266,21 @@ namespace Vocaluxe.Base
|
||||
_PreviousFiles.Add(_CurrentPlaylistElement);
|
||||
_PreviousMusicIndex = _PreviousFiles.Count - 1;
|
||||
}
|
||||
|
||||
_StartSong();
|
||||
}
|
||||
|
||||
public static void Previous()
|
||||
{
|
||||
if (IsPlayingPreview)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_PreviousMusicIndex < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_CurrentPlaylistElement == null || (_BGPlayer.Position <= 1.5f && _PreviousMusicIndex > 0))
|
||||
{
|
||||
@@ -250,12 +289,13 @@ namespace Vocaluxe.Base
|
||||
|
||||
_CurrentPlaylistElement = _PreviousFiles[_PreviousMusicIndex];
|
||||
}
|
||||
|
||||
_StartSong();
|
||||
}
|
||||
|
||||
public static void Update()
|
||||
{
|
||||
if (_PreviewStartHelperTask != null && ( _PreviewPlayer.Length > 0 || _PreviewStartWaitCounter++ >= _PreviewStartWaitMaxTries))
|
||||
if (_PreviewStartHelperTask != null && (_PreviewPlayer.Length > 0 || _PreviewStartWaitCounter++ >= _PreviewStartWaitMaxTries))
|
||||
{
|
||||
lock (_PreviewStartHelperTaskLock)
|
||||
{
|
||||
@@ -270,11 +310,15 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
|
||||
if (!IsPlaying)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_CurPlayer.Update();
|
||||
if (!IsPlayingPreview && _BGPlayer.IsFinished)
|
||||
{
|
||||
Next();
|
||||
}
|
||||
}
|
||||
|
||||
public static CTextureRef GetVideoTexture()
|
||||
@@ -285,7 +329,10 @@ namespace Vocaluxe.Base
|
||||
public static void SetMusicSource(EBackgroundMusicSource source)
|
||||
{
|
||||
if (_MusicSource == source)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_MusicSource = source;
|
||||
switch (_MusicSource)
|
||||
{
|
||||
@@ -308,7 +355,9 @@ namespace Vocaluxe.Base
|
||||
public static void LoadPreview(CSong song, float start = -1f)
|
||||
{
|
||||
if (song == null)
|
||||
{
|
||||
throw new ArgumentNullException("song");
|
||||
}
|
||||
|
||||
if (!IsPlayingPreview)
|
||||
{
|
||||
@@ -317,9 +366,11 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
|
||||
//Change song position only if song is changed or near to end
|
||||
bool songChanged = _CurPlayer.SongID != song.ID;
|
||||
var songChanged = _CurPlayer.SongId != song.Id;
|
||||
if (!songChanged && _CurPlayer.Position + 30 < _CurPlayer.Length)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_PreviewPlayer.Load(song);
|
||||
|
||||
@@ -327,33 +378,47 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
_PreviewStartHelperTask = new Task(() =>
|
||||
{
|
||||
float length = _PreviewPlayer.Length;
|
||||
var length = _PreviewPlayer.Length;
|
||||
if (length < 1)
|
||||
{
|
||||
length = 30; // If length is unknow or invalid assume a length of 30s
|
||||
}
|
||||
|
||||
if (start < 0)
|
||||
start = (song.Preview.Source == EDataSource.None) ? length / 4f : song.Preview.StartTime;
|
||||
{
|
||||
start = song.Preview.Source == EDataSource.None ? length / 4f : song.Preview.StartTime;
|
||||
}
|
||||
|
||||
if (start > length - 5f)
|
||||
{
|
||||
start = Math.Max(0f, Math.Min(length / 4f, length - 5f));
|
||||
}
|
||||
|
||||
if (start >= 0.5f)
|
||||
{
|
||||
start -= 0.5f;
|
||||
}
|
||||
|
||||
_PreviewPlayer.Position = start;
|
||||
Play();
|
||||
});
|
||||
}
|
||||
|
||||
_CurPlayer = _PreviewPlayer;
|
||||
}
|
||||
|
||||
public static void StopPreview()
|
||||
{
|
||||
if (!IsPlayingPreview)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Stop();
|
||||
_CurPlayer = _BGPlayer;
|
||||
if (_MusicSource != EBackgroundMusicSource.TR_CONFIG_NO_OWN_MUSIC)
|
||||
{
|
||||
var song = CSongs.GetSong(_PreviewPlayer.SongID);
|
||||
var song = CSongs.GetSong(_PreviewPlayer.SongId);
|
||||
if (song != null)
|
||||
{
|
||||
_CurPlayer.Load(song);
|
||||
@@ -364,6 +429,7 @@ namespace Vocaluxe.Base
|
||||
_CurPlayer.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
CSound.SetGlobalVolume(CConfig.BackgroundMusicVolume);
|
||||
}
|
||||
|
||||
@@ -384,13 +450,18 @@ namespace Vocaluxe.Base
|
||||
|
||||
//otherwhise load
|
||||
if (!_CurrentPlaylistElement.HasMetaData)
|
||||
{
|
||||
_BGPlayer.Load(_CurrentPlaylistElement.MusicFilePath, 0f, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Seek to #Start-Tag, if found
|
||||
float start = 0f;
|
||||
var start = 0f;
|
||||
if (_CurrentPlaylistElement.Start > 0.001 && CConfig.Config.Sound.BackgroundMusicUseStart == EOffOn.TR_CONFIG_ON)
|
||||
{
|
||||
start = _CurrentPlaylistElement.Start;
|
||||
}
|
||||
|
||||
_BGPlayer.Load(_CurrentPlaylistElement.Song, start, true);
|
||||
}
|
||||
}
|
||||
@@ -398,22 +469,33 @@ namespace Vocaluxe.Base
|
||||
private static void _AddOwnMusic()
|
||||
{
|
||||
if (_OwnMusicAdded || !_OwnSongsAvailable)
|
||||
{
|
||||
return;
|
||||
foreach (CSong song in CSongs.AllSongs)
|
||||
}
|
||||
|
||||
foreach (var song in CSongs.AllSongs)
|
||||
{
|
||||
_NotPlayedFiles.Add(new CPlaylistElement(song));
|
||||
}
|
||||
|
||||
_OwnMusicAdded = true;
|
||||
}
|
||||
|
||||
private static void _RemoveOwnMusic()
|
||||
{
|
||||
if (!_OwnMusicAdded)
|
||||
{
|
||||
return;
|
||||
_NotPlayedFiles.RemoveAll(el => el.SongID >= 0);
|
||||
_PreviousFiles.RemoveAll(el => el.SongID >= 0);
|
||||
}
|
||||
|
||||
_NotPlayedFiles.RemoveAll(el => el.SongId >= 0);
|
||||
_PreviousFiles.RemoveAll(el => el.SongId >= 0);
|
||||
_PreviousMusicIndex = _PreviousFiles.IndexOf(_CurrentPlaylistElement);
|
||||
|
||||
if (IsPlaying && !_IsBackgroundFile(_CurrentPlaylistElement))
|
||||
{
|
||||
Next();
|
||||
}
|
||||
|
||||
_OwnMusicAdded = false;
|
||||
}
|
||||
@@ -421,7 +503,10 @@ namespace Vocaluxe.Base
|
||||
private static void _AddBackgroundMusic()
|
||||
{
|
||||
if (_BackgroundMusicAdded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_NotPlayedFiles.AddRange(_BGMusicFiles);
|
||||
_BackgroundMusicAdded = true;
|
||||
}
|
||||
@@ -429,13 +514,18 @@ namespace Vocaluxe.Base
|
||||
private static void _RemoveBackgroundMusic()
|
||||
{
|
||||
if (!_BackgroundMusicAdded)
|
||||
{
|
||||
return;
|
||||
_NotPlayedFiles.RemoveAll(el => el.SongID < 0);
|
||||
_PreviousFiles.RemoveAll(el => el.SongID < 0);
|
||||
}
|
||||
|
||||
_NotPlayedFiles.RemoveAll(el => el.SongId < 0);
|
||||
_PreviousFiles.RemoveAll(el => el.SongId < 0);
|
||||
_PreviousMusicIndex = _PreviousFiles.IndexOf(_CurrentPlaylistElement);
|
||||
|
||||
if (IsPlaying && _IsBackgroundFile(_CurrentPlaylistElement))
|
||||
{
|
||||
Next();
|
||||
}
|
||||
|
||||
_BackgroundMusicAdded = false;
|
||||
}
|
||||
@@ -445,4 +535,4 @@ namespace Vocaluxe.Base
|
||||
return _BGMusicFiles.Contains(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+143
-62
@@ -17,7 +17,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -28,7 +27,6 @@ using Vocaluxe.Lib.Sound.Record;
|
||||
using Vocaluxe.Lib.Webcam;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Log;
|
||||
using VocaluxeLib.Profile;
|
||||
using VocaluxeLib.Xml;
|
||||
|
||||
namespace Vocaluxe.Base
|
||||
@@ -46,7 +44,7 @@ namespace Vocaluxe.Base
|
||||
#pragma warning disable 649
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
public struct SConfigInfo
|
||||
// ReSharper restore MemberCanBePrivate.Global
|
||||
// ReSharper restore MemberCanBePrivate.Global
|
||||
{
|
||||
// ReSharper disable NotAccessedField.Global
|
||||
// ReSharper disable NotAccessedField.Local
|
||||
@@ -76,7 +74,8 @@ namespace Vocaluxe.Base
|
||||
[DefaultValue(ERenderer.TR_CONFIG_DIRECT3D)]
|
||||
public ERenderer Renderer;
|
||||
#else
|
||||
[DefaultValue(ERenderer.TR_CONFIG_OPENGL)] public ERenderer Renderer;
|
||||
[DefaultValue(ERenderer.TR_CONFIG_OPENGL)]
|
||||
public ERenderer Renderer;
|
||||
#endif
|
||||
|
||||
[DefaultValue(ETextureQuality.TR_CONFIG_TEXTURE_HIGH)]
|
||||
@@ -116,16 +115,26 @@ namespace Vocaluxe.Base
|
||||
|
||||
public struct SConfigTheme
|
||||
{
|
||||
[XmlElement("Name"), DefaultValue("Vocaluxe 2024")] public string Theme;
|
||||
[DefaultValue("Standard")] public string Skin;
|
||||
[XmlElement("Cover"), DefaultValue("Vocaluxe 2024")] public string CoverTheme;
|
||||
[DefaultValue(EOffOn.TR_CONFIG_ON)] public EOffOn DrawNoteLines;
|
||||
[DefaultValue(EOffOn.TR_CONFIG_ON)] public EOffOn DrawToneHelper;
|
||||
[DefaultValue(ETimerLook.TR_CONFIG_TIMERLOOK_EXPANDED)] public ETimerLook TimerLook;
|
||||
[DefaultValue(EPlayerInfo.TR_CONFIG_PLAYERINFO_BOTH)] public EPlayerInfo PlayerInfo;
|
||||
[DefaultValue(EFadePlayerInfo.TR_CONFIG_FADEPLAYERINFO_OFF)] public EFadePlayerInfo FadePlayerInfo;
|
||||
[DefaultValue(ECoverLoading.TR_CONFIG_COVERLOADING_DYNAMIC)] public ECoverLoading CoverLoading;
|
||||
[DefaultValue(ELyricStyle.TR_CONFIG_LYRICSTYLE_SLIDE)] public ELyricStyle LyricStyle;
|
||||
[XmlElement("Name"), DefaultValue("Vocaluxe 2024")]
|
||||
public string Theme;
|
||||
[DefaultValue("Standard")]
|
||||
public string Skin;
|
||||
[XmlElement("Cover"), DefaultValue("Vocaluxe 2024")]
|
||||
public string CoverTheme;
|
||||
[DefaultValue(EOffOn.TR_CONFIG_ON)]
|
||||
public EOffOn DrawNoteLines;
|
||||
[DefaultValue(EOffOn.TR_CONFIG_ON)]
|
||||
public EOffOn DrawToneHelper;
|
||||
[DefaultValue(ETimerLook.TR_CONFIG_TIMERLOOK_EXPANDED)]
|
||||
public ETimerLook TimerLook;
|
||||
[DefaultValue(EPlayerInfo.TR_CONFIG_PLAYERINFO_BOTH)]
|
||||
public EPlayerInfo PlayerInfo;
|
||||
[DefaultValue(EFadePlayerInfo.TR_CONFIG_FADEPLAYERINFO_OFF)]
|
||||
public EFadePlayerInfo FadePlayerInfo;
|
||||
[DefaultValue(ECoverLoading.TR_CONFIG_COVERLOADING_DYNAMIC)]
|
||||
public ECoverLoading CoverLoading;
|
||||
[DefaultValue(ELyricStyle.TR_CONFIG_LYRICSTYLE_SLIDE)]
|
||||
public ELyricStyle LyricStyle;
|
||||
}
|
||||
|
||||
public struct SConfigSound
|
||||
@@ -171,17 +180,28 @@ namespace Vocaluxe.Base
|
||||
[DefaultValue(ESongMenu.TR_CONFIG_TILE_BOARD)]
|
||||
public ESongMenu SongMenu;
|
||||
// ReSharper restore MemberHidesStaticFromOuterClass
|
||||
[DefaultValue(ESongSorting.TR_CONFIG_ARTIST)] public ESongSorting SongSorting;
|
||||
[DefaultValue(EOffOn.TR_CONFIG_ON)] public EOffOn IgnoreArticles;
|
||||
[DefaultValue(ETimerMode.TR_CONFIG_TIMERMODE_REMAINING)] public ETimerMode TimerMode;
|
||||
[XmlAltName("NumPlayer"), DefaultValue(2)] public int NumPlayers;
|
||||
[DefaultValue(EOffOn.TR_CONFIG_OFF)] public EOffOn Tabs;
|
||||
[DefaultValue(EOffOn.TR_CONFIG_OFF)] public EOffOn AutoplayPreviews;
|
||||
[XmlAltName("AutoplayPreviewDelay"), DefaultValue(500)] public int AutoplayPreviewDelay;
|
||||
[DefaultValue(ELyricsPosition.TR_CONFIG_LYRICSPOSITION_BOTTOM)] public ELyricsPosition LyricsPosition;
|
||||
[DefaultValue(0.1f)] public float MinLineBreakTime; //Minimum time to show the text before it is (to be) sung (if possible)
|
||||
[XmlArrayItem("Player"), XmlArray] public string[] Players;
|
||||
[DefaultValue(EHighscoreStyle.TR_CONFIG_HIGHSCORE_LIST_BEST)] public EHighscoreStyle HighscoreStyle;
|
||||
[DefaultValue(ESongSorting.TR_CONFIG_ARTIST)]
|
||||
public ESongSorting SongSorting;
|
||||
[DefaultValue(EOffOn.TR_CONFIG_ON)]
|
||||
public EOffOn IgnoreArticles;
|
||||
[DefaultValue(ETimerMode.TR_CONFIG_TIMERMODE_REMAINING)]
|
||||
public ETimerMode TimerMode;
|
||||
[XmlAltName("NumPlayer"), DefaultValue(2)]
|
||||
public int NumPlayers;
|
||||
[DefaultValue(EOffOn.TR_CONFIG_OFF)]
|
||||
public EOffOn Tabs;
|
||||
[DefaultValue(EOffOn.TR_CONFIG_OFF)]
|
||||
public EOffOn AutoplayPreviews;
|
||||
[XmlAltName("AutoplayPreviewDelay"), DefaultValue(500)]
|
||||
public int AutoplayPreviewDelay;
|
||||
[DefaultValue(ELyricsPosition.TR_CONFIG_LYRICSPOSITION_BOTTOM)]
|
||||
public ELyricsPosition LyricsPosition;
|
||||
[DefaultValue(0.1f)]
|
||||
public float MinLineBreakTime; //Minimum time to show the text before it is (to be) sung (if possible)
|
||||
[XmlArrayItem("Player"), XmlArray]
|
||||
public string[] Players;
|
||||
[DefaultValue(EHighscoreStyle.TR_CONFIG_HIGHSCORE_LIST_BEST)]
|
||||
public EHighscoreStyle HighscoreStyle;
|
||||
}
|
||||
|
||||
public struct SConfigVideo
|
||||
@@ -243,7 +263,7 @@ namespace Vocaluxe.Base
|
||||
//Folders
|
||||
//We need full path for folders for matching folder path with textfile path when loading
|
||||
public static readonly List<string> SongFolders = new List<string>
|
||||
{
|
||||
{
|
||||
#if INSTALLER
|
||||
Path.Combine(CSettings.DataFolder, CSettings.FolderNameSongs),
|
||||
Path.Combine(CSettings.ProgramFolder, FolderNameSongs)
|
||||
@@ -252,13 +272,13 @@ namespace Vocaluxe.Base
|
||||
#elif LINUX
|
||||
Path.Combine(CSettings.DataFolder, CSettings.FolderNameSongs)
|
||||
#endif
|
||||
};
|
||||
};
|
||||
/// <summary>
|
||||
/// Folders with profiles
|
||||
/// First one is used for new profiles
|
||||
/// </summary>
|
||||
public static readonly List<string> ProfileFolders = new List<string>
|
||||
{
|
||||
{
|
||||
#if INSTALLER
|
||||
Path.Combine(CSettings.DataFolder, CSettings.FolderNameProfiles),
|
||||
CSettings.FolderNameProfiles
|
||||
@@ -366,22 +386,31 @@ namespace Vocaluxe.Base
|
||||
set
|
||||
{
|
||||
if (Config.Game.SongMenu == value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Config.Game.SongMenu = value;
|
||||
if (SongMenuChanged != null)
|
||||
{
|
||||
SongMenuChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
if (_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Init config file
|
||||
_LoadConfig();
|
||||
if (!File.Exists(_FileConfig))
|
||||
{
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
_Initialized = true;
|
||||
}
|
||||
@@ -401,24 +430,35 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
Config = xml.Deserialize<SConfig>(_FileConfig);
|
||||
if (_XmlErrorsOccured)
|
||||
{
|
||||
CLog.Error("There were some warnings or errors loading the config file. Some values might have been reset to their defaults.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Config = xml.DeserializeString<SConfig>("<root />");
|
||||
}
|
||||
|
||||
NormalizeSongPaths();
|
||||
|
||||
if (Config.Game.MinLineBreakTime < 0)
|
||||
{
|
||||
Config.Game.MinLineBreakTime = 0.1f;
|
||||
}
|
||||
|
||||
if (!Config.Game.NumPlayers.IsInRange(1, CSettings.MaxNumPlayer))
|
||||
{
|
||||
Config.Game.NumPlayers = 2;
|
||||
}
|
||||
|
||||
Array.Resize(ref Config.Game.Players, CSettings.MaxNumPlayer);
|
||||
|
||||
if (!Config.Graphics.NumScreens.IsInRange(1, CSettings.MaxNumScreens))
|
||||
{
|
||||
Config.Graphics.NumScreens = 1;
|
||||
}
|
||||
|
||||
bool langExists = CLanguage.SetLanguage(Config.Game.Language);
|
||||
var langExists = CLanguage.SetLanguage(Config.Game.Language);
|
||||
|
||||
if (langExists == false)
|
||||
{
|
||||
@@ -430,7 +470,9 @@ namespace Vocaluxe.Base
|
||||
Config.Record.MicDelay = (int)(20 * Math.Round(Config.Record.MicDelay / 20.0));
|
||||
|
||||
if (!Config.Server.ServerPort.IsInRange(1, 65535))
|
||||
{
|
||||
Config.Server.ServerPort = 3000;
|
||||
}
|
||||
|
||||
Config.Info = new SConfigInfo
|
||||
{
|
||||
@@ -451,7 +493,10 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
// Avoid multiple comments (e.g. for array entries)
|
||||
if (_CommentsGot.Contains(elName))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
_CommentsGot.Add(elName);
|
||||
switch (elName)
|
||||
{
|
||||
@@ -576,7 +621,8 @@ namespace Vocaluxe.Base
|
||||
case "ServerPort":
|
||||
return "Server Port (default: 3000) [1..65535]";
|
||||
case "SongCountCoverThreshold":
|
||||
return "Threshold of songs for that covers will not longer be included in get-all-songs-requests (e.g. song list) (default: 70) [-1..65535] -1 => always deliver covers";
|
||||
return
|
||||
"Threshold of songs for that covers will not longer be included in get-all-songs-requests (e.g. song list) (default: 70) [-1..65535] -1 => always deliver covers";
|
||||
case "Stretch":
|
||||
return "Stretch view to full window size: " + CHelper.ListStrings(Enum.GetNames(typeof(EOffOn)));
|
||||
default:
|
||||
@@ -596,7 +642,7 @@ namespace Vocaluxe.Base
|
||||
/// </summary>
|
||||
public static float CalcCycleTime()
|
||||
{
|
||||
return (1f / Config.Graphics.MaxFPS) * 1000f;
|
||||
return 1f / Config.Graphics.MaxFPS * 1000f;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -606,32 +652,43 @@ namespace Vocaluxe.Base
|
||||
/// <returns></returns>
|
||||
public static bool IsMicConfig(int player = 0)
|
||||
{
|
||||
ReadOnlyCollection<CRecordDevice> devices = CRecord.GetDevices();
|
||||
var devices = CRecord.GetDevices();
|
||||
if (devices == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (player > 0)
|
||||
{
|
||||
return devices.Any(t => t.PlayerChannel.Contains(player));
|
||||
}
|
||||
|
||||
for (int p = 0; p < CSettings.MaxNumPlayer; ++p)
|
||||
for (var p = 0; p < CSettings.MaxNumPlayer; ++p)
|
||||
{
|
||||
if (devices.Any(t => t.PlayerChannel.Contains(p + 1)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static int GetMaxNumMics()
|
||||
{
|
||||
int max = 0;
|
||||
for (int i = 1; i <= CSettings.MaxNumPlayer; i++)
|
||||
var max = 0;
|
||||
for (var i = 1; i <= CSettings.MaxNumPlayer; i++)
|
||||
{
|
||||
if (IsMicConfig(i))
|
||||
{
|
||||
max = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
@@ -647,11 +704,13 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
//Look for (usb-)mic
|
||||
//SRecordDevice[] Devices = new SRecordDevice[CRecord.RecordGetDevices().Length];
|
||||
ReadOnlyCollection<CRecordDevice> devices = CRecord.GetDevices();
|
||||
var devices = CRecord.GetDevices();
|
||||
if (devices == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (CRecordDevice device in devices)
|
||||
foreach (var device in devices)
|
||||
{
|
||||
//Has Device some signal-names in name -> This could be a (usb-)mic
|
||||
if (Regex.IsMatch(device.Name, "Usb|Wireless", RegexOptions.IgnoreCase))
|
||||
@@ -672,8 +731,9 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//If no usb-mics found -> Look for Devices with "mic" or "mik"
|
||||
foreach (CRecordDevice device in devices)
|
||||
foreach (var device in devices)
|
||||
{
|
||||
//Has Device some signal-names in name -> This could be a mic
|
||||
if (Regex.IsMatch(device.Name, "Mic|Mik", RegexOptions.IgnoreCase))
|
||||
@@ -712,17 +772,21 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
SongFolders.Clear();
|
||||
|
||||
foreach (string folder in Config.Game.SongFolder)
|
||||
foreach (var folder in Config.Game.SongFolder)
|
||||
{
|
||||
//Check if folder exists
|
||||
if (Directory.Exists(folder))
|
||||
{
|
||||
SongFolders.Add(Path.GetFullPath(folder));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Test if songfolders are still empty or now empty
|
||||
if(Config.Game.SongFolder.Length == 0)
|
||||
if (Config.Game.SongFolder.Length == 0)
|
||||
{
|
||||
Config.Game.SongFolder = SongFolders.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -731,19 +795,19 @@ namespace Vocaluxe.Base
|
||||
/// <param name="args">Parameters</param>
|
||||
public static void LoadCommandLineParams(string[] args)
|
||||
{
|
||||
Regex spliterParam = new Regex(@"-{1,2}|\/", RegexOptions.IgnoreCase);
|
||||
var spliterParam = new Regex(@"-{1,2}|\/", RegexOptions.IgnoreCase);
|
||||
|
||||
//Complete argument string
|
||||
string arguments = args.Aggregate(String.Empty, (current, arg) => current + arg + " ");
|
||||
var arguments = args.Aggregate(string.Empty, (current, arg) => current + arg + " ");
|
||||
|
||||
args = spliterParam.Split(arguments);
|
||||
|
||||
foreach (string text in args)
|
||||
foreach (var text in args)
|
||||
{
|
||||
Regex spliterVal = new Regex(@"\s", RegexOptions.IgnoreCase);
|
||||
var spliterVal = new Regex(@"\s", RegexOptions.IgnoreCase);
|
||||
|
||||
//split arg with Spilter-Regex and save in parts
|
||||
string[] parts = spliterVal.Split(text.Trim(), 2);
|
||||
var parts = spliterVal.Split(text.Trim(), 2);
|
||||
|
||||
switch (parts.Length)
|
||||
{
|
||||
@@ -757,6 +821,7 @@ namespace Vocaluxe.Base
|
||||
//Add value
|
||||
_Values.Add("");
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
@@ -770,6 +835,7 @@ namespace Vocaluxe.Base
|
||||
//Add value
|
||||
_Values.Add(parts[1]);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -781,25 +847,31 @@ namespace Vocaluxe.Base
|
||||
public static void UseCommandLineParamsBefore()
|
||||
{
|
||||
//Check each parameter
|
||||
for (int i = 0; i < _Params.Count; i++)
|
||||
for (var i = 0; i < _Params.Count; i++)
|
||||
{
|
||||
//Switch parameter to lower case
|
||||
string param = _Params[i].ToLower();
|
||||
var param = _Params[i].ToLower();
|
||||
|
||||
string value = _Values[i];
|
||||
var value = _Values[i];
|
||||
|
||||
switch (param)
|
||||
{
|
||||
case "configfile":
|
||||
//Check if value is valid
|
||||
if (_CheckFile(value))
|
||||
{
|
||||
_FileConfig = value;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "scorefile":
|
||||
//Check if value is valid
|
||||
if (_CheckFile(value))
|
||||
{
|
||||
FileHighscoreDB = value;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case "playlistfolder":
|
||||
@@ -819,16 +891,16 @@ namespace Vocaluxe.Base
|
||||
/// </summary>
|
||||
public static void UseCommandLineParamsAfter()
|
||||
{
|
||||
bool songFoldersOverwritten = false;
|
||||
var songFoldersOverwritten = false;
|
||||
//Check each parameter
|
||||
for (int i = 0; i < _Params.Count; i++)
|
||||
for (var i = 0; i < _Params.Count; i++)
|
||||
{
|
||||
//Switch parameter as lower case
|
||||
string param = _Params[i];
|
||||
var param = _Params[i];
|
||||
|
||||
param = param.ToLower();
|
||||
|
||||
string value = _Values[i];
|
||||
var value = _Values[i];
|
||||
|
||||
switch (param)
|
||||
{
|
||||
@@ -839,8 +911,12 @@ namespace Vocaluxe.Base
|
||||
SongFolders.Clear();
|
||||
songFoldersOverwritten = true;
|
||||
}
|
||||
|
||||
if (!SongFolders.Contains(value))
|
||||
{
|
||||
SongFolders.Add(value);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -848,13 +924,16 @@ namespace Vocaluxe.Base
|
||||
|
||||
private static bool _CheckFile(string value)
|
||||
{
|
||||
char[] chars = Path.GetInvalidPathChars();
|
||||
for (int i = 0; i < chars.Length; i++)
|
||||
var chars = Path.GetInvalidPathChars();
|
||||
for (var i = 0; i < chars.Length; i++)
|
||||
{
|
||||
if (value.Contains(chars[i].ToString()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return !String.IsNullOrEmpty(Path.GetFileName(value)) && Path.HasExtension(value);
|
||||
|
||||
return !string.IsNullOrEmpty(Path.GetFileName(value)) && Path.HasExtension(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -862,23 +941,25 @@ namespace Vocaluxe.Base
|
||||
/// </summary>
|
||||
public static void UsePlayers()
|
||||
{
|
||||
CProfile[] profiles = CProfiles.GetProfiles();
|
||||
var profiles = CProfiles.GetProfiles();
|
||||
|
||||
for (int j = 0; j < CSettings.MaxNumPlayer; j++)
|
||||
for (var j = 0; j < CSettings.MaxNumPlayer; j++)
|
||||
{
|
||||
CGame.Players[j].ProfileID = Guid.Empty;
|
||||
CGame.Players[j].ProfileId = Guid.Empty;
|
||||
if (string.IsNullOrEmpty(Config.Game.Players[j]))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (CProfile profile in profiles)
|
||||
foreach (var profile in profiles)
|
||||
{
|
||||
if (Path.GetFileName(profile.FilePath) == Config.Game.Players[j] && profile.Active == EOffOn.TR_CONFIG_ON)
|
||||
{
|
||||
//Update Game-infos with player
|
||||
CGame.Players[j].ProfileID = profile.ID;
|
||||
CGame.Players[j].ProfileId = profile.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,15 +44,20 @@ namespace Vocaluxe.Base
|
||||
private static void _AddController(IController controller)
|
||||
{
|
||||
if (controller.Init())
|
||||
{
|
||||
_Controller.Add(controller);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Close()
|
||||
{
|
||||
if (_Controller != null)
|
||||
{
|
||||
foreach (IController controller in _Controller)
|
||||
foreach (var controller in _Controller)
|
||||
{
|
||||
controller.Close();
|
||||
}
|
||||
|
||||
_Controller = null;
|
||||
_KeysPool = null;
|
||||
_MousePool = null;
|
||||
@@ -61,14 +66,18 @@ namespace Vocaluxe.Base
|
||||
|
||||
public static void Connect()
|
||||
{
|
||||
foreach (IController controller in _Controller)
|
||||
foreach (var controller in _Controller)
|
||||
{
|
||||
controller.Connect();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Disconnect()
|
||||
{
|
||||
foreach (IController controller in _Controller)
|
||||
foreach (var controller in _Controller)
|
||||
{
|
||||
controller.Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsConnected()
|
||||
@@ -79,17 +88,21 @@ namespace Vocaluxe.Base
|
||||
|
||||
public static void Update()
|
||||
{
|
||||
foreach (IController controller in _Controller)
|
||||
foreach (var controller in _Controller)
|
||||
{
|
||||
controller.Update();
|
||||
|
||||
var ke = new SKeyEvent();
|
||||
while (controller.PollKeyEvent(ref ke))
|
||||
{
|
||||
_KeysPool.Add(ke);
|
||||
}
|
||||
|
||||
var me = new SMouseEvent();
|
||||
while (controller.PollMouseEvent(ref me))
|
||||
{
|
||||
_MousePool.Add(me);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,6 +114,7 @@ namespace Vocaluxe.Base
|
||||
_KeysPool.RemoveAt(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -112,13 +126,16 @@ namespace Vocaluxe.Base
|
||||
_MousePool.RemoveAt(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static void SetRumble(float duration)
|
||||
{
|
||||
foreach (IController controller in _Controller)
|
||||
foreach (var controller in _Controller)
|
||||
{
|
||||
controller.SetRumble(duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+63
-32
@@ -18,11 +18,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Linq;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Draw;
|
||||
using VocaluxeLib.Log;
|
||||
@@ -69,11 +68,14 @@ namespace Vocaluxe.Base
|
||||
/// <returns></returns>
|
||||
public static int GetCoverThemeIndex()
|
||||
{
|
||||
for (int i = 0; i < _CoverThemes.Count; i++)
|
||||
for (var i = 0; i < _CoverThemes.Count; i++)
|
||||
{
|
||||
if (_CoverThemes[i].Info.Name == CConfig.Config.Theme.CoverTheme)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -85,7 +87,9 @@ namespace Vocaluxe.Base
|
||||
lock (_Covers)
|
||||
{
|
||||
if (!_CoverExists(name))
|
||||
{
|
||||
return NoCover;
|
||||
}
|
||||
|
||||
return _Covers[name];
|
||||
}
|
||||
@@ -93,27 +97,37 @@ namespace Vocaluxe.Base
|
||||
|
||||
public static CTextureRef GenerateCover(string text, ECoverGeneratorType type, CSong firstSong)
|
||||
{
|
||||
CTextureRef texture = Cover(text);
|
||||
var texture = Cover(text);
|
||||
if (texture != NoCover)
|
||||
{
|
||||
return texture;
|
||||
}
|
||||
|
||||
texture = CDraw.CopyTexture(NoCover);
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
_CancelToken.Token.ThrowIfCancellationRequested();
|
||||
var coverBmp = !_CoverGenerators.ContainsKey(type)
|
||||
? null : _CoverGenerators[type].GetCover(text, firstSong != null ? Path.Combine(firstSong.Folder, firstSong.CoverFileName) : null);
|
||||
_CancelToken.Token.ThrowIfCancellationRequested();
|
||||
if (coverBmp == null && _CoverGenerators.ContainsKey(ECoverGeneratorType.Default))
|
||||
{
|
||||
_CancelToken.Token.ThrowIfCancellationRequested();
|
||||
Bitmap coverBmp = !_CoverGenerators.ContainsKey(type)
|
||||
? null : _CoverGenerators[type].GetCover(text, firstSong != null ? Path.Combine(firstSong.Folder, firstSong.CoverFileName) : null);
|
||||
_CancelToken.Token.ThrowIfCancellationRequested();
|
||||
if (coverBmp == null && _CoverGenerators.ContainsKey(ECoverGeneratorType.Default))
|
||||
coverBmp = _CoverGenerators[ECoverGeneratorType.Default].GetCover(text, firstSong != null ? Path.Combine(firstSong.Folder, firstSong.CoverFileName) : null);
|
||||
_CancelToken.Token.ThrowIfCancellationRequested();
|
||||
if (coverBmp != null)
|
||||
CDraw.EnqueueTextureUpdate(texture, coverBmp);
|
||||
_CancelToken.Token.ThrowIfCancellationRequested();
|
||||
}, _CancelToken.Token);
|
||||
coverBmp = _CoverGenerators[ECoverGeneratorType.Default].GetCover(text, firstSong != null ? Path.Combine(firstSong.Folder, firstSong.CoverFileName) : null);
|
||||
}
|
||||
|
||||
_CancelToken.Token.ThrowIfCancellationRequested();
|
||||
if (coverBmp != null)
|
||||
{
|
||||
CDraw.EnqueueTextureUpdate(texture, coverBmp);
|
||||
}
|
||||
|
||||
_CancelToken.Token.ThrowIfCancellationRequested();
|
||||
}, _CancelToken.Token);
|
||||
lock (_Covers)
|
||||
{
|
||||
_Covers.Add(text, texture);
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
@@ -136,7 +150,7 @@ namespace Vocaluxe.Base
|
||||
|
||||
// Stefan1200: Added a workaround to fix issue #446, because switching the cover theme gets bugged on the song screen and needed a game restart.
|
||||
// Toggle the tabs view fixes this bug somehow.
|
||||
CSongs.Categorizer.Tabs = (CConfig.Config.Game.Tabs == EOffOn.TR_CONFIG_ON ? EOffOn.TR_CONFIG_OFF : EOffOn.TR_CONFIG_ON);
|
||||
CSongs.Categorizer.Tabs = CConfig.Config.Game.Tabs == EOffOn.TR_CONFIG_ON ? EOffOn.TR_CONFIG_OFF : EOffOn.TR_CONFIG_ON;
|
||||
CSongs.Categorizer.Tabs = CConfig.Config.Game.Tabs;
|
||||
}
|
||||
|
||||
@@ -144,13 +158,15 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
lock (_Covers)
|
||||
{
|
||||
foreach (string key in _Covers.Keys)
|
||||
foreach (var key in _Covers.Keys)
|
||||
{
|
||||
CTextureRef texture = _Covers[key];
|
||||
var texture = _Covers[key];
|
||||
CDraw.RemoveTexture(ref texture);
|
||||
}
|
||||
|
||||
_Covers.Clear();
|
||||
}
|
||||
|
||||
lock (_CoverGenerators)
|
||||
{
|
||||
_CoverGenerators.Clear();
|
||||
@@ -162,13 +178,14 @@ namespace Vocaluxe.Base
|
||||
/// </summary>
|
||||
private static SThemeCover _GetCoverTheme()
|
||||
{
|
||||
int index = GetCoverThemeIndex();
|
||||
var index = GetCoverThemeIndex();
|
||||
if (index < 0)
|
||||
{
|
||||
index = 0;
|
||||
CConfig.Config.Theme.CoverTheme = _CoverThemes[0].Info.Name;
|
||||
}
|
||||
return _CoverThemes[index];
|
||||
|
||||
return _CoverThemes[index];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -178,11 +195,11 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
_CoverThemes.Clear();
|
||||
|
||||
string folderPath = Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameCover);
|
||||
IEnumerable<string> files = CHelper.ListFiles(folderPath, "*.xml");
|
||||
var folderPath = Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameCover);
|
||||
var files = CHelper.ListFiles(folderPath, "*.xml");
|
||||
|
||||
var xml = new CXmlDeserializer();
|
||||
foreach (string file in files)
|
||||
foreach (var file in files)
|
||||
{
|
||||
SThemeCover theme;
|
||||
try
|
||||
@@ -195,7 +212,7 @@ namespace Vocaluxe.Base
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!String.IsNullOrEmpty(theme.Info.Folder) && !String.IsNullOrEmpty(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);
|
||||
@@ -208,29 +225,38 @@ namespace Vocaluxe.Base
|
||||
/// </summary>
|
||||
private static bool _LoadCovers()
|
||||
{
|
||||
SThemeCover coverTheme = _GetCoverTheme();
|
||||
var coverTheme = _GetCoverTheme();
|
||||
|
||||
Debug.Assert(!String.IsNullOrEmpty(coverTheme.Info.Name));
|
||||
Debug.Assert(!string.IsNullOrEmpty(coverTheme.Info.Name));
|
||||
|
||||
IEnumerable<string> files = CHelper.ListImageFiles(coverTheme.FolderPath, true, true);
|
||||
var files = CHelper.ListImageFiles(coverTheme.FolderPath, true, true);
|
||||
|
||||
lock (_Covers)
|
||||
{
|
||||
foreach (string file in files)
|
||||
foreach (var file in files)
|
||||
{
|
||||
_AddCover(Path.GetFileNameWithoutExtension(file), file);
|
||||
}
|
||||
|
||||
if (_CoverExists(_NoCoverName))
|
||||
{
|
||||
NoCover = _Covers[_NoCoverName];
|
||||
}
|
||||
else if (_CoverExists(_NoCoverNameAlt))
|
||||
{
|
||||
NoCover = _Covers[_NoCoverNameAlt];
|
||||
}
|
||||
else
|
||||
{
|
||||
CLog.Fatal("Covertheme \"{ThemeName}\" does not include a cover file named \"{MissingFileName}\" and cannot be used!", CLog.Params(coverTheme.Info.Name, _NoCoverName));
|
||||
CLog.Fatal("Covertheme \"{ThemeName}\" does not include a cover file named \"{MissingFileName}\" and cannot be used!",
|
||||
CLog.Params(coverTheme.Info.Name, _NoCoverName));
|
||||
_UnloadCovers();
|
||||
// Remove current theme and recursively try the other themes
|
||||
_CoverThemes.Remove(coverTheme);
|
||||
return _CoverThemes.Count > 0 && _LoadCovers();
|
||||
}
|
||||
}
|
||||
|
||||
_LoadCoverGenerators(coverTheme);
|
||||
return true;
|
||||
}
|
||||
@@ -271,11 +297,14 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
lock (_CoverGenerators)
|
||||
{
|
||||
foreach (SThemeCoverGenerator theme in coverTheme.CoverGenerators)
|
||||
foreach (var theme in coverTheme.CoverGenerators)
|
||||
{
|
||||
if (_CoverGenerators.ContainsKey(theme.Type))
|
||||
{
|
||||
continue;
|
||||
CCoverGenerator el = new CCoverGenerator(theme, coverTheme.FolderPath);
|
||||
}
|
||||
|
||||
var el = new CCoverGenerator(theme, coverTheme.FolderPath);
|
||||
_CoverGenerators.Add(theme.Type, el);
|
||||
}
|
||||
}
|
||||
@@ -291,8 +320,10 @@ namespace Vocaluxe.Base
|
||||
lock (_Covers)
|
||||
{
|
||||
if (!_CoverExists(name))
|
||||
{
|
||||
_Covers.Add(name, CDraw.AddTexture(file));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,9 +23,9 @@ using System.Drawing.Drawing2D;
|
||||
using System.Drawing.Imaging;
|
||||
using System.Drawing.Text;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Vocaluxe.Base.Fonts;
|
||||
using VocaluxeLib;
|
||||
using System.Linq;
|
||||
|
||||
namespace Vocaluxe.Base
|
||||
{
|
||||
@@ -49,9 +49,9 @@ namespace Vocaluxe.Base
|
||||
/// <summary>
|
||||
/// Split lines after special chars, descending priority
|
||||
/// </summary>
|
||||
private static readonly char[] _SplitCharPreferences = {':', '/', '-'};
|
||||
private static readonly char[] _SplitCharAfter = {':', '/', '-', ' ', ')', '.', '*', ','};
|
||||
private static readonly char[] _SplitCharBefore = {'('};
|
||||
private static readonly char[] _SplitCharPreferences = { ':', '/', '-' };
|
||||
private static readonly char[] _SplitCharAfter = { ':', '/', '-', ' ', ')', '.', '*', ',' };
|
||||
private static readonly char[] _SplitCharBefore = { '(' };
|
||||
|
||||
public CCoverGenerator(SThemeCoverGenerator theme, string basePath)
|
||||
{
|
||||
@@ -64,6 +64,7 @@ namespace Vocaluxe.Base
|
||||
_Image = Path.Combine(basePath, _Theme.Image);
|
||||
_Valid = File.Exists(_Image);
|
||||
}
|
||||
|
||||
_MarginLeft = theme.Text.Margin.Left.HasValue ? theme.Text.Margin.Left.Value : theme.Text.Margin.Default;
|
||||
_MarginRight = theme.Text.Margin.Right.HasValue ? theme.Text.Margin.Right.Value : theme.Text.Margin.Default;
|
||||
_MarginTop = theme.Text.Margin.Top.HasValue ? theme.Text.Margin.Top.Value : theme.Text.Margin.Default;
|
||||
@@ -83,9 +84,10 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
if (_WidthTrimmed < 0f)
|
||||
{
|
||||
string text = Text.TrimEnd(null);
|
||||
var text = Text.TrimEnd(null);
|
||||
_WidthTrimmed = text.Length == Text.Length ? Width : _Graphics.MeasureString(text, _Font).Width;
|
||||
}
|
||||
|
||||
return _WidthTrimmed;
|
||||
}
|
||||
}
|
||||
@@ -94,7 +96,7 @@ namespace Vocaluxe.Base
|
||||
public CTextElement(string text, Graphics g, Font font)
|
||||
{
|
||||
Text = text;
|
||||
SizeF dimensions = g.MeasureString(text, font);
|
||||
var dimensions = g.MeasureString(text, font);
|
||||
Width = dimensions.Width;
|
||||
Height = (dimensions.Height + font.Height) / 2;
|
||||
_Graphics = g;
|
||||
@@ -114,28 +116,32 @@ namespace Vocaluxe.Base
|
||||
g.Clear(_BGColor.AsColor());
|
||||
|
||||
ImageAttributes ia = null;
|
||||
if (_Theme.ShowFirstCover && !String.IsNullOrEmpty(firstCoverPath) && File.Exists(firstCoverPath))
|
||||
if (_Theme.ShowFirstCover && !string.IsNullOrEmpty(firstCoverPath) && File.Exists(firstCoverPath))
|
||||
{
|
||||
using (Bitmap bmp2 = new Bitmap(firstCoverPath))
|
||||
using (var bmp2 = new Bitmap(firstCoverPath))
|
||||
{
|
||||
g.DrawImage(bmp2, bmpBackground.GetRect(), 0, 0, bmp2.Width, bmp2.Height, GraphicsUnit.Pixel);
|
||||
ColorMatrix cm = new ColorMatrix {Matrix33 = _Theme.ImageAlpha};
|
||||
}
|
||||
|
||||
var cm = new ColorMatrix { Matrix33 = _Theme.ImageAlpha };
|
||||
ia = new ImageAttributes();
|
||||
ia.SetColorMatrix(cm);
|
||||
}
|
||||
|
||||
g.DrawImage(bmpBackground, bmpBackground.GetRect(), 0, 0, bmpBackground.Width, bmpBackground.Height, GraphicsUnit.Pixel, ia);
|
||||
}
|
||||
|
||||
private void _DrawText(Graphics g, Size bmpSize, CFont font, List<CTextElement> elements)
|
||||
{
|
||||
Font fo = CFonts.GetSystemFont(font);
|
||||
var fo = CFonts.GetSystemFont(font);
|
||||
|
||||
float maxHeight = elements.Select(el => el.Height).Max();
|
||||
int lineCount = elements.Last().Line + 1;
|
||||
var maxHeight = elements.Select(el => el.Height).Max();
|
||||
var lineCount = elements.Last().Line + 1;
|
||||
|
||||
//Have to use size in em not pixels!
|
||||
float emSize = fo.Size * fo.FontFamily.GetCellAscent(fo.Style) / fo.FontFamily.GetEmHeight(fo.Style);
|
||||
float outlineSize = CFonts.GetOutlineSize(font) * font.Height;
|
||||
SColorF outlineColorF = CFonts.GetOutlineColor(font);
|
||||
var emSize = fo.Size * fo.FontFamily.GetCellAscent(fo.Style) / fo.FontFamily.GetEmHeight(fo.Style);
|
||||
var outlineSize = CFonts.GetOutlineSize(font) * font.Height;
|
||||
var outlineColorF = CFonts.GetOutlineColor(font);
|
||||
outlineColorF.A = outlineColorF.A * _TextColor.A;
|
||||
|
||||
using (var path = new GraphicsPath())
|
||||
@@ -143,37 +149,43 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
pen.LineJoin = LineJoin.Round;
|
||||
pen.Alignment = PenAlignment.Outset;
|
||||
float top = (bmpSize.Height - _MarginBottom - _MarginTop - maxHeight * lineCount) / 2 + _MarginTop;
|
||||
int nextLineEl = 0;
|
||||
for (int i = 0; i < lineCount; i++)
|
||||
var top = (bmpSize.Height - _MarginBottom - _MarginTop - maxHeight * lineCount) / 2 + _MarginTop;
|
||||
var nextLineEl = 0;
|
||||
for (var i = 0; i < lineCount; i++)
|
||||
{
|
||||
int firstEl = nextLineEl;
|
||||
var firstEl = nextLineEl;
|
||||
for (; nextLineEl < elements.Count; nextLineEl++)
|
||||
{
|
||||
if (elements[nextLineEl].Line > i)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
string line = elements.GetRange(firstEl, nextLineEl - firstEl).Aggregate("", (current, element) => current + element.Text);
|
||||
var line = elements.GetRange(firstEl, nextLineEl - firstEl).Aggregate("", (current, element) => current + element.Text);
|
||||
float left;
|
||||
if (lineCount == 1 || (i == 1 && lineCount == 3))
|
||||
{
|
||||
//Center Text if this is the only line or the middle line
|
||||
float width = _GetWidth(elements, firstEl, nextLineEl - 1);
|
||||
var width = _GetWidth(elements, firstEl, nextLineEl - 1);
|
||||
left = (bmpSize.Width - _MarginLeft - _MarginRight - width) / 2 + _MarginLeft;
|
||||
}
|
||||
else if (i == lineCount - 1)
|
||||
{
|
||||
//Place last line at right
|
||||
float width = _GetWidth(elements, firstEl, nextLineEl - 1);
|
||||
var width = _GetWidth(elements, firstEl, nextLineEl - 1);
|
||||
left = bmpSize.Width - width - _MarginRight;
|
||||
}
|
||||
else
|
||||
{
|
||||
left = _MarginLeft;
|
||||
}
|
||||
|
||||
//g.DrawString(line, fo, new SolidBrush(_TextColor.AsColor()), left, top, StringFormat.GenericTypographic);
|
||||
path.AddString(line, fo.FontFamily, (int)fo.Style, emSize, new PointF(left, top), StringFormat.GenericTypographic);
|
||||
top += maxHeight + _LineSpace;
|
||||
}
|
||||
|
||||
g.DrawPath(pen, path);
|
||||
g.FillPath(new SolidBrush(_TextColor.AsColor()), path);
|
||||
}
|
||||
@@ -182,14 +194,17 @@ namespace Vocaluxe.Base
|
||||
public Bitmap GetCover(string text, string firstCoverPath)
|
||||
{
|
||||
if (!_Valid)
|
||||
return null;
|
||||
text = CLanguage.Translate(_Theme.Text.Text.Replace("%TEXT%", text));
|
||||
using (Bitmap bmpImage = new Bitmap(_Image))
|
||||
{
|
||||
Bitmap bmp = new Bitmap(bmpImage.Width, bmpImage.Height, PixelFormat.Format32bppArgb);
|
||||
return null;
|
||||
}
|
||||
|
||||
text = CLanguage.Translate(_Theme.Text.Text.Replace("%TEXT%", text));
|
||||
using (var bmpImage = new Bitmap(_Image))
|
||||
{
|
||||
var bmp = new Bitmap(bmpImage.Width, bmpImage.Height, PixelFormat.Format32bppArgb);
|
||||
try
|
||||
{
|
||||
using (Graphics g = Graphics.FromImage(bmp))
|
||||
using (var g = Graphics.FromImage(bmp))
|
||||
{
|
||||
g.SmoothingMode = SmoothingMode.AntiAlias;
|
||||
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
|
||||
@@ -199,17 +214,21 @@ namespace Vocaluxe.Base
|
||||
|
||||
if (text != "")
|
||||
{
|
||||
CFont font = new CFont(_Theme.Text.Font);
|
||||
Font fo = CFonts.GetSystemFont(font);
|
||||
IEnumerable<string> textParts = _SplitText(text);
|
||||
List<CTextElement> elements = textParts.Select(line => new CTextElement(line, g, fo)).ToList();
|
||||
float factor = _DistributeText(elements, bmp.Width, bmp.Height);
|
||||
foreach (CTextElement element in elements)
|
||||
var font = new CFont(_Theme.Text.Font);
|
||||
var fo = CFonts.GetSystemFont(font);
|
||||
var textParts = _SplitText(text);
|
||||
var elements = textParts.Select(line => new CTextElement(line, g, fo)).ToList();
|
||||
var factor = _DistributeText(elements, bmp.Width, bmp.Height);
|
||||
foreach (var element in elements)
|
||||
{
|
||||
element.AdjustSize(factor);
|
||||
}
|
||||
|
||||
font.Height *= factor / (1f + CFonts.GetOutlineSize(font)); //Adjust for outline size
|
||||
_DrawText(g, bmp.GetSize(), font, elements);
|
||||
}
|
||||
}
|
||||
|
||||
return bmp;
|
||||
}
|
||||
catch (Exception)
|
||||
@@ -217,6 +236,7 @@ namespace Vocaluxe.Base
|
||||
bmp.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -230,19 +250,22 @@ namespace Vocaluxe.Base
|
||||
/// <returns>Factor for resizing the text (Maximizing this factor means maximizing the height)</returns>
|
||||
private float _DistributeText(List<CTextElement> elements, int width, int height)
|
||||
{
|
||||
int availableWidth = width - _MarginLeft - _MarginRight;
|
||||
int availableHeight = height - _MarginTop - _MarginBottom;
|
||||
var availableWidth = width - _MarginLeft - _MarginRight;
|
||||
var availableHeight = height - _MarginTop - _MarginBottom;
|
||||
|
||||
float textHeight = elements.Select(el => el.Height).Max();
|
||||
var textHeight = elements.Select(el => el.Height).Max();
|
||||
|
||||
//Try 1 line:
|
||||
float textWidth = _GetWidth(elements, 0);
|
||||
int maxHeight = Math.Min(availableHeight, (int)_Theme.Text.Font.Size);
|
||||
float factorH = maxHeight / textHeight;
|
||||
float factorW = availableWidth / textWidth;
|
||||
var textWidth = _GetWidth(elements, 0);
|
||||
var maxHeight = Math.Min(availableHeight, (int)_Theme.Text.Font.Size);
|
||||
var factorH = maxHeight / textHeight;
|
||||
var factorW = availableWidth / textWidth;
|
||||
if (factorH <= factorW)
|
||||
{
|
||||
return factorH; //Limited by Height
|
||||
float factor1 = factorW;
|
||||
}
|
||||
|
||||
var factor1 = factorW;
|
||||
|
||||
//Try 2 lines
|
||||
if (elements.Count == 1)
|
||||
@@ -250,15 +273,19 @@ namespace Vocaluxe.Base
|
||||
//Only 1 element -> 1 line
|
||||
return factor1;
|
||||
}
|
||||
|
||||
availableWidth -= _Theme.Text.Indent;
|
||||
maxHeight = Math.Min(availableHeight / 2 - _LineSpace, (int)_Theme.Text.Font.Size);
|
||||
factorH = maxHeight / textHeight;
|
||||
if (factorH <= factor1)
|
||||
{
|
||||
return factor1; //Cannot get any bigger with more lines
|
||||
int splitEl = _GetSplitElement(elements, textWidth / 2);
|
||||
}
|
||||
|
||||
var splitEl = _GetSplitElement(elements, textWidth / 2);
|
||||
Debug.Assert(splitEl >= 0 && splitEl < elements.Count - 1);
|
||||
float width1 = _GetWidth(elements, 0, splitEl);
|
||||
float width2 = _GetWidth(elements, splitEl + 1);
|
||||
var width1 = _GetWidth(elements, 0, splitEl);
|
||||
var width2 = _GetWidth(elements, splitEl + 1);
|
||||
factorW = availableWidth / Math.Max(width1, width2);
|
||||
if (factorH <= factorW)
|
||||
{
|
||||
@@ -268,8 +295,9 @@ namespace Vocaluxe.Base
|
||||
_SetLine(elements, splitEl + 1, elements.Count - 1, 1);
|
||||
return factorH;
|
||||
}
|
||||
|
||||
// factor2 < factorH && factorH>factor1
|
||||
float factor2 = factorW;
|
||||
var factor2 = factorW;
|
||||
|
||||
//Try 3 lines
|
||||
maxHeight = Math.Min(availableHeight / 3 - 2 * _LineSpace, (int)_Theme.Text.Font.Size);
|
||||
@@ -278,29 +306,35 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
//Only 2 elements or cannot get any bigger
|
||||
if (factor2 <= factor1)
|
||||
{
|
||||
return factor1;
|
||||
}
|
||||
|
||||
_SetLine(elements, splitEl + 1, elements.Count - 1, 1);
|
||||
return factor2;
|
||||
}
|
||||
int splitEl21 = _GetSplitElement(elements, textWidth / 3, false);
|
||||
int splitEl22 = _GetSplitElement(elements, textWidth / 3, true, splitEl21 + 1);
|
||||
|
||||
var splitEl21 = _GetSplitElement(elements, textWidth / 3, false);
|
||||
var splitEl22 = _GetSplitElement(elements, textWidth / 3, true, splitEl21 + 1);
|
||||
Debug.Assert(splitEl21 >= 0 && splitEl21 < splitEl22 && splitEl22 < elements.Count - 1);
|
||||
float width21 = _GetWidth(elements, 0, splitEl21);
|
||||
float width22 = _GetWidth(elements, splitEl21 + 1, splitEl22);
|
||||
float width23 = _GetWidth(elements, splitEl22 + 1);
|
||||
var width21 = _GetWidth(elements, 0, splitEl21);
|
||||
var width22 = _GetWidth(elements, splitEl21 + 1, splitEl22);
|
||||
var width23 = _GetWidth(elements, splitEl22 + 1);
|
||||
factorW = availableWidth / Math.Max(Math.Max(width21, width22), width23);
|
||||
float factor3 = Math.Min(factorH, factorW);
|
||||
var factor3 = Math.Min(factorH, factorW);
|
||||
if (factor3 > Math.Max(factor1, factor2))
|
||||
{
|
||||
_SetLine(elements, splitEl21 + 1, splitEl22, 1);
|
||||
_SetLine(elements, splitEl22 + 1, elements.Count - 1, 2);
|
||||
return factor3;
|
||||
}
|
||||
|
||||
if (factor2 > factor1)
|
||||
{
|
||||
_SetLine(elements, splitEl + 1, elements.Count - 1, 1);
|
||||
return factor2;
|
||||
}
|
||||
|
||||
return factor1;
|
||||
}
|
||||
|
||||
@@ -325,19 +359,30 @@ namespace Vocaluxe.Base
|
||||
private static float _GetWidth(List<CTextElement> list, int start, int end)
|
||||
{
|
||||
if (start < 0)
|
||||
{
|
||||
start = 0;
|
||||
}
|
||||
|
||||
if (end >= list.Count)
|
||||
{
|
||||
end = list.Count - 1;
|
||||
}
|
||||
|
||||
if (start > end)
|
||||
{
|
||||
return 0f;
|
||||
float width = list.GetRange(start, end - start).Select(el => el.Width).Sum();
|
||||
}
|
||||
|
||||
var width = list.GetRange(start, end - start).Select(el => el.Width).Sum();
|
||||
return width + list[end].WidthTrimmed;
|
||||
}
|
||||
|
||||
private static void _SetLine(List<CTextElement> list, int start, int end, int line)
|
||||
{
|
||||
for (int i = start; i <= end; i++)
|
||||
for (var i = start; i <= end; i++)
|
||||
{
|
||||
list[i].Line = line;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -352,63 +397,88 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
//Assert we have enough elements
|
||||
Debug.Assert(singleSplit && elements.Count - startElement >= 2 || !singleSplit && elements.Count - startElement >= 3);
|
||||
float curWidth = 0f;
|
||||
var curWidth = 0f;
|
||||
int splitEl;
|
||||
for (splitEl = startElement; splitEl < elements.Count; splitEl++)
|
||||
{
|
||||
curWidth += elements[splitEl].Width;
|
||||
if (curWidth >= requestedWidth)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// At this point we can either keep splitEl on this line for move it to the next line
|
||||
// ==> line with splitEl is to long, without it is to short. so find the best option
|
||||
// Check if line starts or ends with a long word, than put that on a single line
|
||||
if (splitEl == startElement)
|
||||
{
|
||||
return splitEl;
|
||||
}
|
||||
|
||||
// These 2 conditions also cover if the text fits on 1 line
|
||||
if (!singleSplit && splitEl >= elements.Count - 2)
|
||||
{
|
||||
return elements.Count - 3; // Make sure we have 2 elements left if in multi split mode!
|
||||
if (splitEl >= elements.Count - 1)
|
||||
return elements.Count - 2; // Make sure we have 1 element left!
|
||||
}
|
||||
|
||||
float diffWith = curWidth - requestedWidth;
|
||||
float diffWithout = requestedWidth - (curWidth - elements[splitEl].Width);
|
||||
if (splitEl >= elements.Count - 1)
|
||||
{
|
||||
return elements.Count - 2; // Make sure we have 1 element left!
|
||||
}
|
||||
|
||||
var diffWith = curWidth - requestedWidth;
|
||||
var diffWithout = requestedWidth - (curWidth - elements[splitEl].Width);
|
||||
if (!singleSplit)
|
||||
{
|
||||
// If we split in 3 lines, add the error of the next 2 lines to the current error for both cases
|
||||
int splitEl2 = _GetSplitElement(elements, requestedWidth, true, splitEl + 1);
|
||||
int splitEl3 = _GetSplitElement(elements, requestedWidth, true, splitEl);
|
||||
var splitEl2 = _GetSplitElement(elements, requestedWidth, true, splitEl + 1);
|
||||
var splitEl3 = _GetSplitElement(elements, requestedWidth, true, splitEl);
|
||||
diffWith += Math.Abs(requestedWidth - _GetWidth(elements, splitEl + 1, splitEl2)) + Math.Abs(requestedWidth - _GetWidth(elements, splitEl2 + 1));
|
||||
diffWithout += Math.Abs(requestedWidth - _GetWidth(elements, splitEl, splitEl3)) + Math.Abs(requestedWidth - _GetWidth(elements, splitEl3 + 1));
|
||||
}
|
||||
float diff = diffWith - diffWithout;
|
||||
|
||||
var diff = diffWith - diffWithout;
|
||||
//Differences below this value are considered acceptable
|
||||
float equalDist = requestedWidth * 0.025f;
|
||||
var equalDist = requestedWidth * 0.025f;
|
||||
if (diff > equalDist)
|
||||
{
|
||||
return splitEl - 1; // width error with element is much higher than without -> put element on next line
|
||||
}
|
||||
|
||||
if (diff < -equalDist)
|
||||
{
|
||||
return splitEl; // width error with element is much less than without -> keep element on line
|
||||
}
|
||||
|
||||
//The real split would be somewhere in the middle of the element so we can move it to either line
|
||||
string tmp = elements[splitEl].Text.TrimEnd(null);
|
||||
char lastCharWith = tmp[tmp.Length - 1];
|
||||
var tmp = elements[splitEl].Text.TrimEnd(null);
|
||||
var lastCharWith = tmp[tmp.Length - 1];
|
||||
tmp = elements[splitEl - 1].Text.TrimEnd(null);
|
||||
char lastCharWithout = tmp[tmp.Length - 1];
|
||||
var lastCharWithout = tmp[tmp.Length - 1];
|
||||
//Check if last chars are special chars
|
||||
if (Char.IsLetterOrDigit(lastCharWith))
|
||||
{
|
||||
if (Char.IsLetterOrDigit(lastCharWithout))
|
||||
{
|
||||
return startElement == 0 ? splitEl : splitEl - 1; //Both are alphanumeric, favor longer first lines but shorter middle lines
|
||||
}
|
||||
|
||||
return splitEl - 1; //Split after non-alphanumeric char
|
||||
}
|
||||
if (Char.IsLetterOrDigit(lastCharWithout))
|
||||
return splitEl; //Split after non-alphanumeric char
|
||||
|
||||
int indexWith = Array.IndexOf(_SplitCharPreferences, lastCharWith);
|
||||
int indexWithout = Array.IndexOf(_SplitCharPreferences, lastCharWithout);
|
||||
if (Char.IsLetterOrDigit(lastCharWithout))
|
||||
{
|
||||
return splitEl; //Split after non-alphanumeric char
|
||||
}
|
||||
|
||||
var indexWith = Array.IndexOf(_SplitCharPreferences, lastCharWith);
|
||||
var indexWithout = Array.IndexOf(_SplitCharPreferences, lastCharWithout);
|
||||
if (indexWith <= indexWithout)
|
||||
{
|
||||
return startElement == 0 ? splitEl : splitEl - 1; //favor longer first lines but shorter middle lines
|
||||
}
|
||||
|
||||
return splitEl - 1;
|
||||
}
|
||||
|
||||
@@ -422,15 +492,16 @@ namespace Vocaluxe.Base
|
||||
Debug.Assert(!String.IsNullOrWhiteSpace(text));
|
||||
|
||||
text = text.Trim().TrimMultipleWs();
|
||||
List<string> lines = new List<string>();
|
||||
var lines = new List<string>();
|
||||
if (text.Length == 1)
|
||||
{
|
||||
lines.Add(text);
|
||||
return lines;
|
||||
}
|
||||
|
||||
//Split the text on non-letter chars
|
||||
int curStart = 0;
|
||||
for (int i = 1; i < text.Length - 1; i++)
|
||||
var curStart = 0;
|
||||
for (var i = 1; i < text.Length - 1; i++)
|
||||
{
|
||||
if ((Array.IndexOf(_SplitCharAfter, text[i]) >= 0 && (Char.IsLetterOrDigit(text, i + 1) || Array.IndexOf(_SplitCharBefore, text[i + 1]) >= 0)) ||
|
||||
(Char.IsLetterOrDigit(text, i) && Array.IndexOf(_SplitCharBefore, text[i + 1]) >= 0))
|
||||
@@ -439,20 +510,24 @@ namespace Vocaluxe.Base
|
||||
curStart = ++i;
|
||||
}
|
||||
}
|
||||
|
||||
//Add the rest
|
||||
lines.Add(text.Substring(curStart));
|
||||
|
||||
//Check for initials (like J. R.R. Tolkien) and join them
|
||||
curStart = -1;
|
||||
string curText = "";
|
||||
for (int i = 0; i < lines.Count; i++)
|
||||
var curText = "";
|
||||
for (var i = 0; i < lines.Count; i++)
|
||||
{
|
||||
string part = lines[i].Trim();
|
||||
var part = lines[i].Trim();
|
||||
if (part.Length == 2 && part[1] == '.')
|
||||
{
|
||||
//Initials found, continue or start new
|
||||
if (curStart < 0)
|
||||
{
|
||||
curStart = i;
|
||||
}
|
||||
|
||||
curText += lines[i];
|
||||
}
|
||||
else if (curStart >= 0)
|
||||
@@ -465,10 +540,12 @@ namespace Vocaluxe.Base
|
||||
lines.RemoveRange(curStart + 1, i - curStart - 1);
|
||||
i = curStart;
|
||||
}
|
||||
|
||||
curText = "";
|
||||
curStart = -1;
|
||||
}
|
||||
}
|
||||
|
||||
//Handle last part
|
||||
if (curStart >= 0)
|
||||
{
|
||||
@@ -482,14 +559,16 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
|
||||
// Remove single char lines
|
||||
for (int i = 0; i < lines.Count; i++)
|
||||
for (var i = 0; i < lines.Count; i++)
|
||||
{
|
||||
string part = lines[i];
|
||||
var part = lines[i];
|
||||
if (part.Trim().Length == 1)
|
||||
{
|
||||
lines.RemoveAt(i);
|
||||
if (i == 0)
|
||||
{
|
||||
lines[0] = part + lines[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
lines[i - 1] += part;
|
||||
@@ -497,6 +576,7 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lines;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,18 +54,24 @@ namespace Vocaluxe.Base
|
||||
public void Draw()
|
||||
{
|
||||
if (_Movetimer.ElapsedMilliseconds > CSettings.MouseMoveOffTime)
|
||||
{
|
||||
Deactivate();
|
||||
}
|
||||
|
||||
if (_Fading != null)
|
||||
{
|
||||
bool finished;
|
||||
_Cursor.Color.A = _Fading.GetValue(out finished);
|
||||
if (finished)
|
||||
{
|
||||
_Fading = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (Visible && (CSettings.ProgramState == EProgramState.EditTheme || ShowCursor))
|
||||
{
|
||||
CDraw.DrawTexture(_Cursor);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdatePosition(int x, int y)
|
||||
@@ -87,7 +93,7 @@ namespace Vocaluxe.Base
|
||||
|
||||
public void LoadSkin()
|
||||
{
|
||||
SThemeCursor theme = CThemes.GetCursorTheme();
|
||||
var theme = CThemes.GetCursorTheme();
|
||||
_Cursor = CDraw.CopyTexture(CThemes.GetSkinTexture(theme.SkinName, -1));
|
||||
|
||||
theme.Color.Get(-1, out _Cursor.Color);
|
||||
@@ -103,8 +109,8 @@ namespace Vocaluxe.Base
|
||||
|
||||
public void ReloadSkin()
|
||||
{
|
||||
int x = X;
|
||||
int y = Y;
|
||||
var x = X;
|
||||
var y = Y;
|
||||
UnloadSkin();
|
||||
LoadSkin();
|
||||
UpdatePosition(x, y);
|
||||
@@ -113,7 +119,10 @@ namespace Vocaluxe.Base
|
||||
public void Deactivate()
|
||||
{
|
||||
if (!IsActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_MouseMoveDiffMin = CSettings.MouseMoveDiffMinInactive;
|
||||
_Movetimer.Reset();
|
||||
_Fade(0f, 0.5f);
|
||||
@@ -122,10 +131,13 @@ namespace Vocaluxe.Base
|
||||
public void Activate()
|
||||
{
|
||||
// Here we need to restart the timer in all cases but only set fading and diff if we are not yet active
|
||||
bool active = IsActive;
|
||||
var active = IsActive;
|
||||
_Movetimer.Restart();
|
||||
if (active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_MouseMoveDiffMin = CSettings.MouseMoveDiffMinActive;
|
||||
_Fade(1f, 0.2f);
|
||||
}
|
||||
|
||||
@@ -40,11 +40,13 @@ namespace Vocaluxe.Base
|
||||
CLog.Fatal("Error initializing Highscore-DB");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_CoverDB.Init())
|
||||
{
|
||||
CLog.Fatal("Error initializing Cover-DB");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -55,6 +57,7 @@ namespace Vocaluxe.Base
|
||||
_HighscoreDB.Close();
|
||||
_HighscoreDB = null;
|
||||
}
|
||||
|
||||
if (_CoverDB != null)
|
||||
{
|
||||
_CoverDB.Close();
|
||||
@@ -62,21 +65,22 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
}
|
||||
|
||||
public static bool GetDataBaseSongInfos(string artist, string title, out int numPlayed, out DateTime dateAdded, out int highscoreID)
|
||||
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;
|
||||
highscoreId = 0;
|
||||
return false;
|
||||
}
|
||||
return _HighscoreDB.GetDataBaseSongInfos(artist, title, out numPlayed, out dateAdded, out highscoreID);
|
||||
|
||||
return _HighscoreDB.GetDataBaseSongInfos(artist, title, out numPlayed, out dateAdded, out highscoreId);
|
||||
}
|
||||
|
||||
public static List<SDBScoreEntry> LoadScore(int songID, EGameMode gameMode, EHighscoreStyle style)
|
||||
public static List<SDBScoreEntry> LoadScore(int songId, EGameMode gameMode, EHighscoreStyle style)
|
||||
{
|
||||
return _HighscoreDB == null ? null : _HighscoreDB.LoadScore(songID, gameMode, style);
|
||||
return _HighscoreDB == null ? null : _HighscoreDB.LoadScore(songId, gameMode, style);
|
||||
}
|
||||
|
||||
public static int AddScore(SPlayer player)
|
||||
@@ -84,10 +88,12 @@ namespace Vocaluxe.Base
|
||||
return _HighscoreDB == null ? -1 : _HighscoreDB.AddScore(player);
|
||||
}
|
||||
|
||||
public static void IncreaseSongCounter(int dataBaseSongID)
|
||||
public static void IncreaseSongCounter(int dataBaseSongId)
|
||||
{
|
||||
if (_HighscoreDB != null)
|
||||
_HighscoreDB.IncreaseSongCounter(dataBaseSongID);
|
||||
{
|
||||
_HighscoreDB.IncreaseSongCounter(dataBaseSongId);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool GetCover(string fileName, ref CTextureRef tex, int maxSize)
|
||||
@@ -98,7 +104,9 @@ namespace Vocaluxe.Base
|
||||
public static void CommitCovers()
|
||||
{
|
||||
if (_CoverDB != null)
|
||||
{
|
||||
_CoverDB.CommitCovers();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+12
-2
@@ -35,7 +35,10 @@ namespace Vocaluxe.Base
|
||||
public static bool Init()
|
||||
{
|
||||
if (_Draw != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (CConfig.Config.Graphics.Renderer)
|
||||
{
|
||||
case ERenderer.TR_CONFIG_SOFTWARE:
|
||||
@@ -52,6 +55,7 @@ namespace Vocaluxe.Base
|
||||
CLog.Fatal(e, "Error in initializing of OpenGL. Please check whether your graphic card drivers are up to date.");
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
#if WIN
|
||||
@@ -66,6 +70,7 @@ namespace Vocaluxe.Base
|
||||
"download the DirectX runtimes at https://www.microsoft.com/en-us/download/details.aspx?id=8109");
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
#endif
|
||||
|
||||
@@ -73,6 +78,7 @@ namespace Vocaluxe.Base
|
||||
_Draw = new CDrawWinForm();
|
||||
break;
|
||||
}
|
||||
|
||||
return _Draw.Init();
|
||||
}
|
||||
|
||||
@@ -267,7 +273,9 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
// Disposed textures call this, possibly at program end!
|
||||
if (_Draw != null)
|
||||
{
|
||||
_Draw.RemoveTexture(ref texture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -383,9 +391,11 @@ namespace Vocaluxe.Base
|
||||
public static void DrawTexture(CTextureRef textureRef, SRectF bounds, EAspect aspect, SColorF color)
|
||||
{
|
||||
if (textureRef == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SRectF rect = CHelper.FitInBounds(bounds, textureRef.OrigAspect, aspect);
|
||||
var rect = CHelper.FitInBounds(bounds, textureRef.OrigAspect, aspect);
|
||||
DrawTexture(textureRef, rect, color, bounds);
|
||||
}
|
||||
|
||||
@@ -403,4 +413,4 @@ namespace Vocaluxe.Base
|
||||
_Draw.DrawTextureReflection(textureRef, rect, color, bounds, space, height, allMonitors);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+129
-60
@@ -38,12 +38,8 @@ namespace Vocaluxe.Base
|
||||
/// Last beat that has been evaluated
|
||||
/// </summary>
|
||||
private static int _LastEvalBeat;
|
||||
private static readonly Random _Rand = new Random();
|
||||
|
||||
public static Random Rand
|
||||
{
|
||||
get { return _Rand; }
|
||||
}
|
||||
public static Random Rand { get; } = new Random();
|
||||
|
||||
public static float GetBeatFromTime(float time, float bpm, float gap)
|
||||
{
|
||||
@@ -53,7 +49,9 @@ namespace Vocaluxe.Base
|
||||
public static float GetTimeFromBeats(float beats, float bpm)
|
||||
{
|
||||
if (bpm > 0f)
|
||||
{
|
||||
return beats / bpm * 60f;
|
||||
}
|
||||
|
||||
return 0f;
|
||||
}
|
||||
@@ -185,7 +183,9 @@ namespace Vocaluxe.Base
|
||||
set
|
||||
{
|
||||
if (value > 0 && value <= CSettings.MaxNumPlayer)
|
||||
{
|
||||
_NumPlayers = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +196,7 @@ namespace Vocaluxe.Base
|
||||
|
||||
public static void ResetPlayer()
|
||||
{
|
||||
for (int i = 0; i < Players.Length; i++)
|
||||
for (var i = 0; i < Players.Length; i++)
|
||||
{
|
||||
Players[i].Points = 0f;
|
||||
Players[i].PointsLineBonus = 0f;
|
||||
@@ -207,13 +207,14 @@ namespace Vocaluxe.Base
|
||||
Players[i].SungLines = new List<CSungLine>();
|
||||
Players[i].CurrentLine = -1;
|
||||
Players[i].CurrentNote = -1;
|
||||
Players[i].SongID = -1;
|
||||
Players[i].SongId = -1;
|
||||
Players[i].GameMode = EGameMode.TR_GAMEMODE_NORMAL;
|
||||
Players[i].DateTicks = DateTime.Now.Ticks;
|
||||
Players[i].SongFinished = false;
|
||||
Players[i].RatingLastLine = 0f;
|
||||
Players[i].TimeLastLineChange = float.MaxValue;
|
||||
}
|
||||
|
||||
_LastEvalBeat = -100;
|
||||
CurrentBeatF = -100;
|
||||
MidRecordedBeat = -100;
|
||||
@@ -221,37 +222,49 @@ namespace Vocaluxe.Base
|
||||
|
||||
public static void UpdatePoints(float time)
|
||||
{
|
||||
CSong song = _SongQueue.GetSong();
|
||||
var song = _SongQueue.GetSong();
|
||||
|
||||
if (song == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float b = GetBeatFromTime(time, song.BPM, song.Gap);
|
||||
var b = GetBeatFromTime(time, song.Bpm, song.Gap);
|
||||
if (b <= CurrentBeatF)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentBeatF = b;
|
||||
|
||||
MidRecordedBeat = -0.5f + GetBeatFromTime(time, song.BPM, song.Gap + CConfig.Config.Record.MicDelay / 1000f);
|
||||
MidRecordedBeat = -0.5f + GetBeatFromTime(time, song.Bpm, song.Gap + CConfig.Config.Record.MicDelay / 1000f);
|
||||
|
||||
for (int p = 0; p < _NumPlayers; p++)
|
||||
for (var p = 0; p < _NumPlayers; p++)
|
||||
{
|
||||
CRecord.AnalyzeBuffer(p);
|
||||
}
|
||||
|
||||
if (_LastEvalBeat >= RecordedBeat)
|
||||
return;
|
||||
|
||||
for (int p = 0; p < _NumPlayers; p++)
|
||||
{
|
||||
for (int beat = _LastEvalBeat + 1; beat <= RecordedBeat; beat++)
|
||||
return;
|
||||
}
|
||||
|
||||
for (var p = 0; p < _NumPlayers; p++)
|
||||
{
|
||||
for (var beat = _LastEvalBeat + 1; beat <= RecordedBeat; beat++)
|
||||
{
|
||||
if ((_SongQueue.GetCurrentGameMode() == EGameMode.TR_GAMEMODE_MEDLEY && song.Medley.EndBeat == beat) ||
|
||||
(_SongQueue.GetCurrentGameMode() == EGameMode.TR_GAMEMODE_SHORTSONG && song.ShortEnd.EndBeat == beat))
|
||||
{
|
||||
Players[p].SongFinished = true;
|
||||
}
|
||||
|
||||
CSongLine[] lines = song.Notes.GetVoice(Players[p].VoiceNr).Lines;
|
||||
int line = song.Notes.GetVoice(Players[p].VoiceNr).FindPreviousLine(beat);
|
||||
var lines = song.Notes.GetVoice(Players[p].VoiceNr).Lines;
|
||||
var line = song.Notes.GetVoice(Players[p].VoiceNr).FindPreviousLine(beat);
|
||||
if (line < 0 || lines[line].EndBeat < beat)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Players[p].CurrentLine != line && line > 0)
|
||||
{
|
||||
@@ -260,48 +273,59 @@ namespace Vocaluxe.Base
|
||||
|
||||
//Check for already sung
|
||||
if (line < Players[p].SungLines.Count - 1)
|
||||
{
|
||||
continue; // Already sung whole line
|
||||
}
|
||||
|
||||
if (line == Players[p].SungLines.Count - 1)
|
||||
{
|
||||
//We are in the last line
|
||||
if (beat <= Players[p].SungLines[line].LastNoteBeat)
|
||||
{
|
||||
continue; //We already have something that ends with/after that beat
|
||||
}
|
||||
}
|
||||
|
||||
if (line != Players[p].CurrentLine)
|
||||
{
|
||||
Players[p].CurrentNote = -1;
|
||||
}
|
||||
|
||||
Players[p].CurrentLine = line;
|
||||
|
||||
while (Players[p].SungLines.Count <= line)
|
||||
{
|
||||
Players[p].SungLines.Add(new CSungLine());
|
||||
}
|
||||
|
||||
CSongNote[] notes = lines[line].Notes;
|
||||
int note = lines[line].FindPreviousNote(beat);
|
||||
var notes = lines[line].Notes;
|
||||
var note = lines[line].FindPreviousNote(beat);
|
||||
if (note < 0 || notes[note].EndBeat < beat)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Players[p].CurrentNote = note;
|
||||
|
||||
if (line == lines.Length - 1 && beat == lines[line].LastNoteBeat)
|
||||
Players[p].SongFinished = true;
|
||||
|
||||
if (notes[note].PointsForBeat > 0 && (CRecord.ToneValid(p)
|
||||
#if DEBUG_HIT
|
||||
|| true
|
||||
#elif DEBUG_HIT_1
|
||||
|| (true && p == 0)
|
||||
#endif
|
||||
))
|
||||
{
|
||||
int tone = notes[note].Tone;
|
||||
int tonePlayer = CRecord.GetTone(p);
|
||||
Players[p].SongFinished = true;
|
||||
}
|
||||
|
||||
if (notes[note].PointsForBeat > 0 && CRecord.ToneValid(p))
|
||||
{
|
||||
var tone = notes[note].Tone;
|
||||
var tonePlayer = CRecord.GetTone(p);
|
||||
|
||||
while (tonePlayer - tone > 6)
|
||||
{
|
||||
tonePlayer -= 12;
|
||||
}
|
||||
|
||||
while (tonePlayer - tone < -6)
|
||||
{
|
||||
tonePlayer += 12;
|
||||
}
|
||||
|
||||
#if DEBUG_HIT
|
||||
tonePlayer = tone;
|
||||
@@ -310,29 +334,35 @@ namespace Vocaluxe.Base
|
||||
#endif
|
||||
|
||||
if (notes[note].Type == ENoteType.Rap || notes[note].Type == ENoteType.RapGolden)
|
||||
{
|
||||
tonePlayer = tone;
|
||||
}
|
||||
|
||||
Players[p].NoteDiff = Math.Abs(tone - tonePlayer);
|
||||
bool hit = Players[p].NoteDiff <= (2 - (int)CProfiles.GetDifficulty(Players[p].ProfileID));
|
||||
var hit = Players[p].NoteDiff <= 2 - (int)CProfiles.GetDifficulty(Players[p].ProfileId);
|
||||
|
||||
if (hit)
|
||||
{
|
||||
// valid
|
||||
//CRecord.RecordSetTone(p, Tone);
|
||||
double points = (CSettings.MaxScore - CSettings.LinebonusScore) * (double)notes[note].PointsForBeat /
|
||||
song.Notes.GetVoice(Players[p].VoiceNr).Points;
|
||||
var points = (CSettings.MaxScore - CSettings.LinebonusScore) * (double)notes[note].PointsForBeat /
|
||||
song.Notes.GetVoice(Players[p].VoiceNr).Points;
|
||||
if (notes[note].Type == ENoteType.Golden || notes[note].Type == ENoteType.RapGolden)
|
||||
{
|
||||
Players[p].PointsGoldenNotes += points;
|
||||
}
|
||||
|
||||
Players[p].Points += points;
|
||||
|
||||
// update player notes (sung notes)
|
||||
if (Players[p].SungLines[line].NoteCount > 0)
|
||||
{
|
||||
CSungNote lastNote = Players[p].SungLines[line].LastNote;
|
||||
var lastNote = Players[p].SungLines[line].LastNote;
|
||||
|
||||
if (notes[note].StartBeat == beat || lastNote.EndBeat + 1 != beat || lastNote.Tone != tone || !lastNote.Hit)
|
||||
{
|
||||
Players[p].SungLines[line].AddNote(new CSungNote(beat, 1, tone, notes[note], points));
|
||||
}
|
||||
else
|
||||
{
|
||||
Players[p].SungLines[line].IncLastNoteLength();
|
||||
@@ -340,7 +370,9 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Players[p].SungLines[line].AddNote(new CSungNote(beat, 1, tone, notes[note], points));
|
||||
}
|
||||
|
||||
Players[p].SungLines[line].LastNote.CheckPerfect();
|
||||
Players[p].SungLines[line].IsPerfect(lines[line]);
|
||||
@@ -349,27 +381,37 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
if (Players[p].SungLines[line].NoteCount > 0)
|
||||
{
|
||||
CSungNote lastNote = Players[p].SungLines[line].LastNote;
|
||||
var lastNote = Players[p].SungLines[line].LastNote;
|
||||
if (lastNote.Tone != tonePlayer || lastNote.EndBeat + 1 != beat || lastNote.Hit)
|
||||
{
|
||||
Players[p].SungLines[line].AddNote(new CSungNote(beat, 1, tonePlayer));
|
||||
}
|
||||
else
|
||||
{
|
||||
Players[p].SungLines[line].IncLastNoteLength();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Players[p].SungLines[line].AddNote(new CSungNote(beat, 1, tonePlayer));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if line ended
|
||||
int numLinesWithPoints = song.Notes.GetNumLinesWithPoints(Players[p].VoiceNr);
|
||||
var numLinesWithPoints = song.Notes.GetNumLinesWithPoints(Players[p].VoiceNr);
|
||||
if (beat == lines[line].LastNoteBeat && lines[line].Points > 0 && numLinesWithPoints > 0)
|
||||
{
|
||||
// Line Bonus
|
||||
double factor = Players[p].SungLines[line].Points / (double)lines[line].Points;
|
||||
var factor = Players[p].SungLines[line].Points / (double)lines[line].Points;
|
||||
if (factor <= 0.4)
|
||||
{
|
||||
factor = 0.0;
|
||||
}
|
||||
else if (factor >= 0.9)
|
||||
{
|
||||
factor = 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
factor -= 0.4;
|
||||
@@ -377,71 +419,88 @@ namespace Vocaluxe.Base
|
||||
factor *= factor;
|
||||
}
|
||||
|
||||
double points = CSettings.LinebonusScore * factor / numLinesWithPoints;
|
||||
var points = CSettings.LinebonusScore * factor / numLinesWithPoints;
|
||||
Players[p].Points += points;
|
||||
Players[p].PointsLineBonus += points;
|
||||
Players[p].SungLines[line].BonusPoints += points;
|
||||
|
||||
//Calculate rating
|
||||
//Shift fraction of correct sung notes to [-0.1, 0.1], player needs to sing five lines fully correctly to get highest ranking
|
||||
double current = Players[p].SungLines[line].Points / (double)lines[line].Points;
|
||||
var current = Players[p].SungLines[line].Points / (double)lines[line].Points;
|
||||
Players[p].Rating = (Players[p].Rating + (current * 0.2 - 0.1)).Clamp(0, 1);
|
||||
Players[p].RatingLastLine = current;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_LastEvalBeat = RecordedBeat;
|
||||
}
|
||||
|
||||
public static void ResetToLastLine(int soundStream, CVideoStream vidStream)
|
||||
{
|
||||
float[] time = _GetLastSungLineStart();
|
||||
var time = _GetLastSungLineStart();
|
||||
ResetToTime(time[0], time[1], soundStream, vidStream);
|
||||
}
|
||||
|
||||
public static void ResetToTime(float time, float nextStart, int soundStream, CVideoStream vidStream)
|
||||
{
|
||||
if (time < 0)
|
||||
{
|
||||
time = 0;
|
||||
}
|
||||
|
||||
CurrentBeatF = GetBeatFromTime(time, GetSong().BPM, GetSong().Gap);
|
||||
CurrentBeatF = GetBeatFromTime(time, GetSong().Bpm, GetSong().Gap);
|
||||
|
||||
for (int p = 0; p < _NumPlayers; p++)
|
||||
for (var p = 0; p < _NumPlayers; p++)
|
||||
{
|
||||
Players[p].Points = 0;
|
||||
Players[p].PointsGoldenNotes = 0;
|
||||
Players[p].PointsLineBonus = 0;
|
||||
int l = 0;
|
||||
int deleteLine = 0;
|
||||
foreach (CSungLine line in Players[p].SungLines)
|
||||
var l = 0;
|
||||
var deleteLine = 0;
|
||||
foreach (var line in Players[p].SungLines)
|
||||
{
|
||||
int n = -1;
|
||||
int deleteNote = 0;
|
||||
var n = -1;
|
||||
var deleteNote = 0;
|
||||
Players[p].PointsLineBonus += line.BonusPoints;
|
||||
foreach (CSungNote note in line.Notes)
|
||||
foreach (var note in line.Notes)
|
||||
{
|
||||
if (note.StartBeat < nextStart)
|
||||
{
|
||||
if (note.Hit && (note.HitNote.Type == ENoteType.Golden || note.HitNote.Type == ENoteType.RapGolden))
|
||||
{
|
||||
Players[p].PointsGoldenNotes += note.Points;
|
||||
}
|
||||
|
||||
Players[p].Points += note.Points;
|
||||
}
|
||||
else if (deleteNote != -1)
|
||||
{
|
||||
deleteNote = n;
|
||||
}
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
while (line.NoteCount > n && n >= 0)
|
||||
{
|
||||
if (line.Notes[n].Hit && (line.Notes[n].HitNote.Type == ENoteType.Golden || line.Notes[n].HitNote.Type == ENoteType.RapGolden))
|
||||
{
|
||||
Players[p].PointsGoldenNotes -= line.Notes[n].Points;
|
||||
}
|
||||
|
||||
Players[p].Points -= line.Notes[n].Points;
|
||||
line.DeleteNote(n);
|
||||
}
|
||||
|
||||
if (line.LastNoteBeat > CurrentBeat && deleteLine == 0)
|
||||
{
|
||||
deleteLine = l;
|
||||
}
|
||||
|
||||
l++;
|
||||
}
|
||||
|
||||
Players[p].SungLines.RemoveRange(deleteLine, Players[p].SungLines.Count - deleteLine);
|
||||
}
|
||||
|
||||
@@ -456,34 +515,44 @@ namespace Vocaluxe.Base
|
||||
|
||||
private static float[] _GetNoteTimeBeforeBeat(int beat)
|
||||
{
|
||||
CSong song = GetSong();
|
||||
int startBeat = (int)Math.Floor(beat - GetBeatFromTime(CSettings.PauseResetTime, song.BPM, 0f));
|
||||
int lastStart = 0;
|
||||
int nextStart = 0;
|
||||
foreach (CVoice voice in song.Notes.Voices)
|
||||
var song = GetSong();
|
||||
var startBeat = (int)Math.Floor(beat - GetBeatFromTime(CSettings.PauseResetTime, song.Bpm, 0f));
|
||||
var lastStart = 0;
|
||||
var nextStart = 0;
|
||||
foreach (var voice in song.Notes.Voices)
|
||||
{
|
||||
int lastEnd = 0;
|
||||
int voiceStart = 0;
|
||||
int nextStartNote = 0;
|
||||
foreach (CSongLine line in voice.Lines)
|
||||
var lastEnd = 0;
|
||||
var voiceStart = 0;
|
||||
var nextStartNote = 0;
|
||||
foreach (var line in voice.Lines)
|
||||
{
|
||||
foreach (CSongNote note in line.Notes)
|
||||
foreach (var note in line.Notes)
|
||||
{
|
||||
if (note.StartBeat > startBeat)
|
||||
{
|
||||
nextStartNote = note.StartBeat;
|
||||
break;
|
||||
}
|
||||
|
||||
voiceStart = note.StartBeat;
|
||||
lastEnd = note.EndBeat;
|
||||
}
|
||||
|
||||
if (nextStartNote > 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nextStartNote - beat > CSettings.PauseResetTime)
|
||||
{
|
||||
lastStart = beat;
|
||||
}
|
||||
else if (nextStartNote - lastEnd > CSettings.PauseResetTime)
|
||||
lastStart = nextStartNote - (int)Math.Floor(GetBeatFromTime(CSettings.PauseResetTime, song.BPM, 0f));
|
||||
{
|
||||
lastStart = nextStartNote - (int)Math.Floor(GetBeatFromTime(CSettings.PauseResetTime, song.Bpm, 0f));
|
||||
}
|
||||
|
||||
if (voiceStart > lastStart)
|
||||
{
|
||||
lastStart = voiceStart;
|
||||
@@ -491,7 +560,7 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
}
|
||||
|
||||
return new float[] {GetTimeFromBeats(lastStart, GetSong().BPM), nextStart};
|
||||
return new float[] { GetTimeFromBeats(lastStart, GetSong().Bpm), nextStart };
|
||||
}
|
||||
}
|
||||
}
|
||||
+196
-56
@@ -53,7 +53,7 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
get
|
||||
{
|
||||
int id = _Screens.IndexOf(NextScreen);
|
||||
var id = _Screens.IndexOf(NextScreen);
|
||||
return (EScreen)id;
|
||||
}
|
||||
}
|
||||
@@ -92,6 +92,7 @@ namespace Vocaluxe.Base
|
||||
_PopupScreens.Add(new CPopupScreenVolumeControl());
|
||||
_PopupScreens.Add(new CPopupScreenServerQR());
|
||||
}
|
||||
|
||||
CurrentScreen = _Screens[(int)EScreen.Load];
|
||||
NextScreen = null;
|
||||
_CurrentPopupScreen = EPopupScreens.NoPopup;
|
||||
@@ -109,39 +110,48 @@ namespace Vocaluxe.Base
|
||||
public static void Close()
|
||||
{
|
||||
if (_CurrentPopupScreen != EPopupScreens.NoPopup && _PopupScreens.Count > 0)
|
||||
{
|
||||
_PopupScreens[(int)_CurrentPopupScreen].OnClose();
|
||||
}
|
||||
|
||||
if (CurrentScreen != null)
|
||||
{
|
||||
CurrentScreen.OnClose();
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadTheme()
|
||||
{
|
||||
_Cursor.LoadSkin();
|
||||
|
||||
for (int i = 0; i < _Screens.Count; i++)
|
||||
for (var i = 0; i < _Screens.Count; i++)
|
||||
{
|
||||
using (CBenchmark.Time("Load Theme " + Enum.GetNames(typeof(EScreen))[i]))
|
||||
{
|
||||
_Screens[i].Init();
|
||||
_Screens[i].LoadTheme(CThemes.GetThemeScreensPath(_Screens[i].PartyModeID));
|
||||
_Screens[i].LoadTheme(CThemes.GetThemeScreensPath(_Screens[i].PartyModeId));
|
||||
}
|
||||
}
|
||||
|
||||
foreach (IMenu popup in _PopupScreens)
|
||||
foreach (var popup in _PopupScreens)
|
||||
{
|
||||
popup.Init();
|
||||
popup.LoadTheme(CThemes.GetThemeScreensPath(popup.PartyModeID));
|
||||
popup.LoadTheme(CThemes.GetThemeScreensPath(popup.PartyModeId));
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReloadTheme()
|
||||
{
|
||||
_Cursor.ReloadSkin();
|
||||
foreach (IMenu screen in _Screens)
|
||||
screen.ReloadTheme(CThemes.GetThemeScreensPath(screen.PartyModeID));
|
||||
foreach (var screen in _Screens)
|
||||
{
|
||||
screen.ReloadTheme(CThemes.GetThemeScreensPath(screen.PartyModeId));
|
||||
}
|
||||
|
||||
foreach (IMenu popup in _PopupScreens)
|
||||
popup.ReloadTheme(CThemes.GetThemeScreensPath(popup.PartyModeID));
|
||||
foreach (var popup in _PopupScreens)
|
||||
{
|
||||
popup.ReloadTheme(CThemes.GetThemeScreensPath(popup.PartyModeId));
|
||||
}
|
||||
|
||||
CParty.ReloadTheme();
|
||||
}
|
||||
@@ -149,11 +159,15 @@ namespace Vocaluxe.Base
|
||||
public static void ReloadSkin()
|
||||
{
|
||||
_Cursor.ReloadSkin();
|
||||
foreach (IMenu menu in _Screens)
|
||||
foreach (var menu in _Screens)
|
||||
{
|
||||
menu.ReloadSkin();
|
||||
}
|
||||
|
||||
foreach (IMenu menu in _PopupScreens)
|
||||
foreach (var menu in _PopupScreens)
|
||||
{
|
||||
menu.ReloadSkin();
|
||||
}
|
||||
|
||||
CParty.ReloadSkin();
|
||||
}
|
||||
@@ -163,13 +177,17 @@ namespace Vocaluxe.Base
|
||||
foreach (CMenu screen in _Screens)
|
||||
{
|
||||
if (screen.ThemePath == null || screen.ThemeName == "ScreenTest")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
screen.SaveTheme();
|
||||
}
|
||||
|
||||
foreach (IMenu popup in _PopupScreens)
|
||||
foreach (var popup in _PopupScreens)
|
||||
{
|
||||
popup.SaveTheme();
|
||||
}
|
||||
|
||||
CParty.SaveThemes();
|
||||
}
|
||||
@@ -182,7 +200,7 @@ namespace Vocaluxe.Base
|
||||
|
||||
public static bool UpdateGameLogic(CKeys keys, CMouse mouse)
|
||||
{
|
||||
bool run = true;
|
||||
var run = true;
|
||||
_Cursor.Visible = mouse.Visible;
|
||||
|
||||
mouse.CopyEvents();
|
||||
@@ -215,27 +233,35 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
_Fading = new CFading(0f, 1f, CConfig.Config.Graphics.FadeTime);
|
||||
|
||||
if (NextScreen.PartyModeID != -1)
|
||||
if (NextScreen.PartyModeId != -1)
|
||||
{
|
||||
CFonts.PartyModeID = NextScreen.PartyModeID;
|
||||
CFonts.PartyModeId = NextScreen.PartyModeId;
|
||||
NextScreen.OnShow();
|
||||
CFonts.PartyModeID = -1;
|
||||
CFonts.PartyModeId = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
NextScreen.OnShow();
|
||||
}
|
||||
|
||||
if (_Cursor.IsActive)
|
||||
{
|
||||
NextScreen.ProcessMouseMove(_Cursor.X, _Cursor.Y);
|
||||
}
|
||||
|
||||
HidePopup(EPopupScreens.PopupPlayerControl);
|
||||
if (NextScreen.CurrentMusicType != EMusicType.Background && NextScreen.CurrentMusicType != EMusicType.Preview && NextScreen.CurrentMusicType != EMusicType.BackgroundPreview)
|
||||
if (NextScreen.CurrentMusicType != EMusicType.Background && NextScreen.CurrentMusicType != EMusicType.Preview &&
|
||||
NextScreen.CurrentMusicType != EMusicType.BackgroundPreview)
|
||||
{
|
||||
CBackgroundMusic.Disabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (_Fading != null)
|
||||
{
|
||||
Debug.Assert(NextScreen != null);
|
||||
bool finished;
|
||||
float newAlpha = _Fading.GetValue(out finished);
|
||||
var newAlpha = _Fading.GetValue(out finished);
|
||||
|
||||
if (!finished)
|
||||
{
|
||||
@@ -247,24 +273,30 @@ namespace Vocaluxe.Base
|
||||
_DrawScreen(NextScreen);
|
||||
|
||||
GlobalAlpha = 1f;
|
||||
int oldVol = CConfig.GetVolumeByType(CurrentScreen.CurrentMusicType);
|
||||
int newVol = CConfig.GetVolumeByType(NextScreen.CurrentMusicType);
|
||||
var oldVol = CConfig.GetVolumeByType(CurrentScreen.CurrentMusicType);
|
||||
var newVol = CConfig.GetVolumeByType(NextScreen.CurrentMusicType);
|
||||
CSound.SetGlobalVolume((int)((newVol - oldVol) * newAlpha + oldVol));
|
||||
}
|
||||
else
|
||||
{
|
||||
_FinishScreenFading();
|
||||
if (_Cursor.IsActive)
|
||||
{
|
||||
CurrentScreen.ProcessMouseMove(_Cursor.X, _Cursor.Y);
|
||||
}
|
||||
|
||||
_DrawScreen(CurrentScreen);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_DrawScreen(CurrentScreen);
|
||||
}
|
||||
|
||||
foreach (IMenu popup in _PopupScreens)
|
||||
foreach (var popup in _PopupScreens)
|
||||
{
|
||||
popup.Draw();
|
||||
}
|
||||
|
||||
_Cursor.Draw();
|
||||
_DrawDebugInfos();
|
||||
@@ -275,37 +307,47 @@ namespace Vocaluxe.Base
|
||||
private static void _FinishScreenFading()
|
||||
{
|
||||
if (_Fading == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Assert(NextScreen != null);
|
||||
CurrentScreen.OnClose();
|
||||
CurrentScreen = NextScreen;
|
||||
NextScreen = null;
|
||||
CurrentScreen.OnShowFinish();
|
||||
CSound.SetGlobalVolume(CConfig.GetVolumeByType(CurrentScreen.CurrentMusicType));
|
||||
if (CurrentScreen.CurrentMusicType == EMusicType.Background || CurrentScreen.CurrentMusicType == EMusicType.Preview || CurrentScreen.CurrentMusicType == EMusicType.BackgroundPreview)
|
||||
if (CurrentScreen.CurrentMusicType == EMusicType.Background || CurrentScreen.CurrentMusicType == EMusicType.Preview ||
|
||||
CurrentScreen.CurrentMusicType == EMusicType.BackgroundPreview)
|
||||
{
|
||||
CBackgroundMusic.Disabled = false;
|
||||
CBackgroundMusic.IsPlayingPreview = CurrentScreen.CurrentMusicType == EMusicType.Preview || CurrentScreen.CurrentMusicType == EMusicType.BackgroundPreview;
|
||||
}
|
||||
|
||||
_Fading = null;
|
||||
}
|
||||
|
||||
private static void _DrawScreen(IMenu screen)
|
||||
{
|
||||
if (screen.PartyModeID != -1)
|
||||
if (screen.PartyModeId != -1)
|
||||
{
|
||||
CFonts.PartyModeID = screen.PartyModeID;
|
||||
CFonts.PartyModeId = screen.PartyModeId;
|
||||
screen.Draw();
|
||||
CFonts.PartyModeID = -1;
|
||||
CFonts.PartyModeId = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
screen.Draw();
|
||||
}
|
||||
}
|
||||
|
||||
public static IMenu GetScreen(EScreen screen)
|
||||
{
|
||||
if (screen == EScreen.Unknown || screen == EScreen.CountEntry)
|
||||
{
|
||||
throw new ArgumentException("Invalid screen: " + screen);
|
||||
}
|
||||
|
||||
return _Screens[(int)screen];
|
||||
}
|
||||
|
||||
@@ -317,10 +359,16 @@ namespace Vocaluxe.Base
|
||||
public static void FadeTo(IMenu screen)
|
||||
{
|
||||
if (screen == null)
|
||||
{
|
||||
throw new ArgumentNullException("screen");
|
||||
}
|
||||
|
||||
Debug.Assert(NextScreen == null || NextScreen != screen, "Don't fade to currently fading screen!");
|
||||
if (screen == NextScreen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure the last screen change is done
|
||||
_FinishScreenFading();
|
||||
NextScreen = screen;
|
||||
@@ -336,7 +384,9 @@ namespace Vocaluxe.Base
|
||||
public static void HidePopup(EPopupScreens popupScreen)
|
||||
{
|
||||
if (_CurrentPopupScreen != popupScreen)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_PopupScreens[(int)popupScreen].OnClose();
|
||||
_CurrentPopupScreen = EPopupScreens.NoPopup;
|
||||
@@ -356,25 +406,30 @@ namespace Vocaluxe.Base
|
||||
#region private stuff
|
||||
private static bool _HandleInputs(CKeys keys, CMouse mouse)
|
||||
{
|
||||
SKeyEvent keyEvent = new SKeyEvent();
|
||||
SMouseEvent mouseEvent = new SMouseEvent();
|
||||
SKeyEvent inputKeyEvent = new SKeyEvent();
|
||||
SMouseEvent inputMouseEvent = new SMouseEvent();
|
||||
var keyEvent = new SKeyEvent();
|
||||
var mouseEvent = new SMouseEvent();
|
||||
var inputKeyEvent = new SKeyEvent();
|
||||
var inputMouseEvent = new SMouseEvent();
|
||||
|
||||
bool popupPlayerControlAllowed = CurrentScreen.CurrentMusicType == EMusicType.Background;
|
||||
bool popupVolumeControlAllowed = CurrentScreen.CurrentMusicType != EMusicType.None;
|
||||
var popupPlayerControlAllowed = CurrentScreen.CurrentMusicType == EMusicType.Background;
|
||||
var popupVolumeControlAllowed = CurrentScreen.CurrentMusicType != EMusicType.None;
|
||||
//Hide volume control for bg-music if bg-music is disabled
|
||||
if (popupVolumeControlAllowed && (CurrentScreen.CurrentMusicType == EMusicType.Background || CurrentScreen.CurrentMusicType == EMusicType.BackgroundPreview) && CConfig.Config.Sound.BackgroundMusic == EBackgroundMusicOffOn.TR_CONFIG_OFF)
|
||||
if (popupVolumeControlAllowed && (CurrentScreen.CurrentMusicType == EMusicType.Background || CurrentScreen.CurrentMusicType == EMusicType.BackgroundPreview) &&
|
||||
CConfig.Config.Sound.BackgroundMusic == EBackgroundMusicOffOn.TR_CONFIG_OFF)
|
||||
{
|
||||
popupVolumeControlAllowed = false;
|
||||
}
|
||||
|
||||
bool resume = true;
|
||||
var resume = true;
|
||||
bool eventsAvailable;
|
||||
bool inputEventsAvailable = CController.PollKeyEvent(ref inputKeyEvent);
|
||||
var inputEventsAvailable = CController.PollKeyEvent(ref inputKeyEvent);
|
||||
|
||||
while ((eventsAvailable = keys.PollEvent(ref keyEvent)) || inputEventsAvailable)
|
||||
{
|
||||
if (!eventsAvailable)
|
||||
{
|
||||
keyEvent = inputKeyEvent;
|
||||
}
|
||||
|
||||
if (keyEvent.IsArrowKey() || keyEvent.Key == Keys.NumPad0 || keyEvent.Key == Keys.D0 || keyEvent.Key == Keys.Add)
|
||||
{
|
||||
@@ -386,27 +441,47 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
case Keys.Right:
|
||||
if (keyEvent.ModShift)
|
||||
{
|
||||
CConfig.Config.Graphics.BorderLeft++;
|
||||
}
|
||||
else
|
||||
{
|
||||
CConfig.Config.Graphics.BorderRight--;
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.Left:
|
||||
if (keyEvent.ModShift)
|
||||
{
|
||||
CConfig.Config.Graphics.BorderLeft--;
|
||||
}
|
||||
else
|
||||
{
|
||||
CConfig.Config.Graphics.BorderRight++;
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.Down:
|
||||
if (keyEvent.ModShift)
|
||||
{
|
||||
CConfig.Config.Graphics.BorderTop++;
|
||||
}
|
||||
else
|
||||
{
|
||||
CConfig.Config.Graphics.BorderBottom--;
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.Up:
|
||||
if (keyEvent.ModShift)
|
||||
{
|
||||
CConfig.Config.Graphics.BorderTop--;
|
||||
}
|
||||
else
|
||||
{
|
||||
CConfig.Config.Graphics.BorderBottom++;
|
||||
}
|
||||
|
||||
break;
|
||||
case Keys.D0:
|
||||
case Keys.NumPad0:
|
||||
@@ -426,8 +501,10 @@ namespace Vocaluxe.Base
|
||||
CConfig.Config.Graphics.ScreenAlignment = EGeneralAlignment.Middle;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
CConfig.SaveConfig();
|
||||
break;
|
||||
}
|
||||
@@ -436,9 +513,13 @@ namespace Vocaluxe.Base
|
||||
if (keyEvent.Key == Keys.F11)
|
||||
{
|
||||
if (_CurrentPopupScreen == EPopupScreens.NoPopup)
|
||||
{
|
||||
ShowPopup(EPopupScreens.PopupServerQR);
|
||||
}
|
||||
else
|
||||
{
|
||||
HidePopup(EPopupScreens.PopupServerQR);
|
||||
}
|
||||
}
|
||||
|
||||
if (keyEvent.Key == Keys.F8)
|
||||
@@ -449,42 +530,62 @@ namespace Vocaluxe.Base
|
||||
if (popupPlayerControlAllowed && keyEvent.Key == Keys.Tab)
|
||||
{
|
||||
if (_CurrentPopupScreen == EPopupScreens.NoPopup && CConfig.Config.Sound.BackgroundMusic == EBackgroundMusicOffOn.TR_CONFIG_ON)
|
||||
{
|
||||
ShowPopup(EPopupScreens.PopupPlayerControl);
|
||||
}
|
||||
else
|
||||
{
|
||||
HidePopup(EPopupScreens.PopupPlayerControl);
|
||||
}
|
||||
}
|
||||
|
||||
if (popupPlayerControlAllowed && CConfig.Config.Sound.BackgroundMusic != EBackgroundMusicOffOn.TR_CONFIG_OFF)
|
||||
{
|
||||
if (keyEvent.Key == Keys.MediaNextTrack)
|
||||
{
|
||||
CBackgroundMusic.Next();
|
||||
}
|
||||
else if (keyEvent.Key == Keys.MediaPreviousTrack)
|
||||
{
|
||||
CBackgroundMusic.Previous();
|
||||
}
|
||||
else if (keyEvent.Key == Keys.MediaPlayPause)
|
||||
{
|
||||
if (CBackgroundMusic.IsPlaying)
|
||||
{
|
||||
CBackgroundMusic.Pause();
|
||||
}
|
||||
else
|
||||
{
|
||||
CBackgroundMusic.Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (keyEvent.ModShift && (keyEvent.Key == Keys.F1))
|
||||
if (keyEvent.ModShift && keyEvent.Key == Keys.F1)
|
||||
{
|
||||
CSettings.ProgramState = EProgramState.EditTheme;
|
||||
else if (keyEvent.ModAlt && (keyEvent.Key == Keys.Enter))
|
||||
CConfig.Config.Graphics.FullScreen = (CConfig.Config.Graphics.FullScreen == EOffOn.TR_CONFIG_ON) ? EOffOn.TR_CONFIG_OFF : EOffOn.TR_CONFIG_ON;
|
||||
else if (keyEvent.ModAlt && (keyEvent.Key == Keys.P))
|
||||
}
|
||||
else if (keyEvent.ModAlt && keyEvent.Key == Keys.Enter)
|
||||
{
|
||||
CConfig.Config.Graphics.FullScreen = CConfig.Config.Graphics.FullScreen == EOffOn.TR_CONFIG_ON ? EOffOn.TR_CONFIG_OFF : EOffOn.TR_CONFIG_ON;
|
||||
}
|
||||
else if (keyEvent.ModAlt && keyEvent.Key == Keys.P)
|
||||
{
|
||||
CDraw.MakeScreenShot();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_Fading == null)
|
||||
{
|
||||
bool handled = false;
|
||||
var handled = false;
|
||||
if (_CurrentPopupScreen != EPopupScreens.NoPopup)
|
||||
{
|
||||
handled = _PopupScreens[(int)_CurrentPopupScreen].HandleInput(keyEvent);
|
||||
if (popupVolumeControlAllowed && _CurrentPopupScreen == EPopupScreens.PopupVolumeControl && handled)
|
||||
{
|
||||
_VolumePopupTimer.Restart();
|
||||
}
|
||||
}
|
||||
else if (popupVolumeControlAllowed && _PopupScreens[(int)EPopupScreens.PopupVolumeControl].HandleInput(keyEvent))
|
||||
{
|
||||
@@ -493,12 +594,16 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
{
|
||||
resume &= CurrentScreen.HandleInput(keyEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!eventsAvailable)
|
||||
{
|
||||
inputEventsAvailable = CController.PollKeyEvent(ref inputKeyEvent);
|
||||
}
|
||||
}
|
||||
|
||||
inputEventsAvailable = CController.PollMouseEvent(ref inputMouseEvent);
|
||||
@@ -506,24 +611,32 @@ namespace Vocaluxe.Base
|
||||
while ((eventsAvailable = mouse.PollEvent(ref mouseEvent)) || inputEventsAvailable)
|
||||
{
|
||||
if (!eventsAvailable)
|
||||
{
|
||||
mouseEvent = inputMouseEvent;
|
||||
}
|
||||
|
||||
if (mouseEvent.Wheel != 0)
|
||||
{
|
||||
_Cursor.Activate();
|
||||
}
|
||||
|
||||
_UpdateMousePosition(mouseEvent.X, mouseEvent.Y);
|
||||
|
||||
bool isOverPopupPlayerControl = CHelper.IsInBounds(_PopupScreens[(int)EPopupScreens.PopupPlayerControl].ScreenArea, mouseEvent);
|
||||
var isOverPopupPlayerControl = CHelper.IsInBounds(_PopupScreens[(int)EPopupScreens.PopupPlayerControl].ScreenArea, mouseEvent);
|
||||
if (popupPlayerControlAllowed && isOverPopupPlayerControl)
|
||||
{
|
||||
if (_CurrentPopupScreen == EPopupScreens.NoPopup && CConfig.Config.Sound.BackgroundMusic == EBackgroundMusicOffOn.TR_CONFIG_ON)
|
||||
{
|
||||
ShowPopup(EPopupScreens.PopupPlayerControl);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isOverPopupPlayerControl && _CurrentPopupScreen == EPopupScreens.PopupPlayerControl)
|
||||
{
|
||||
HidePopup(EPopupScreens.PopupPlayerControl);
|
||||
}
|
||||
|
||||
bool isOverPopupVolumeControl = CHelper.IsInBounds(_PopupScreens[(int)EPopupScreens.PopupVolumeControl].ScreenArea, mouseEvent);
|
||||
var isOverPopupVolumeControl = CHelper.IsInBounds(_PopupScreens[(int)EPopupScreens.PopupVolumeControl].ScreenArea, mouseEvent);
|
||||
if (popupVolumeControlAllowed && isOverPopupVolumeControl)
|
||||
{
|
||||
if (_CurrentPopupScreen == EPopupScreens.NoPopup)
|
||||
@@ -542,52 +655,69 @@ namespace Vocaluxe.Base
|
||||
_VolumePopupTimer.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
_CursorOverVolumeControl = isOverPopupVolumeControl;
|
||||
|
||||
|
||||
bool handled = false;
|
||||
var handled = false;
|
||||
if (_CurrentPopupScreen != EPopupScreens.NoPopup)
|
||||
{
|
||||
handled = _PopupScreens[(int)_CurrentPopupScreen].HandleMouse(mouseEvent);
|
||||
}
|
||||
|
||||
if (!handled && _Fading == null && (_Cursor.IsActive || mouseEvent.LB || mouseEvent.RB || mouseEvent.MB))
|
||||
{
|
||||
resume &= CurrentScreen.HandleMouse(mouseEvent);
|
||||
}
|
||||
|
||||
if (!eventsAvailable)
|
||||
{
|
||||
inputEventsAvailable = CController.PollMouseEvent(ref inputMouseEvent);
|
||||
}
|
||||
}
|
||||
|
||||
return resume;
|
||||
}
|
||||
|
||||
private static bool _HandleInputThemeEditor(CKeys keys, CMouse mouse)
|
||||
{
|
||||
SKeyEvent keyEvent = new SKeyEvent();
|
||||
SMouseEvent mouseEvent = new SMouseEvent();
|
||||
var keyEvent = new SKeyEvent();
|
||||
var mouseEvent = new SMouseEvent();
|
||||
|
||||
while (keys.PollEvent(ref keyEvent))
|
||||
{
|
||||
if (keyEvent.ModShift && (keyEvent.Key == Keys.F1))
|
||||
if (keyEvent.ModShift && keyEvent.Key == Keys.F1)
|
||||
{
|
||||
CSettings.ProgramState = EProgramState.Normal;
|
||||
CurrentScreen.NextElement();
|
||||
}
|
||||
else if (keyEvent.ModAlt && (keyEvent.Key == Keys.Enter))
|
||||
CConfig.Config.Graphics.FullScreen = (CConfig.Config.Graphics.FullScreen == EOffOn.TR_CONFIG_ON) ? EOffOn.TR_CONFIG_OFF : EOffOn.TR_CONFIG_ON;
|
||||
else if (keyEvent.ModAlt && (keyEvent.Key == Keys.P))
|
||||
else if (keyEvent.ModAlt && keyEvent.Key == Keys.Enter)
|
||||
{
|
||||
CConfig.Config.Graphics.FullScreen = CConfig.Config.Graphics.FullScreen == EOffOn.TR_CONFIG_ON ? EOffOn.TR_CONFIG_OFF : EOffOn.TR_CONFIG_ON;
|
||||
}
|
||||
else if (keyEvent.ModAlt && keyEvent.Key == Keys.P)
|
||||
{
|
||||
CDraw.MakeScreenShot();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_Fading == null)
|
||||
{
|
||||
CurrentScreen.HandleInputThemeEditor(keyEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (mouse.PollEvent(ref mouseEvent))
|
||||
{
|
||||
if (_Fading == null)
|
||||
{
|
||||
CurrentScreen.HandleMouseThemeEditor(mouseEvent);
|
||||
}
|
||||
|
||||
_UpdateMousePosition(mouseEvent.X, mouseEvent.Y);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -605,26 +735,33 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
|
||||
if (_VolumePopupTimer.IsRunning)
|
||||
{
|
||||
_Cursor.Activate();
|
||||
}
|
||||
|
||||
if (_CurrentPopupScreen != EPopupScreens.NoPopup)
|
||||
{
|
||||
_PopupScreens[(int)_CurrentPopupScreen].UpdateGame();
|
||||
}
|
||||
|
||||
return CurrentScreen.UpdateGame();
|
||||
}
|
||||
|
||||
private static void _DrawDebugInfos()
|
||||
{
|
||||
if (CConfig.Config.Debug.DebugLevel == EDebugLevel.TR_CONFIG_OFF)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> debugOutput = new List<string> {CTime.GetFPS().ToString("FPS: 000")};
|
||||
var debugOutput = new List<string> { CTime.GetFPS().ToString("FPS: 000") };
|
||||
|
||||
if (CConfig.Config.Debug.DebugLevel >= EDebugLevel.TR_CONFIG_LEVEL1)
|
||||
{
|
||||
debugOutput.Add(CSound.GetStreamCount().ToString(CLanguage.Translate("TR_DEBUG_AUDIO_STREAMS") + ": 00"));
|
||||
debugOutput.Add(CVideo.GetNumStreams().ToString(CLanguage.Translate("TR_DEBUG_VIDEO_STREAMS") + ": 00"));
|
||||
debugOutput.Add(CDraw.TextureCount().ToString(CLanguage.Translate("TR_DEBUG_TEXTURES") + ": 00000"));
|
||||
long memory = GC.GetTotalMemory(false);
|
||||
var memory = GC.GetTotalMemory(false);
|
||||
debugOutput.Add((memory / 1000000L).ToString(CLanguage.Translate("TR_DEBUG_MEMORY") + ": 00000 MB"));
|
||||
|
||||
if (CConfig.Config.Debug.DebugLevel >= EDebugLevel.TR_CONFIG_LEVEL2)
|
||||
@@ -639,17 +776,20 @@ namespace Vocaluxe.Base
|
||||
debugOutput.Add(CSongs.NumSongsWithCoverLoaded.ToString(CLanguage.Translate("TR_DEBUG_SONGS") + ": 00000"));
|
||||
|
||||
if (CConfig.Config.Debug.DebugLevel >= EDebugLevel.TR_CONFIG_LEVEL_MAX)
|
||||
{
|
||||
debugOutput.Add(_Cursor.X.ToString(CLanguage.Translate("TR_DEBUG_MOUSE") + " : (0000/") + _Cursor.Y.ToString("0000)"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
CFont font = new CFont("Normal", EStyle.Normal, 25);
|
||||
SColorF gray = new SColorF(1f, 1f, 1f, 0.5f);
|
||||
|
||||
var font = new CFont("Normal", EStyle.Normal, 25);
|
||||
var gray = new SColorF(1f, 1f, 1f, 0.5f);
|
||||
float y = 0;
|
||||
foreach (string txt in debugOutput)
|
||||
foreach (var txt in debugOutput)
|
||||
{
|
||||
float textWidth = CFonts.GetTextWidth(txt, font);
|
||||
RectangleF rect = new RectangleF(CSettings.RenderW - textWidth, y, textWidth, CFonts.GetTextHeight(txt, font));
|
||||
var textWidth = CFonts.GetTextWidth(txt, font);
|
||||
var rect = new RectangleF(CSettings.RenderW - textWidth, y, textWidth, CFonts.GetTextHeight(txt, font));
|
||||
CDraw.DrawRect(gray, new SRectF(rect.X, rect.Top, rect.Width, rect.Height, CSettings.ZNear));
|
||||
CFonts.DrawText(txt, font, rect.X, rect.Y, CSettings.ZNear);
|
||||
y += rect.Height;
|
||||
@@ -657,4 +797,4 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
#endregion private stuff
|
||||
}
|
||||
}
|
||||
}
|
||||
+54
-22
@@ -36,7 +36,7 @@ namespace Vocaluxe.Base
|
||||
|
||||
struct SPartyLanguage
|
||||
{
|
||||
public int PartyModeID;
|
||||
public int PartyModeId;
|
||||
public Dictionary<string, string> Texts;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,9 @@ namespace Vocaluxe.Base
|
||||
set
|
||||
{
|
||||
if (value >= 0 && value < _Languages.Count)
|
||||
{
|
||||
_CurrentLanguage = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,8 +62,10 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
var languages = new string[_Languages.Count];
|
||||
|
||||
for (int i = 0; i < _Languages.Count; i++)
|
||||
for (var i = 0; i < _Languages.Count; i++)
|
||||
{
|
||||
languages[i] = _Languages[i].Name;
|
||||
}
|
||||
|
||||
return languages;
|
||||
}
|
||||
@@ -71,29 +75,36 @@ namespace Vocaluxe.Base
|
||||
var files = new List<string>();
|
||||
files.AddRange(CHelper.ListFiles(CSettings.FolderNameLanguages, "*.xml", true, true));
|
||||
|
||||
foreach (string file in files)
|
||||
foreach (var file in files)
|
||||
{
|
||||
_LoadLanguageFile(file);
|
||||
}
|
||||
|
||||
return _CurrentLanguage >= 0 && _FallbackLanguage >= 0;
|
||||
}
|
||||
|
||||
public static bool SetLanguage(string language)
|
||||
{
|
||||
int nr = _GetLanguageNr(language);
|
||||
var nr = _GetLanguageNr(language);
|
||||
if (nr != -1)
|
||||
{
|
||||
_CurrentLanguage = nr;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int _GetLanguageNr(string language)
|
||||
{
|
||||
for (int i = 0; i < _Languages.Count; i++)
|
||||
for (var i = 0; i < _Languages.Count; i++)
|
||||
{
|
||||
if (_Languages[i].Name == language)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -101,10 +112,10 @@ namespace Vocaluxe.Base
|
||||
/// Checks if a translation exists and returns it
|
||||
/// </summary>
|
||||
/// <param name="keyWord">Word to translate</param>
|
||||
/// <param name="partyModeID"></param>
|
||||
/// <param name="partyModeId"></param>
|
||||
/// <param name="translation">Translated word or keyWord if translation does not exist</param>
|
||||
/// <returns>True if word was translated</returns>
|
||||
private static bool _GetTranslation(string keyWord, int partyModeID, out string translation)
|
||||
private static bool _GetTranslation(string keyWord, int partyModeId, out string translation)
|
||||
{
|
||||
if (keyWord == null)
|
||||
{
|
||||
@@ -118,45 +129,54 @@ namespace Vocaluxe.Base
|
||||
return false;
|
||||
}
|
||||
|
||||
if (partyModeID != -1)
|
||||
if (partyModeId != -1)
|
||||
{
|
||||
Dictionary<string, string> partyModeTexts = _GetPartyModeTexts(_CurrentLanguage, partyModeID);
|
||||
var partyModeTexts = _GetPartyModeTexts(_CurrentLanguage, partyModeId);
|
||||
if (partyModeTexts != null && partyModeTexts.TryGetValue(keyWord, out translation))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
partyModeTexts = _GetPartyModeTexts(_FallbackLanguage, partyModeID);
|
||||
partyModeTexts = _GetPartyModeTexts(_FallbackLanguage, partyModeId);
|
||||
if (partyModeTexts != null && partyModeTexts.TryGetValue(keyWord, out translation))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (_Languages[_CurrentLanguage].Texts.TryGetValue(keyWord, out translation))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_Languages[_FallbackLanguage].Texts.TryGetValue(keyWord, out translation))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
translation = keyWord;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static string Translate(string keyWord, int partyModeID = -1)
|
||||
public static string Translate(string keyWord, int partyModeId = -1)
|
||||
{
|
||||
string translation;
|
||||
_GetTranslation(keyWord, partyModeID, out translation);
|
||||
_GetTranslation(keyWord, partyModeId, out translation);
|
||||
return translation;
|
||||
}
|
||||
|
||||
public static bool TranslationExists(string keyWord, int partyModeID = -1)
|
||||
public static bool TranslationExists(string keyWord, int partyModeId = -1)
|
||||
{
|
||||
string translation;
|
||||
return _GetTranslation(keyWord, partyModeID, out translation);
|
||||
return _GetTranslation(keyWord, partyModeId, out translation);
|
||||
}
|
||||
|
||||
public static bool LoadPartyLanguageFiles(int partyModeID, string path)
|
||||
public static bool LoadPartyLanguageFiles(int partyModeId, string path)
|
||||
{
|
||||
var files = new List<string>();
|
||||
files.AddRange(CHelper.ListFiles(path, "*.xml", true, true));
|
||||
|
||||
return files.All(file => _LoadPartyLanguageFile(partyModeID, file));
|
||||
return files.All(file => _LoadPartyLanguageFile(partyModeId, file));
|
||||
}
|
||||
|
||||
private static bool _LoadLanguageEntries(string filePath, out Dictionary<string, string> texts)
|
||||
@@ -167,7 +187,9 @@ namespace Vocaluxe.Base
|
||||
texts = deser.Deserialize<Dictionary<string, string>>(filePath);
|
||||
string language;
|
||||
if (!texts.TryGetValue("language", out language))
|
||||
{
|
||||
throw new Exception("'language' entry is missing");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -175,44 +197,54 @@ namespace Vocaluxe.Base
|
||||
texts = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool _LoadPartyLanguageFile(int partyModeID, string filePath)
|
||||
private static bool _LoadPartyLanguageFile(int partyModeId, string filePath)
|
||||
{
|
||||
var lang = new SPartyLanguage {PartyModeID = partyModeID};
|
||||
var lang = new SPartyLanguage { PartyModeId = partyModeId };
|
||||
|
||||
if (!_LoadLanguageEntries(filePath, out lang.Texts))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int nr = _GetLanguageNr(lang.Texts["language"]);
|
||||
var nr = _GetLanguageNr(lang.Texts["language"]);
|
||||
|
||||
if (nr >= 0)
|
||||
{
|
||||
_Languages[nr].PartyModeTexts.Add(lang);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void _LoadLanguageFile(string fileName)
|
||||
{
|
||||
var lang = new SLanguage {FilePath = Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameLanguages, fileName), PartyModeTexts = new List<SPartyLanguage>()};
|
||||
var lang = new SLanguage { FilePath = Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameLanguages, fileName), PartyModeTexts = new List<SPartyLanguage>() };
|
||||
if (!_LoadLanguageEntries(lang.FilePath, out lang.Texts))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lang.Name = lang.Texts["language"];
|
||||
if (lang.Name == CSettings.FallbackLanguage)
|
||||
{
|
||||
_FallbackLanguage = _Languages.Count;
|
||||
if (_CurrentLanguage < 0)
|
||||
{
|
||||
_CurrentLanguage = _FallbackLanguage;
|
||||
}
|
||||
}
|
||||
|
||||
_Languages.Add(lang);
|
||||
}
|
||||
|
||||
private static Dictionary<string, string> _GetPartyModeTexts(int language, int partyModeID)
|
||||
private static Dictionary<string, string> _GetPartyModeTexts(int language, int partyModeId)
|
||||
{
|
||||
return
|
||||
_Languages[language].PartyModeTexts.Where(partyLanguage => partyLanguage.PartyModeID == partyModeID).Select(partyLanguage => partyLanguage.Texts).FirstOrDefault();
|
||||
_Languages[language].PartyModeTexts.Where(partyLanguage => partyLanguage.PartyModeId == partyModeId).Select(partyLanguage => partyLanguage.Texts).FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
+70
-71
@@ -19,16 +19,15 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Drawing;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Vocaluxe.Base.Fonts;
|
||||
using Vocaluxe.Base.ThemeSystem;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Game;
|
||||
using VocaluxeLib.Draw;
|
||||
using VocaluxeLib.Game;
|
||||
using VocaluxeLib.Log;
|
||||
using VocaluxeLib.Menu;
|
||||
using VocaluxeLib.Songs;
|
||||
using VocaluxeLib.Profile;
|
||||
using VocaluxeLib.Songs;
|
||||
|
||||
namespace Vocaluxe.Base
|
||||
{
|
||||
@@ -56,7 +55,7 @@ namespace Vocaluxe.Base
|
||||
public static void Init()
|
||||
{
|
||||
CBase.Assign(_Config, _Settings, _Themes, _BackgroundMusic, _Draw, _Graphics, _Fonts, _Language,
|
||||
_Game, _Profiles, _Record, _Songs, _Video, _Sound, _Cover, _DataBase, _Controller, _Playlist);
|
||||
_Game, _Profiles, _Record, _Songs, _Video, _Sound, _Cover, _DataBase, _Controller, _Playlist);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -293,24 +292,24 @@ namespace Vocaluxe.Base
|
||||
|
||||
class CBtheme : IThemes
|
||||
{
|
||||
public string GetThemeScreensPath(int partyModeID)
|
||||
public string GetThemeScreensPath(int partyModeId)
|
||||
{
|
||||
return CThemes.GetThemeScreensPath(partyModeID);
|
||||
return CThemes.GetThemeScreensPath(partyModeId);
|
||||
}
|
||||
|
||||
public CTextureRef GetSkinTexture(string textureName, int partyModeID)
|
||||
public CTextureRef GetSkinTexture(string textureName, int partyModeId)
|
||||
{
|
||||
return CThemes.GetSkinTexture(textureName, partyModeID);
|
||||
return CThemes.GetSkinTexture(textureName, partyModeId);
|
||||
}
|
||||
|
||||
public CVideoStream GetSkinVideo(string videoName, int partyModeID, bool loop)
|
||||
public CVideoStream GetSkinVideo(string videoName, int partyModeId, bool loop)
|
||||
{
|
||||
return CThemes.GetSkinVideo(videoName, partyModeID, loop);
|
||||
return CThemes.GetSkinVideo(videoName, partyModeId, loop);
|
||||
}
|
||||
|
||||
public bool GetColor(string colorName, int partyModeID, out SColorF color)
|
||||
public bool GetColor(string colorName, int partyModeId, out SColorF color)
|
||||
{
|
||||
return CThemes.GetColor(colorName, partyModeID, out color);
|
||||
return CThemes.GetColor(colorName, partyModeId, out color);
|
||||
}
|
||||
|
||||
public SColorF GetPlayerColor(int playerNr)
|
||||
@@ -538,9 +537,9 @@ namespace Vocaluxe.Base
|
||||
return CLanguage.Translate(keyWord);
|
||||
}
|
||||
|
||||
public string Translate(string keyWord, int partyModeID)
|
||||
public string Translate(string keyWord, int partyModeId)
|
||||
{
|
||||
return CLanguage.Translate(keyWord, partyModeID);
|
||||
return CLanguage.Translate(keyWord, partyModeId);
|
||||
}
|
||||
|
||||
public bool TranslationExists(string keyWord)
|
||||
@@ -606,9 +605,9 @@ namespace Vocaluxe.Base
|
||||
return CGame.GetBeatFromTime(time, bpm, gap);
|
||||
}
|
||||
|
||||
public void AddSong(int songID, EGameMode gameMode)
|
||||
public void AddSong(int songId, EGameMode gameMode)
|
||||
{
|
||||
CGame.AddSong(songID, gameMode);
|
||||
CGame.AddSong(songId, gameMode);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
@@ -649,19 +648,19 @@ namespace Vocaluxe.Base
|
||||
return CProfiles.NumProfiles;
|
||||
}
|
||||
|
||||
public EGameDifficulty GetDifficulty(Guid profileID)
|
||||
public EGameDifficulty GetDifficulty(Guid profileId)
|
||||
{
|
||||
return CProfiles.GetDifficulty(profileID);
|
||||
return CProfiles.GetDifficulty(profileId);
|
||||
}
|
||||
|
||||
public string GetPlayerName(Guid profileID, int playerNum = 0)
|
||||
public string GetPlayerName(Guid profileId, int playerNum = 0)
|
||||
{
|
||||
return CProfiles.GetPlayerName(profileID, playerNum);
|
||||
return CProfiles.GetPlayerName(profileId, playerNum);
|
||||
}
|
||||
|
||||
public CTextureRef GetAvatar(Guid profileID)
|
||||
public CTextureRef GetAvatar(Guid profileId)
|
||||
{
|
||||
return CProfiles.GetAvatarTextureFromProfile(profileID);
|
||||
return CProfiles.GetAvatarTextureFromProfile(profileId);
|
||||
}
|
||||
|
||||
public CAvatar GetAvatarByFilename(string fileName)
|
||||
@@ -669,14 +668,14 @@ namespace Vocaluxe.Base
|
||||
return CProfiles.GetAvatarByFilename(fileName);
|
||||
}
|
||||
|
||||
public bool IsProfileIDValid(Guid profileID)
|
||||
public bool IsProfileIdValid(Guid profileId)
|
||||
{
|
||||
return CProfiles.IsProfileIDValid(profileID);
|
||||
return CProfiles.IsProfileIdValid(profileId);
|
||||
}
|
||||
|
||||
public bool IsGuest(Guid profileID)
|
||||
public bool IsGuest(Guid profileId)
|
||||
{
|
||||
return CProfiles.IsGuestProfile(profileID);
|
||||
return CProfiles.IsGuestProfile(profileId);
|
||||
}
|
||||
|
||||
public void AddProfileChangedCallback(ProfileChangedCallback notification)
|
||||
@@ -780,9 +779,9 @@ namespace Vocaluxe.Base
|
||||
return CSongs.GetVisibleSongByIndex(visibleIndex);
|
||||
}
|
||||
|
||||
public CSong GetSongByID(int songID)
|
||||
public CSong GetSongById(int songId)
|
||||
{
|
||||
return CSongs.GetSong(songID);
|
||||
return CSongs.GetSong(songId);
|
||||
}
|
||||
|
||||
public ReadOnlyCollection<CSong> GetSongs()
|
||||
@@ -800,9 +799,9 @@ namespace Vocaluxe.Base
|
||||
return CSongs.GetCategoryByIndex(index);
|
||||
}
|
||||
|
||||
public void AddPartySongSung(int songID)
|
||||
public void AddPartySongSung(int songId)
|
||||
{
|
||||
CSongs.AddPartySongSung(songID);
|
||||
CSongs.AddPartySongSung(songId);
|
||||
}
|
||||
|
||||
public void ResetSongSung()
|
||||
@@ -815,9 +814,9 @@ namespace Vocaluxe.Base
|
||||
CSongs.ResetPartySongSung(catIndex);
|
||||
}
|
||||
|
||||
public void SortSongs(ESongSorting sorting, EOffOn tabs, EOffOn ignoreArticles, String searchString, EDuetOptions duetOptions, int playlistID)
|
||||
public void SortSongs(ESongSorting sorting, EOffOn tabs, EOffOn ignoreArticles, String searchString, EDuetOptions duetOptions, int playlistId)
|
||||
{
|
||||
CSongs.Sort(sorting, tabs, ignoreArticles, searchString, duetOptions, playlistID);
|
||||
CSongs.Sort(sorting, tabs, ignoreArticles, searchString, duetOptions, playlistId);
|
||||
}
|
||||
|
||||
public void NextCategory()
|
||||
@@ -833,9 +832,9 @@ namespace Vocaluxe.Base
|
||||
|
||||
class CBvideo : IVideo
|
||||
{
|
||||
public CVideoStream Load(string videoFileName)
|
||||
public CVideoStream Load(string videoUri)
|
||||
{
|
||||
return CVideo.Load(videoFileName);
|
||||
return CVideo.Load(videoUri);
|
||||
}
|
||||
|
||||
public bool Skip(CVideoStream stream, float startPosition, float videoGap)
|
||||
@@ -897,9 +896,9 @@ namespace Vocaluxe.Base
|
||||
|
||||
class CBsound : ISound
|
||||
{
|
||||
public int Load(string soundFile, bool loop = false, bool prescan = false)
|
||||
public int Load(string uri, bool loop = false, bool prescan = false)
|
||||
{
|
||||
return CSound.Load(soundFile, loop, prescan);
|
||||
return CSound.Load(uri, loop, prescan);
|
||||
}
|
||||
|
||||
public void SetPosition(int soundStream, float newPosition)
|
||||
@@ -947,9 +946,9 @@ namespace Vocaluxe.Base
|
||||
CSound.SetGlobalVolume(volume);
|
||||
}
|
||||
|
||||
public bool IsPaused(int streamID)
|
||||
public bool IsPaused(int streamId)
|
||||
{
|
||||
return CSound.IsPaused(streamID);
|
||||
return CSound.IsPaused(streamId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -973,9 +972,9 @@ namespace Vocaluxe.Base
|
||||
return CDataBase.GetCover(fileName, ref texture, coverSize);
|
||||
}
|
||||
|
||||
public bool GetDataBaseSongInfos(string artist, string title, out int numPlayed, out DateTime dateAdded, out int highscoreID)
|
||||
public bool GetDataBaseSongInfos(string artist, string title, out int numPlayed, out DateTime dateAdded, out int highscoreId)
|
||||
{
|
||||
return CDataBase.GetDataBaseSongInfos(artist, title, out numPlayed, out dateAdded, out highscoreID);
|
||||
return CDataBase.GetDataBaseSongInfos(artist, title, out numPlayed, out dateAdded, out highscoreId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -989,9 +988,9 @@ namespace Vocaluxe.Base
|
||||
|
||||
class CBplaylist : IPlaylist
|
||||
{
|
||||
public void SetName(int playlistID, string name)
|
||||
public void SetName(int playlistId, string name)
|
||||
{
|
||||
CPlaylists.SetName(playlistID, name);
|
||||
CPlaylists.SetName(playlistId, name);
|
||||
}
|
||||
|
||||
public List<int> GetIds()
|
||||
@@ -1004,24 +1003,24 @@ namespace Vocaluxe.Base
|
||||
return CPlaylists.Names;
|
||||
}
|
||||
|
||||
public bool Exists(int playlistID)
|
||||
public bool Exists(int playlistId)
|
||||
{
|
||||
return CPlaylists.Get(playlistID) != null;
|
||||
return CPlaylists.Get(playlistId) != null;
|
||||
}
|
||||
|
||||
public string GetName(int playlistID)
|
||||
public string GetName(int playlistId)
|
||||
{
|
||||
return CPlaylists.GetName(playlistID);
|
||||
return CPlaylists.GetName(playlistId);
|
||||
}
|
||||
|
||||
public void Delete(int playlistID)
|
||||
public void Delete(int playlistId)
|
||||
{
|
||||
CPlaylists.Delete(playlistID);
|
||||
CPlaylists.Delete(playlistId);
|
||||
}
|
||||
|
||||
public void Save(int playlistID)
|
||||
public void Save(int playlistId)
|
||||
{
|
||||
CPlaylists.Save(playlistID);
|
||||
CPlaylists.Save(playlistId);
|
||||
}
|
||||
|
||||
public int GetNumPlaylists()
|
||||
@@ -1029,54 +1028,54 @@ namespace Vocaluxe.Base
|
||||
return CPlaylists.NumPlaylists;
|
||||
}
|
||||
|
||||
public void AddSong(int playlistID, int songID)
|
||||
public void AddSong(int playlistId, int songId)
|
||||
{
|
||||
CPlaylists.AddSong(playlistID, songID);
|
||||
CPlaylists.AddSong(playlistId, songId);
|
||||
}
|
||||
|
||||
public void AddSong(int playlistID, int songID, EGameMode gameMode)
|
||||
public void AddSong(int playlistId, int songId, EGameMode gameMode)
|
||||
{
|
||||
CPlaylists.AddSong(playlistID, songID, gameMode);
|
||||
CPlaylists.AddSong(playlistId, songId, gameMode);
|
||||
}
|
||||
|
||||
public void InsertSong(int playlistID, int positionIndex, int songID, EGameMode gameMode)
|
||||
public void InsertSong(int playlistId, int positionIndex, int songId, EGameMode gameMode)
|
||||
{
|
||||
CPlaylists.InsertSong(playlistID, positionIndex, songID, gameMode);
|
||||
CPlaylists.InsertSong(playlistId, positionIndex, songId, gameMode);
|
||||
}
|
||||
|
||||
public void MoveSong(int playlistID, int sourceIndex, int destIndex)
|
||||
public void MoveSong(int playlistId, int sourceIndex, int destIndex)
|
||||
{
|
||||
CPlaylists.MoveSong(playlistID, sourceIndex, destIndex);
|
||||
CPlaylists.MoveSong(playlistId, sourceIndex, destIndex);
|
||||
}
|
||||
|
||||
public void MoveSongDown(int playlistID, int songIndex)
|
||||
public void MoveSongDown(int playlistId, int songIndex)
|
||||
{
|
||||
CPlaylists.MovePSongDown(playlistID, songIndex);
|
||||
CPlaylists.MovePSongDown(playlistId, songIndex);
|
||||
}
|
||||
|
||||
public void MoveSongUp(int playlistID, int songIndex)
|
||||
public void MoveSongUp(int playlistId, int songIndex)
|
||||
{
|
||||
CPlaylists.MoveSongUp(playlistID, songIndex);
|
||||
CPlaylists.MoveSongUp(playlistId, songIndex);
|
||||
}
|
||||
|
||||
public void DeleteSong(int playlistID, int songIndex)
|
||||
public void DeleteSong(int playlistId, int songIndex)
|
||||
{
|
||||
CPlaylists.DeleteSong(playlistID, songIndex);
|
||||
CPlaylists.DeleteSong(playlistId, songIndex);
|
||||
}
|
||||
|
||||
public int GetSongCount(int playlistID)
|
||||
public int GetSongCount(int playlistId)
|
||||
{
|
||||
return CPlaylists.GetSongCount(playlistID);
|
||||
return CPlaylists.GetSongCount(playlistId);
|
||||
}
|
||||
|
||||
public CPlaylistSong GetSong(int playlistID, int songIndex)
|
||||
public CPlaylistSong GetSong(int playlistId, int songIndex)
|
||||
{
|
||||
return CPlaylists.GetSong(playlistID, songIndex);
|
||||
return CPlaylists.GetSong(playlistId, songIndex);
|
||||
}
|
||||
|
||||
public bool ContainsSong(int playlistID, int songID)
|
||||
public bool ContainsSong(int playlistId, int songId)
|
||||
{
|
||||
return CPlaylists.ContainsSong(playlistID, songID);
|
||||
return CPlaylists.ContainsSong(playlistId, songId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+88
-45
@@ -35,44 +35,54 @@ namespace Vocaluxe.Base
|
||||
private const int _PartyModeSystemVersion = 2;
|
||||
|
||||
private static readonly Dictionary<int, SPartyMode> _PartyModes = new Dictionary<int, SPartyMode>();
|
||||
private static int _NextID;
|
||||
private static int _NextId;
|
||||
private static IPartyMode _CurrentPartyMode;
|
||||
|
||||
#region public stuff
|
||||
public static bool Init()
|
||||
{
|
||||
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<string>()
|
||||
};
|
||||
}
|
||||
|
||||
var 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<string>()
|
||||
};
|
||||
_PartyModes.Add(-1, pm);
|
||||
_CurrentPartyMode = pm.PartyMode;
|
||||
Debug.Assert(_CurrentPartyMode != null && _CurrentPartyMode.ID == -1);
|
||||
Debug.Assert(_CurrentPartyMode != null && _CurrentPartyMode.Id == -1);
|
||||
|
||||
//load other party modes
|
||||
_LoadPartyModes();
|
||||
return _CurrentPartyMode.Init();
|
||||
}
|
||||
|
||||
public static int CurrentPartyModeID
|
||||
public static int CurrentPartyModeId
|
||||
{
|
||||
get { return _CurrentPartyMode.ID; }
|
||||
get { return _CurrentPartyMode.Id; }
|
||||
set
|
||||
{
|
||||
if (_CurrentPartyMode.ID == value) {
|
||||
if (_CurrentPartyMode.Id == value)
|
||||
{
|
||||
_CurrentPartyMode.SetDefaults();
|
||||
return;
|
||||
}
|
||||
|
||||
if (value != -1 && !_PartyModes.ContainsKey(value))
|
||||
throw new ArgumentException("Partymode with ID=" + value + " does not exist!");
|
||||
IPartyMode pm = _PartyModes[value].PartyMode;
|
||||
{
|
||||
throw new ArgumentException("Partymode with Id=" + value + " does not exist!");
|
||||
}
|
||||
|
||||
var pm = _PartyModes[value].PartyMode;
|
||||
if (pm.Init())
|
||||
{
|
||||
_CurrentPartyMode = pm;
|
||||
}
|
||||
else
|
||||
{
|
||||
CLog.Error("Could not init PartyMode \"" + _PartyModes[value].Info.Name + "\"! Removing...", true);
|
||||
@@ -88,42 +98,51 @@ namespace Vocaluxe.Base
|
||||
|
||||
public static void ReloadTheme()
|
||||
{
|
||||
foreach (SPartyMode pm in _PartyModes.Values)
|
||||
foreach (var pm in _PartyModes.Values)
|
||||
{
|
||||
pm.PartyMode.ReloadTheme();
|
||||
}
|
||||
}
|
||||
|
||||
public static void ReloadSkin()
|
||||
{
|
||||
foreach (SPartyMode pm in _PartyModes.Values)
|
||||
foreach (var pm in _PartyModes.Values)
|
||||
{
|
||||
pm.PartyMode.ReloadSkin();
|
||||
}
|
||||
}
|
||||
|
||||
public static void SaveThemes()
|
||||
{
|
||||
foreach (SPartyMode pm in _PartyModes.Values)
|
||||
foreach (var pm in _PartyModes.Values)
|
||||
{
|
||||
pm.PartyMode.SaveScreens();
|
||||
}
|
||||
}
|
||||
|
||||
public static List<SPartyModeInfos> GetPartyModeInfos()
|
||||
{
|
||||
List<SPartyModeInfos> list = new List<SPartyModeInfos>();
|
||||
foreach (SPartyMode pm in _PartyModes.Values)
|
||||
var list = new List<SPartyModeInfos>();
|
||||
foreach (var pm in _PartyModes.Values)
|
||||
{
|
||||
if (pm.PartyMode.ID >= 0)
|
||||
if (pm.PartyMode.Id >= 0)
|
||||
{
|
||||
list.Add(pm.Info);
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
public static void SetNormalGameMode()
|
||||
{
|
||||
CSongs.ResetPartySongSung();
|
||||
CurrentPartyModeID = -1;
|
||||
CurrentPartyModeId = -1;
|
||||
}
|
||||
|
||||
public static void SetPartyMode(int partyModeID)
|
||||
public static void SetPartyMode(int partyModeId)
|
||||
{
|
||||
CurrentPartyModeID = partyModeID;
|
||||
CurrentPartyModeId = partyModeId;
|
||||
}
|
||||
#endregion public stuff
|
||||
|
||||
@@ -163,9 +182,9 @@ namespace Vocaluxe.Base
|
||||
_CurrentPartyMode.JokerUsed(teamNr);
|
||||
}
|
||||
|
||||
public static void SongSelected(int songID)
|
||||
public static void SongSelected(int songId)
|
||||
{
|
||||
_CurrentPartyMode.SongSelected(songID);
|
||||
_CurrentPartyMode.SongSelected(songId);
|
||||
}
|
||||
|
||||
public static void FinishedSinging()
|
||||
@@ -190,25 +209,31 @@ namespace Vocaluxe.Base
|
||||
var files = new List<string>();
|
||||
files.AddRange(CHelper.ListFiles(CSettings.FolderNamePartyModes, "*.xml", false, true));
|
||||
|
||||
foreach (string file in files)
|
||||
foreach (var file in files)
|
||||
{
|
||||
SPartyMode pm;
|
||||
if (_LoadPartyMode(file, out pm))
|
||||
_PartyModes.Add(pm.PartyMode.ID, pm);
|
||||
{
|
||||
_PartyModes.Add(pm.PartyMode.Id, pm);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool _LoadPartyMode(string filePath, out SPartyMode pm)
|
||||
{
|
||||
CXmlDeserializer deser = new CXmlDeserializer();
|
||||
var deser = new CXmlDeserializer();
|
||||
try
|
||||
{
|
||||
pm = deser.Deserialize<SPartyMode>(filePath);
|
||||
if (pm.PartyModeSystemVersion != _PartyModeSystemVersion)
|
||||
{
|
||||
throw new Exception("Wrong PartyModeSystemVersion " + pm.PartyModeSystemVersion + " expected: " + _PartyModeSystemVersion);
|
||||
}
|
||||
|
||||
if (pm.ScreenFiles.Count == 0)
|
||||
{
|
||||
throw new Exception("No ScreenFiles found");
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -217,18 +242,20 @@ namespace Vocaluxe.Base
|
||||
return false;
|
||||
}
|
||||
|
||||
string pathToPm = Path.Combine(CSettings.ProgramFolder, CSettings.FolderNamePartyModes, pm.Info.Folder);
|
||||
string pathToCode = Path.Combine(pathToPm, CSettings.FolderNamePartyModeCode);
|
||||
var pathToPm = Path.Combine(CSettings.ProgramFolder, CSettings.FolderNamePartyModes, pm.Info.Folder);
|
||||
var pathToCode = Path.Combine(pathToPm, CSettings.FolderNamePartyModeCode);
|
||||
|
||||
var filesToCompile = new List<string>();
|
||||
filesToCompile.AddRange(CHelper.ListFiles(pathToCode, "*.cs", false, true));
|
||||
|
||||
Assembly output = _CompileFiles(filesToCompile.ToArray());
|
||||
var output = _CompileFiles(filesToCompile.ToArray());
|
||||
if (output == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
object instance = output.CreateInstance(typeof(IPartyMode).Namespace + "." + pm.Info.Folder + "." + pm.Info.PartyModeFile, false,
|
||||
BindingFlags.Public | BindingFlags.Instance, null, new object[] {_NextID++}, null, null);
|
||||
var instance = output.CreateInstance(typeof(IPartyMode).Namespace + "." + pm.Info.Folder + "." + pm.Info.PartyModeFile, false,
|
||||
BindingFlags.Public | BindingFlags.Instance, null, new object[] { _NextId++ }, null, null);
|
||||
if (instance == null)
|
||||
{
|
||||
CLog.Error("Error creating Instance of PartyMode file: " + filePath);
|
||||
@@ -245,21 +272,25 @@ namespace Vocaluxe.Base
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CLanguage.LoadPartyLanguageFiles(pm.PartyMode.ID, Path.Combine(pathToPm, CSettings.FolderNamePartyModeLanguages)))
|
||||
if (!CLanguage.LoadPartyLanguageFiles(pm.PartyMode.Id, Path.Combine(pathToPm, CSettings.FolderNamePartyModeLanguages)))
|
||||
{
|
||||
CLog.Error("Error loading language files for PartyMode: " + filePath);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CThemes.ReadThemesFromFolder(Path.Combine(pathToPm, CSettings.FolderNameThemes), pm.PartyMode.ID))
|
||||
return false;
|
||||
|
||||
if (!CThemes.LoadPartymodeTheme(pm.PartyMode.ID))
|
||||
return false;
|
||||
|
||||
foreach (string screenfile in pm.ScreenFiles)
|
||||
if (!CThemes.ReadThemesFromFolder(Path.Combine(pathToPm, CSettings.FolderNameThemes), pm.PartyMode.Id))
|
||||
{
|
||||
CMenuParty screen = _GetPartyScreenInstance(output, screenfile, pm.Info.Folder);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CThemes.LoadPartymodeTheme(pm.PartyMode.Id))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach (var screenfile in pm.ScreenFiles)
|
||||
{
|
||||
var screen = _GetPartyScreenInstance(output, screenfile, pm.Info.Folder);
|
||||
|
||||
if (screen != null)
|
||||
{
|
||||
@@ -267,8 +298,11 @@ namespace Vocaluxe.Base
|
||||
pm.PartyMode.AddScreen(screen, screenfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
pm.PartyMode.LoadTheme();
|
||||
pm.Info.ExtInfo = pm.PartyMode;
|
||||
return true;
|
||||
@@ -277,20 +311,22 @@ namespace Vocaluxe.Base
|
||||
private static Assembly _CompileFiles(string[] files)
|
||||
{
|
||||
if (files == null || files.Length == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
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(Path.Combine("libs","managed","VocaluxeLib.dll"));
|
||||
compilerParams.ReferencedAssemblies.Add(Path.Combine("libs", "managed", "VocaluxeLib.dll"));
|
||||
compilerParams.GenerateInMemory = true;
|
||||
#if DEBUG
|
||||
compilerParams.IncludeDebugInformation = true;
|
||||
#endif
|
||||
|
||||
using (CodeDomProvider cdp = CodeDomProvider.CreateProvider("CSharp"))
|
||||
using (var cdp = CodeDomProvider.CreateProvider("CSharp"))
|
||||
{
|
||||
CompilerResults compileResult;
|
||||
|
||||
@@ -307,9 +343,13 @@ namespace Vocaluxe.Base
|
||||
if (compileResult.Errors.Count > 0)
|
||||
{
|
||||
foreach (CompilerError e in compileResult.Errors)
|
||||
{
|
||||
CLog.Error("Error Compiling Source (" + CHelper.ListStrings(files) + "): " + e.ErrorText + " in '" + e.FileName + "' (" + e.Line + ")");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return compileResult.CompiledAssembly;
|
||||
}
|
||||
}
|
||||
@@ -317,9 +357,11 @@ namespace Vocaluxe.Base
|
||||
private static CMenuParty _GetPartyScreenInstance(Assembly assembly, string screenName, string partyModeName)
|
||||
{
|
||||
if (assembly == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
object instance = assembly.CreateInstance(typeof(IPartyMode).Namespace + "." + partyModeName + "." + screenName);
|
||||
var instance = assembly.CreateInstance(typeof(IPartyMode).Namespace + "." + partyModeName + "." + screenName);
|
||||
if (instance == null)
|
||||
{
|
||||
CLog.Error("Error creating Instance of PartyScreen: " + screenName);
|
||||
@@ -336,6 +378,7 @@ namespace Vocaluxe.Base
|
||||
CLog.Error("Error casting PartyScreen: " + screenName + "; " + e.Message);
|
||||
return null;
|
||||
}
|
||||
|
||||
return screen;
|
||||
}
|
||||
#endregion private stuff
|
||||
|
||||
@@ -24,16 +24,16 @@ namespace Vocaluxe.Base
|
||||
class CPlaylistElement
|
||||
{
|
||||
public readonly CSong Song;
|
||||
private readonly string _MusicFilePath = String.Empty;
|
||||
private readonly string _MusicFilePath = string.Empty;
|
||||
|
||||
public bool HasMetaData
|
||||
{
|
||||
get { return Song != null; }
|
||||
}
|
||||
|
||||
public int SongID
|
||||
public int SongId
|
||||
{
|
||||
get { return HasMetaData ? Song.ID : -1; }
|
||||
get { return HasMetaData ? Song.Id : -1; }
|
||||
}
|
||||
|
||||
public string MusicFilePath
|
||||
@@ -63,7 +63,7 @@ namespace Vocaluxe.Base
|
||||
|
||||
public float Finish
|
||||
{
|
||||
get { return HasMetaData ? Song.Finish : 0f; }
|
||||
get { return HasMetaData ? Song.End : 0f; }
|
||||
}
|
||||
|
||||
public CTextureRef Cover
|
||||
@@ -79,14 +79,20 @@ namespace Vocaluxe.Base
|
||||
public CPlaylistElement(CSong song)
|
||||
{
|
||||
if (song == null)
|
||||
{
|
||||
throw new ArgumentNullException("song");
|
||||
}
|
||||
|
||||
Song = song;
|
||||
}
|
||||
|
||||
public CPlaylistElement(string filePath)
|
||||
{
|
||||
if (String.IsNullOrEmpty(filePath))
|
||||
if (string.IsNullOrEmpty(filePath))
|
||||
{
|
||||
throw new ArgumentNullException("filePath");
|
||||
}
|
||||
|
||||
_MusicFilePath = filePath;
|
||||
}
|
||||
}
|
||||
|
||||
+87
-50
@@ -17,7 +17,6 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
@@ -25,7 +24,6 @@ using Vocaluxe.Lib.Playlist;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Log;
|
||||
using VocaluxeLib.Menu;
|
||||
using VocaluxeLib.Songs;
|
||||
|
||||
namespace Vocaluxe.Base
|
||||
{
|
||||
@@ -66,9 +64,9 @@ namespace Vocaluxe.Base
|
||||
var files = new List<string>();
|
||||
files.AddRange(CHelper.ListFiles(Path.Combine(CSettings.DataFolder, CConfig.FolderPlaylists), "*.upl", true, true));
|
||||
|
||||
foreach (string file in files)
|
||||
foreach (var file in files)
|
||||
{
|
||||
CPlaylistFile playlist = _ConvertUSDXPlaylist(file);
|
||||
var playlist = _ConvertUSDXPlaylist(file);
|
||||
playlist.Save();
|
||||
_Playlists.Add(playlist);
|
||||
}
|
||||
@@ -81,38 +79,45 @@ namespace Vocaluxe.Base
|
||||
var files = new List<string>();
|
||||
files.AddRange(CHelper.ListFiles(Path.Combine(CSettings.DataFolder, CConfig.FolderPlaylists), "*.xml", true, true));
|
||||
|
||||
foreach (string file in files)
|
||||
foreach (var file in files)
|
||||
{
|
||||
CPlaylistFile playlist = new CPlaylistFile();
|
||||
var playlist = new CPlaylistFile();
|
||||
if (playlist._Load(file))
|
||||
{
|
||||
_Playlists.Add(playlist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static CPlaylistFile Get(int playlistID)
|
||||
public static CPlaylistFile Get(int playlistId)
|
||||
{
|
||||
return _Playlists.FirstOrDefault(pl => pl.Id == playlistID);
|
||||
return _Playlists.FirstOrDefault(pl => pl.Id == playlistId);
|
||||
}
|
||||
|
||||
public static string GetName(int playlistID)
|
||||
public static string GetName(int playlistId)
|
||||
{
|
||||
CPlaylistFile pl = Get(playlistID);
|
||||
var pl = Get(playlistId);
|
||||
return pl == null ? "Error: Can't find Playlist" : pl.Name;
|
||||
}
|
||||
|
||||
public static void SetName(int playlistID, string name)
|
||||
public static void SetName(int playlistId, string name)
|
||||
{
|
||||
CPlaylistFile pl = Get(playlistID);
|
||||
var pl = Get(playlistId);
|
||||
|
||||
if (pl != null)
|
||||
{
|
||||
pl.Name = name;
|
||||
}
|
||||
}
|
||||
|
||||
public static void Delete(int playlistID)
|
||||
public static void Delete(int playlistId)
|
||||
{
|
||||
CPlaylistFile pl = Get(playlistID);
|
||||
var pl = Get(playlistId);
|
||||
if (pl == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (pl.File != "" && File.Exists(pl.File))
|
||||
{
|
||||
try
|
||||
@@ -121,94 +126,113 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
CLog.Error("Can't delete Playlist File " + _Playlists[playlistID].File + ".xml");
|
||||
CLog.Error("Can't delete Playlist File " + _Playlists[playlistId].File + ".xml");
|
||||
}
|
||||
}
|
||||
|
||||
_Playlists.Remove(pl);
|
||||
}
|
||||
|
||||
public static void Save(int playlistID)
|
||||
public static void Save(int playlistId)
|
||||
{
|
||||
CPlaylistFile pl = Get(playlistID);
|
||||
var pl = Get(playlistId);
|
||||
if (pl != null)
|
||||
{
|
||||
pl.Save();
|
||||
}
|
||||
}
|
||||
|
||||
public static int NewPlaylist(string name = "New Playlist")
|
||||
{
|
||||
CPlaylistFile pl = new CPlaylistFile {Name = name};
|
||||
var pl = new CPlaylistFile { Name = name };
|
||||
_Playlists.Add(pl);
|
||||
return pl.Id;
|
||||
}
|
||||
|
||||
public static void AddSong(int playlistID, int songID)
|
||||
public static void AddSong(int playlistId, int songId)
|
||||
{
|
||||
CPlaylistFile pl = Get(playlistID);
|
||||
var pl = Get(playlistId);
|
||||
if (pl != null)
|
||||
pl.AddSong(songID);
|
||||
{
|
||||
pl.AddSong(songId);
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddSong(int playlistID, int songID, EGameMode gameMode)
|
||||
public static void AddSong(int playlistId, int songId, EGameMode gameMode)
|
||||
{
|
||||
CPlaylistFile pl = Get(playlistID);
|
||||
var pl = Get(playlistId);
|
||||
if (pl != null)
|
||||
pl.AddSong(songID, gameMode);
|
||||
{
|
||||
pl.AddSong(songId, gameMode);
|
||||
}
|
||||
}
|
||||
|
||||
public static void InsertSong(int playlistID, int positionIndex, int songID, EGameMode gameMode)
|
||||
public static void InsertSong(int playlistId, int positionIndex, int songId, EGameMode gameMode)
|
||||
{
|
||||
CPlaylistFile pl = Get(playlistID);
|
||||
var pl = Get(playlistId);
|
||||
if (pl != null)
|
||||
pl.InsertSong(positionIndex, songID, gameMode);
|
||||
{
|
||||
pl.InsertSong(positionIndex, songId, gameMode);
|
||||
}
|
||||
}
|
||||
|
||||
public static void MoveSong(int playlistID, int sourceIndex, int destIndex)
|
||||
public static void MoveSong(int playlistId, int sourceIndex, int destIndex)
|
||||
{
|
||||
CPlaylistFile pl = Get(playlistID);
|
||||
var pl = Get(playlistId);
|
||||
if (pl != null)
|
||||
{
|
||||
pl.MoveSong(sourceIndex, destIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void MovePSongDown(int playlistID, int songIndex)
|
||||
public static void MovePSongDown(int playlistId, int songIndex)
|
||||
{
|
||||
CPlaylistFile pl = Get(playlistID);
|
||||
var pl = Get(playlistId);
|
||||
if (pl != null)
|
||||
{
|
||||
pl.MoveSongDown(songIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void MoveSongUp(int playlistID, int songIndex)
|
||||
public static void MoveSongUp(int playlistId, int songIndex)
|
||||
{
|
||||
CPlaylistFile pl = Get(playlistID);
|
||||
var pl = Get(playlistId);
|
||||
if (pl != null)
|
||||
{
|
||||
pl.MoveSongUp(songIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public static void DeleteSong(int playlistID, int songIndex)
|
||||
public static void DeleteSong(int playlistId, int songIndex)
|
||||
{
|
||||
CPlaylistFile pl = Get(playlistID);
|
||||
var pl = Get(playlistId);
|
||||
if (pl != null)
|
||||
{
|
||||
pl.DeleteSong(songIndex);
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetSongCount(int playlistID)
|
||||
public static int GetSongCount(int playlistId)
|
||||
{
|
||||
CPlaylistFile pl = Get(playlistID);
|
||||
var pl = Get(playlistId);
|
||||
return pl != null ? pl.Songs.Count : -1;
|
||||
}
|
||||
|
||||
public static CPlaylistSong GetSong(int playlistID, int songIndex)
|
||||
public static CPlaylistSong GetSong(int playlistId, int songIndex)
|
||||
{
|
||||
CPlaylistFile pl = Get(playlistID);
|
||||
var pl = Get(playlistId);
|
||||
if (pl == null || songIndex >= pl.Songs.Count)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return pl.Songs[songIndex];
|
||||
}
|
||||
|
||||
public static bool ContainsSong(int playlistID, int songID)
|
||||
public static bool ContainsSong(int playlistId, int songId)
|
||||
{
|
||||
CPlaylistFile pl = Get(playlistID);
|
||||
return pl != null && pl.Songs.Find((x) => x.SongID == songID) != null;
|
||||
var pl = Get(playlistId);
|
||||
return pl != null && pl.Songs.Find((x) => x.SongId == songId) != null;
|
||||
}
|
||||
|
||||
#region private methods
|
||||
@@ -225,10 +249,13 @@ namespace Vocaluxe.Base
|
||||
private static CPlaylistFile _ConvertUSDXPlaylist(string file)
|
||||
{
|
||||
var pl = new CPlaylistFile();
|
||||
ReadOnlyCollection<CSong> allSongs = CSongs.AllSongs;
|
||||
var allSongs = CSongs.AllSongs;
|
||||
|
||||
if (!File.Exists(file))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
StreamReader sr;
|
||||
@@ -237,30 +264,40 @@ namespace Vocaluxe.Base
|
||||
string line;
|
||||
while ((line = sr.ReadLine()) != null)
|
||||
{
|
||||
int pos = line.IndexOf(":", StringComparison.Ordinal);
|
||||
var pos = line.IndexOf(":", StringComparison.Ordinal);
|
||||
if (pos <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (line[0] == '#')
|
||||
{
|
||||
//Name or comment
|
||||
string identifier = line.Substring(1, pos - 1).Trim();
|
||||
string value = line.Substring(pos + 1, line.Length - pos - 1).Trim();
|
||||
var identifier = line.Substring(1, pos - 1).Trim();
|
||||
var value = line.Substring(pos + 1, line.Length - pos - 1).Trim();
|
||||
if (identifier.ToUpper() == "NAME")
|
||||
{
|
||||
pl.Name = value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Song
|
||||
string artist = line.Substring(0, pos - 1).Trim();
|
||||
string title = line.Substring(pos + 1, line.Length - pos - 1).Trim();
|
||||
CSong plSong = allSongs.FirstOrDefault(song => song.Artist == artist && song.Title == title);
|
||||
var artist = line.Substring(0, pos - 1).Trim();
|
||||
var title = line.Substring(pos + 1, line.Length - pos - 1).Trim();
|
||||
var plSong = allSongs.FirstOrDefault(song => song.Artist == artist && song.Title == title);
|
||||
if (plSong != null)
|
||||
pl.AddSong(plSong.ID);
|
||||
{
|
||||
pl.AddSong(plSong.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
CLog.Error("Can't find song '" + title + "' from '" + artist + "' in playlist file: " + file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File.Delete(file);
|
||||
}
|
||||
catch
|
||||
|
||||
+259
-142
@@ -17,8 +17,8 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Draw;
|
||||
@@ -46,7 +46,7 @@ namespace Vocaluxe.Base
|
||||
public CProfile Profile;
|
||||
public CAvatar Avatar;
|
||||
public EAction Action;
|
||||
public Guid ProfileID;
|
||||
public Guid ProfileId;
|
||||
}
|
||||
#endregion enums and structs
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace Vocaluxe.Base
|
||||
private static Dictionary<Guid, CProfile> _Profiles;
|
||||
|
||||
private static Dictionary<int, CAvatar> _Avatars;
|
||||
private static Queue<int> _AvatarIDs;
|
||||
private static Queue<int> _AvatarIds;
|
||||
|
||||
private static readonly Queue<SChange> _Queue = new Queue<SChange>();
|
||||
private static readonly Object _QueueMutex = new Object();
|
||||
@@ -80,9 +80,11 @@ namespace Vocaluxe.Base
|
||||
public static void Init()
|
||||
{
|
||||
_Avatars = new Dictionary<int, CAvatar>();
|
||||
_AvatarIDs = new Queue<int>(1000);
|
||||
for (int i = 0; i < 1000; i++)
|
||||
_AvatarIDs.Enqueue(i);
|
||||
_AvatarIds = new Queue<int>(1000);
|
||||
for (var i = 0; i < 1000; i++)
|
||||
{
|
||||
_AvatarIds.Enqueue(i);
|
||||
}
|
||||
|
||||
_Profiles = new Dictionary<Guid, CProfile>();
|
||||
|
||||
@@ -95,7 +97,7 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
while (_Queue.Count > 0)
|
||||
{
|
||||
SChange change = _Queue.Dequeue();
|
||||
var change = _Queue.Dequeue();
|
||||
switch (change.Action)
|
||||
{
|
||||
case EAction.LoadProfiles:
|
||||
@@ -110,61 +112,78 @@ namespace Vocaluxe.Base
|
||||
break;
|
||||
|
||||
case EAction.AddProfile:
|
||||
CProfile newProf = change.Profile;
|
||||
var newProf = change.Profile;
|
||||
if (newProf == null)
|
||||
break;
|
||||
|
||||
newProf.ID = Guid.NewGuid();
|
||||
if (newProf.Avatar == null)
|
||||
newProf.Avatar = _Avatars.Values.First();
|
||||
else if (newProf.Avatar.ID < 0)
|
||||
{
|
||||
newProf.Avatar.ID = _AvatarIDs.Dequeue();
|
||||
_Avatars.Add(newProf.Avatar.ID, newProf.Avatar);
|
||||
break;
|
||||
}
|
||||
|
||||
newProf.Id = Guid.NewGuid();
|
||||
if (newProf.Avatar == null)
|
||||
{
|
||||
newProf.Avatar = _Avatars.Values.First();
|
||||
}
|
||||
else if (newProf.Avatar.Id < 0)
|
||||
{
|
||||
newProf.Avatar.Id = _AvatarIds.Dequeue();
|
||||
_Avatars.Add(newProf.Avatar.Id, newProf.Avatar);
|
||||
_AvatarsChanged = true;
|
||||
}
|
||||
|
||||
newProf.SaveProfile();
|
||||
_Profiles.Add(newProf.ID, newProf);
|
||||
_Profiles.Add(newProf.Id, newProf);
|
||||
|
||||
_ProfilesChanged = true;
|
||||
break;
|
||||
|
||||
case EAction.EditProfile:
|
||||
if (change.Profile == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IsProfileIDValid(change.Profile.ID))
|
||||
if (!IsProfileIdValid(change.Profile.Id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Profiles[change.Profile.ID] = change.Profile;
|
||||
_Profiles[change.Profile.Id] = change.Profile;
|
||||
_ProfilesChanged = true;
|
||||
break;
|
||||
|
||||
case EAction.DeleteProfile:
|
||||
if (!IsProfileIDValid(change.ProfileID))
|
||||
if (!IsProfileIdValid(change.ProfileId))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
_DeleteProfile(change.ProfileID);
|
||||
_DeleteProfile(change.ProfileId);
|
||||
_ProfilesChanged = true;
|
||||
break;
|
||||
|
||||
case EAction.AddAvatar:
|
||||
if (change.Avatar == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
change.Avatar.ID = _AvatarIDs.Dequeue();
|
||||
_Avatars.Add(change.Avatar.ID, change.Avatar);
|
||||
change.Avatar.Id = _AvatarIds.Dequeue();
|
||||
_Avatars.Add(change.Avatar.Id, change.Avatar);
|
||||
_AvatarsChanged = true;
|
||||
break;
|
||||
|
||||
case EAction.EditAvatar:
|
||||
if (change.Avatar == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (!IsAvatarIDValid(change.Avatar.ID))
|
||||
if (!IsAvatarIdValid(change.Avatar.Id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Avatars[change.Avatar.ID] = change.Avatar;
|
||||
_Avatars[change.Avatar.Id] = change.Avatar;
|
||||
_AvatarsChanged = true;
|
||||
break;
|
||||
}
|
||||
@@ -172,19 +191,25 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
|
||||
if (_ProfileChangedCallbacks.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var flags = EProfileChangedFlags.None;
|
||||
|
||||
if (_AvatarsChanged)
|
||||
{
|
||||
flags = EProfileChangedFlags.Avatar;
|
||||
}
|
||||
|
||||
if (_ProfilesChanged)
|
||||
{
|
||||
flags |= EProfileChangedFlags.Profile;
|
||||
}
|
||||
|
||||
if (flags != EProfileChangedFlags.None)
|
||||
{
|
||||
int index = 0;
|
||||
var index = 0;
|
||||
while (index < _ProfileChangedCallbacks.Count)
|
||||
{
|
||||
try
|
||||
@@ -195,9 +220,11 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
_ProfileChangedCallbacks.RemoveAt(index);
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
_AvatarsChanged = false;
|
||||
_ProfilesChanged = false;
|
||||
}
|
||||
@@ -209,7 +236,7 @@ namespace Vocaluxe.Base
|
||||
|
||||
public static void LoadProfiles()
|
||||
{
|
||||
var change = new SChange {Action = EAction.LoadProfiles};
|
||||
var change = new SChange { Action = EAction.LoadProfiles };
|
||||
|
||||
lock (_QueueMutex)
|
||||
{
|
||||
@@ -219,7 +246,7 @@ namespace Vocaluxe.Base
|
||||
|
||||
public static void LoadAvatars()
|
||||
{
|
||||
var change = new SChange {Action = EAction.LoadAvatars};
|
||||
var change = new SChange { Action = EAction.LoadAvatars };
|
||||
|
||||
lock (_QueueMutex)
|
||||
{
|
||||
@@ -230,9 +257,11 @@ namespace Vocaluxe.Base
|
||||
public static void AddProfile(CProfile newProfile)
|
||||
{
|
||||
if (newProfile == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var change = new SChange {Action = EAction.AddProfile, Profile = newProfile};
|
||||
var change = new SChange { Action = EAction.AddProfile, Profile = newProfile };
|
||||
|
||||
lock (_QueueMutex)
|
||||
{
|
||||
@@ -243,9 +272,11 @@ namespace Vocaluxe.Base
|
||||
public static void EditProfile(CProfile editProfile)
|
||||
{
|
||||
if (editProfile == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var change = new SChange {Action = EAction.EditProfile, Profile = editProfile};
|
||||
var change = new SChange { Action = EAction.EditProfile, Profile = editProfile };
|
||||
|
||||
lock (_QueueMutex)
|
||||
{
|
||||
@@ -253,12 +284,14 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
}
|
||||
|
||||
public static void DeleteProfile(Guid profileID)
|
||||
public static void DeleteProfile(Guid profileId)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID))
|
||||
if (!IsProfileIdValid(profileId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var change = new SChange {Action = EAction.DeleteProfile, ProfileID = profileID};
|
||||
var change = new SChange { Action = EAction.DeleteProfile, ProfileId = profileId };
|
||||
|
||||
lock (_QueueMutex)
|
||||
{
|
||||
@@ -269,9 +302,11 @@ namespace Vocaluxe.Base
|
||||
public static void AddAvatar(CAvatar newAvatar)
|
||||
{
|
||||
if (newAvatar == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var change = new SChange {Action = EAction.AddAvatar, Avatar = newAvatar};
|
||||
var change = new SChange { Action = EAction.AddAvatar, Avatar = newAvatar };
|
||||
|
||||
lock (_QueueMutex)
|
||||
{
|
||||
@@ -282,9 +317,11 @@ namespace Vocaluxe.Base
|
||||
public static void EditAvatar(CAvatar editAvatar)
|
||||
{
|
||||
if (editAvatar == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var change = new SChange {Action = EAction.EditAvatar, Avatar = editAvatar};
|
||||
var change = new SChange { Action = EAction.EditAvatar, Avatar = editAvatar };
|
||||
|
||||
lock (_QueueMutex)
|
||||
{
|
||||
@@ -295,25 +332,31 @@ namespace Vocaluxe.Base
|
||||
public static CProfile[] GetProfiles()
|
||||
{
|
||||
if (_Profiles.Count == 0)
|
||||
{
|
||||
return new CProfile[0];
|
||||
}
|
||||
|
||||
var list = new List<CProfile>(_Profiles.Values);
|
||||
list.Sort(_AlphaNumericCompareByPlayerName);
|
||||
return list.ToArray();
|
||||
}
|
||||
|
||||
public static CProfile GetProfile(Guid profileID)
|
||||
public static CProfile GetProfile(Guid profileId)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID))
|
||||
if (!IsProfileIdValid(profileId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return _Profiles[profileID];
|
||||
return _Profiles[profileId];
|
||||
}
|
||||
|
||||
public static IEnumerable<CAvatar> GetAvatars()
|
||||
{
|
||||
if (_Avatars.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var result = new CAvatar[_Avatars.Count];
|
||||
_Avatars.Values.CopyTo(result, 0);
|
||||
@@ -324,199 +367,242 @@ namespace Vocaluxe.Base
|
||||
public static Guid NewProfile(string fileName = "")
|
||||
{
|
||||
var profile = new CProfile
|
||||
{
|
||||
FilePath = fileName != "" ? Path.Combine(CConfig.ProfileFolders[0], fileName) : String.Empty
|
||||
};
|
||||
{
|
||||
FilePath = fileName != "" ? Path.Combine(CConfig.ProfileFolders[0], fileName) : string.Empty
|
||||
};
|
||||
|
||||
if (File.Exists(profile.FilePath))
|
||||
{
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
||||
profile.ID = Guid.NewGuid();
|
||||
_Profiles.Add(profile.ID, profile);
|
||||
profile.Id = Guid.NewGuid();
|
||||
_Profiles.Add(profile.Id, profile);
|
||||
_ProfilesChanged = true;
|
||||
return profile.ID;
|
||||
return profile.Id;
|
||||
}
|
||||
|
||||
public static int NewAvatar(string fileName)
|
||||
{
|
||||
CAvatar avatar = CAvatar.GetAvatar(fileName);
|
||||
var avatar = CAvatar.GetAvatar(fileName);
|
||||
if (avatar == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
avatar.ID = _AvatarIDs.Dequeue();
|
||||
_Avatars.Add(avatar.ID, avatar);
|
||||
avatar.Id = _AvatarIds.Dequeue();
|
||||
_Avatars.Add(avatar.Id, avatar);
|
||||
_AvatarsChanged = true;
|
||||
return avatar.ID;
|
||||
return avatar.Id;
|
||||
}
|
||||
|
||||
public static void SaveProfiles()
|
||||
{
|
||||
foreach (Guid id in _Profiles.Keys)
|
||||
foreach (var id in _Profiles.Keys)
|
||||
{
|
||||
_Profiles[id].SaveProfile();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsProfileIDValid(Guid profileID)
|
||||
public static bool IsProfileIdValid(Guid profileId)
|
||||
{
|
||||
return profileID != Guid.Empty && _Profiles.ContainsKey(profileID);
|
||||
return profileId != Guid.Empty && _Profiles.ContainsKey(profileId);
|
||||
}
|
||||
|
||||
public static bool IsAvatarIDValid(int avatarID)
|
||||
public static bool IsAvatarIdValid(int avatarId)
|
||||
{
|
||||
return _Avatars.ContainsKey(avatarID);
|
||||
return _Avatars.ContainsKey(avatarId);
|
||||
}
|
||||
#endregion public methods
|
||||
|
||||
#region profile properties
|
||||
public static string GetPlayerName(Guid profileID, int playerNum = 0)
|
||||
public static string GetPlayerName(Guid profileId, int playerNum = 0)
|
||||
{
|
||||
if (IsProfileIDValid(profileID))
|
||||
return _Profiles[profileID].PlayerName;
|
||||
if (IsProfileIdValid(profileId))
|
||||
{
|
||||
return _Profiles[profileId].PlayerName;
|
||||
}
|
||||
|
||||
string playerName = CLanguage.Translate("TR_SCREENNAMES_PLAYER");
|
||||
var playerName = CLanguage.Translate("TR_SCREENNAMES_PLAYER");
|
||||
if (playerNum > 0)
|
||||
{
|
||||
playerName += " " + playerNum;
|
||||
}
|
||||
|
||||
return playerName;
|
||||
}
|
||||
|
||||
public static void SetPlayerName(Guid profileID, string playerName)
|
||||
public static void SetPlayerName(Guid profileId, string playerName)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID))
|
||||
if (!IsProfileIdValid(profileId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Profiles[profileID].PlayerName = playerName;
|
||||
_Profiles[profileId].PlayerName = playerName;
|
||||
}
|
||||
|
||||
public static string GetProfileFileName(Guid profileID)
|
||||
public static string GetProfileFileName(Guid profileId)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID))
|
||||
return String.Empty;
|
||||
if (!IsProfileIdValid(profileId))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
return Path.GetFileName(_Profiles[profileID].FilePath);
|
||||
return Path.GetFileName(_Profiles[profileId].FilePath);
|
||||
}
|
||||
|
||||
public static string AddGetPlayerName(Guid profileID, char chr)
|
||||
public static string AddGetPlayerName(Guid profileId, char chr)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID))
|
||||
return String.Empty;
|
||||
if (!IsProfileIdValid(profileId))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
_Profiles[profileID].PlayerName += chr;
|
||||
return _Profiles[profileID].PlayerName;
|
||||
_Profiles[profileId].PlayerName += chr;
|
||||
return _Profiles[profileId].PlayerName;
|
||||
}
|
||||
|
||||
public static string GetDeleteCharInPlayerName(Guid profileID)
|
||||
public static string GetDeleteCharInPlayerName(Guid profileId)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID))
|
||||
return String.Empty;
|
||||
if (!IsProfileIdValid(profileId))
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
CProfile profile = _Profiles[profileID];
|
||||
if (!String.IsNullOrEmpty(profile.PlayerName))
|
||||
var profile = _Profiles[profileId];
|
||||
if (!string.IsNullOrEmpty(profile.PlayerName))
|
||||
{
|
||||
profile.PlayerName = profile.PlayerName.Remove(profile.PlayerName.Length - 1);
|
||||
}
|
||||
|
||||
return profile.PlayerName;
|
||||
}
|
||||
|
||||
public static EGameDifficulty GetDifficulty(Guid profileID)
|
||||
public static EGameDifficulty GetDifficulty(Guid profileId)
|
||||
{
|
||||
return IsProfileIDValid(profileID) ? _Profiles[profileID].Difficulty : EGameDifficulty.TR_CONFIG_NORMAL;
|
||||
return IsProfileIdValid(profileId) ? _Profiles[profileId].Difficulty : EGameDifficulty.TR_CONFIG_NORMAL;
|
||||
}
|
||||
|
||||
public static void SetDifficulty(Guid profileID, EGameDifficulty difficulty)
|
||||
public static void SetDifficulty(Guid profileId, EGameDifficulty difficulty)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID))
|
||||
if (!IsProfileIdValid(profileId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Profiles[profileID].Difficulty = difficulty;
|
||||
_Profiles[profileId].Difficulty = difficulty;
|
||||
}
|
||||
|
||||
public static EUserRole GetUserRoleProfile(Guid profileID)
|
||||
public static EUserRole GetUserRoleProfile(Guid profileId)
|
||||
{
|
||||
return IsProfileIDValid(profileID) ? _Profiles[profileID].UserRole : EUserRole.TR_USERROLE_GUEST;
|
||||
return IsProfileIdValid(profileId) ? _Profiles[profileId].UserRole : EUserRole.TR_USERROLE_GUEST;
|
||||
}
|
||||
|
||||
public static void SetUserRoleProfile(Guid profileID, EUserRole option)
|
||||
public static void SetUserRoleProfile(Guid profileId, EUserRole option)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID))
|
||||
if (!IsProfileIdValid(profileId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//Only allow the change of TR_USERROLE_GUEST, TR_USERROLE_NORMAL and TR_USERROLE_ADMIN
|
||||
const EUserRole mask = (EUserRole.TR_USERROLE_GUEST | EUserRole.TR_USERROLE_NORMAL | EUserRole.TR_USERROLE_ADMIN);
|
||||
const EUserRole mask = EUserRole.TR_USERROLE_GUEST | EUserRole.TR_USERROLE_NORMAL | EUserRole.TR_USERROLE_ADMIN;
|
||||
option &= mask;
|
||||
_Profiles[profileID].UserRole = (_Profiles[profileID].UserRole & ~mask) | option;
|
||||
_Profiles[profileId].UserRole = (_Profiles[profileId].UserRole & ~mask) | option;
|
||||
}
|
||||
|
||||
public static EOffOn GetActive(Guid profileID)
|
||||
public static EOffOn GetActive(Guid profileId)
|
||||
{
|
||||
return IsProfileIDValid(profileID) ? _Profiles[profileID].Active : EOffOn.TR_CONFIG_OFF;
|
||||
return IsProfileIdValid(profileId) ? _Profiles[profileId].Active : EOffOn.TR_CONFIG_OFF;
|
||||
}
|
||||
|
||||
public static void SetActive(Guid profileID, EOffOn option)
|
||||
public static void SetActive(Guid profileId, EOffOn option)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID))
|
||||
if (!IsProfileIdValid(profileId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Profiles[profileID].Active = option;
|
||||
_Profiles[profileId].Active = option;
|
||||
}
|
||||
|
||||
public static bool IsGuestProfile(Guid profileID)
|
||||
public static bool IsGuestProfile(Guid profileId)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID))
|
||||
if (!IsProfileIdValid(profileId))
|
||||
{
|
||||
return true; // this will prevent from saving dummy profiles to highscore db
|
||||
}
|
||||
|
||||
return _Profiles[profileID].UserRole <= EUserRole.TR_USERROLE_GUEST;
|
||||
return _Profiles[profileId].UserRole <= EUserRole.TR_USERROLE_GUEST;
|
||||
}
|
||||
|
||||
public static bool IsActive(Guid profileID)
|
||||
public static bool IsActive(Guid profileId)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID))
|
||||
if (!IsProfileIdValid(profileId))
|
||||
{
|
||||
return false;
|
||||
return _Profiles[profileID].Active == EOffOn.TR_CONFIG_ON;
|
||||
}
|
||||
|
||||
return _Profiles[profileId].Active == EOffOn.TR_CONFIG_ON;
|
||||
}
|
||||
|
||||
public static void SetAvatar(Guid profileID, int avatarID)
|
||||
public static void SetAvatar(Guid profileId, int avatarId)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID) || !IsAvatarIDValid(avatarID))
|
||||
if (!IsProfileIdValid(profileId) || !IsAvatarIdValid(avatarId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Profiles[profileID].Avatar = _Avatars[avatarID];
|
||||
_Profiles[profileId].Avatar = _Avatars[avatarId];
|
||||
}
|
||||
|
||||
public static int GetAvatarID(Guid profileID)
|
||||
public static int GetAvatarId(Guid profileId)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID) || _Profiles[profileID].Avatar == null)
|
||||
if (!IsProfileIdValid(profileId) || _Profiles[profileId].Avatar == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _Profiles[profileID].Avatar.ID;
|
||||
return _Profiles[profileId].Avatar.Id;
|
||||
}
|
||||
|
||||
public static CAvatar GetAvatar(Guid profileID)
|
||||
public static CAvatar GetAvatar(Guid profileId)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID))
|
||||
if (!IsProfileIdValid(profileId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return _Profiles[profileID].Avatar;
|
||||
return _Profiles[profileId].Avatar;
|
||||
}
|
||||
|
||||
//TODO: Remove this?
|
||||
public static Guid GetProfileID(Guid num)
|
||||
public static Guid GetProfileId(Guid num)
|
||||
{
|
||||
return _Profiles[num].ID;
|
||||
return _Profiles[num].Id;
|
||||
}
|
||||
#endregion profile properties
|
||||
|
||||
#region avatar texture
|
||||
public static CTextureRef GetAvatarTexture(int avatarID)
|
||||
public static CTextureRef GetAvatarTexture(int avatarId)
|
||||
{
|
||||
if (!IsAvatarIDValid(avatarID))
|
||||
if (!IsAvatarIdValid(avatarId))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return _Avatars[avatarID].Texture;
|
||||
return _Avatars[avatarId].Texture;
|
||||
}
|
||||
|
||||
public static CTextureRef GetAvatarTextureFromProfile(Guid profileID)
|
||||
public static CTextureRef GetAvatarTextureFromProfile(Guid profileId)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID) || _Profiles[profileID].Avatar == null)
|
||||
if (!IsProfileIdValid(profileId) || _Profiles[profileId].Avatar == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return _Profiles[profileID].Avatar.Texture;
|
||||
return _Profiles[profileId].Avatar.Texture;
|
||||
}
|
||||
#endregion avatar texture
|
||||
|
||||
@@ -530,30 +616,41 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
var ids = new Guid[_Profiles.Keys.Count];
|
||||
_Profiles.Keys.CopyTo(ids, 0);
|
||||
foreach (Guid id in ids)
|
||||
foreach (var id in ids)
|
||||
{
|
||||
if (_Profiles[id].LoadProfile())
|
||||
{
|
||||
knownFiles.Add(Path.GetFileName(_Profiles[id].FilePath));
|
||||
}
|
||||
else
|
||||
{
|
||||
_Profiles.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var files = new List<string>();
|
||||
foreach (string path in CConfig.ProfileFolders)
|
||||
foreach (var path in CConfig.ProfileFolders)
|
||||
{
|
||||
files.AddRange(CHelper.ListFiles(path, "*.xml", true, true));
|
||||
}
|
||||
|
||||
foreach (string file in files)
|
||||
foreach (var file in files)
|
||||
{
|
||||
if (knownFiles.Contains(Path.GetFileName(file)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var profile = new CProfile();
|
||||
|
||||
if (profile.LoadProfile(file))
|
||||
_Profiles.Add(profile.ID, profile);
|
||||
{
|
||||
_Profiles.Add(profile.Id, profile);
|
||||
}
|
||||
}
|
||||
|
||||
_ProfilesChanged = true;
|
||||
}
|
||||
|
||||
@@ -564,79 +661,96 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
var ids = new int[_Avatars.Keys.Count];
|
||||
_Avatars.Keys.CopyTo(ids, 0);
|
||||
foreach (int id in ids)
|
||||
foreach (var id in ids)
|
||||
{
|
||||
if (_Avatars[id].Reload())
|
||||
{
|
||||
knownFiles.Add(Path.GetFileName(_Avatars[id].FileName));
|
||||
}
|
||||
else
|
||||
{
|
||||
_Avatars.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var files = new List<string>();
|
||||
foreach (string path in CConfig.ProfileFolders)
|
||||
foreach (var path in CConfig.ProfileFolders)
|
||||
{
|
||||
files.AddRange(CHelper.ListImageFiles(path, true, true));
|
||||
}
|
||||
|
||||
foreach (string file in files)
|
||||
foreach (var file in files)
|
||||
{
|
||||
if (knownFiles.Contains(Path.GetFileName(file)))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CAvatar avatar = CAvatar.GetAvatar(file);
|
||||
var avatar = CAvatar.GetAvatar(file);
|
||||
if (avatar != null)
|
||||
{
|
||||
avatar.ID = _AvatarIDs.Dequeue();
|
||||
_Avatars.Add(avatar.ID, avatar);
|
||||
avatar.Id = _AvatarIds.Dequeue();
|
||||
_Avatars.Add(avatar.Id, avatar);
|
||||
}
|
||||
}
|
||||
|
||||
_ProfilesChanged = true;
|
||||
}
|
||||
|
||||
private static void _DeleteProfile(Guid profileID)
|
||||
private static void _DeleteProfile(Guid profileId)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID))
|
||||
return;
|
||||
|
||||
if (string.IsNullOrEmpty(_Profiles[profileID].FilePath))
|
||||
if (!IsProfileIdValid(profileId))
|
||||
{
|
||||
_RemoveProfile(profileID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(_Profiles[profileId].FilePath))
|
||||
{
|
||||
_RemoveProfile(profileId);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//Check if profile saved in config
|
||||
for (int i = 0; i < CSettings.MaxNumPlayer; i++)
|
||||
for (var i = 0; i < CSettings.MaxNumPlayer; i++)
|
||||
{
|
||||
if (CConfig.Config.Game.Players[i] == GetProfileFileName(profileID))
|
||||
if (CConfig.Config.Game.Players[i] == GetProfileFileName(profileId))
|
||||
{
|
||||
CConfig.Config.Game.Players[i] = string.Empty;
|
||||
CConfig.SaveConfig();
|
||||
}
|
||||
}
|
||||
File.Delete(_Profiles[profileID].FilePath);
|
||||
_RemoveProfile(profileID);
|
||||
|
||||
File.Delete(_Profiles[profileId].FilePath);
|
||||
_RemoveProfile(profileId);
|
||||
|
||||
//Check if profile is selected in game
|
||||
for (int i = 0; i < CGame.Players.Length; i++)
|
||||
for (var i = 0; i < CGame.Players.Length; i++)
|
||||
{
|
||||
if (CGame.Players[i].ProfileID == profileID)
|
||||
CGame.Players[i].ProfileID = Guid.Empty;
|
||||
if (CGame.Players[i].ProfileId == profileId)
|
||||
{
|
||||
CGame.Players[i].ProfileId = Guid.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
CLog.Error("Can't delete Profile File " + _Profiles[profileID].FilePath);
|
||||
CLog.Error("Can't delete Profile File " + _Profiles[profileId].FilePath);
|
||||
}
|
||||
|
||||
_ProfilesChanged = true;
|
||||
}
|
||||
|
||||
private static void _RemoveProfile(Guid profileID)
|
||||
private static void _RemoveProfile(Guid profileId)
|
||||
{
|
||||
if (!IsProfileIDValid(profileID))
|
||||
if (!IsProfileIdValid(profileId))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Profiles.Remove(profileID);
|
||||
_Profiles.Remove(profileId);
|
||||
_ProfilesChanged = true;
|
||||
}
|
||||
|
||||
@@ -652,13 +766,16 @@ namespace Vocaluxe.Base
|
||||
|
||||
public static CAvatar GetAvatarByFilename(string fileName)
|
||||
{
|
||||
string name = Path.GetFileName(fileName);
|
||||
var name = Path.GetFileName(fileName);
|
||||
|
||||
foreach (int id in _Avatars.Keys)
|
||||
foreach (var id in _Avatars.Keys)
|
||||
{
|
||||
if (Path.GetFileName(_Avatars[id].FileName) == name)
|
||||
{
|
||||
return _Avatars[id];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
#endregion private methods
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
|
||||
using System.Collections.ObjectModel;
|
||||
using Vocaluxe.Lib.Sound.Record;
|
||||
using Vocaluxe.Lib.Sound.Record.PortAudio;
|
||||
using VocaluxeLib;
|
||||
#if WIN
|
||||
using Vocaluxe.Lib.Sound.Record.DirectSound;
|
||||
#endif
|
||||
using Vocaluxe.Lib.Sound.Record.PortAudio;
|
||||
using VocaluxeLib;
|
||||
|
||||
namespace Vocaluxe.Base
|
||||
{
|
||||
@@ -32,7 +32,10 @@ namespace Vocaluxe.Base
|
||||
public static bool Init()
|
||||
{
|
||||
if (_Record != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (CConfig.Config.Sound.RecordLib)
|
||||
{
|
||||
#if WIN
|
||||
@@ -41,11 +44,12 @@ namespace Vocaluxe.Base
|
||||
break;
|
||||
#endif
|
||||
|
||||
// case ERecordLib.PortAudio:
|
||||
// case ERecordLib.PortAudio:
|
||||
default:
|
||||
_Record = new CPortAudioRecord();
|
||||
break;
|
||||
}
|
||||
|
||||
return _Record.Init();
|
||||
}
|
||||
|
||||
@@ -120,15 +124,18 @@ namespace Vocaluxe.Base
|
||||
|
||||
public static ReadOnlyCollection<CRecordDevice> GetDevices()
|
||||
{
|
||||
ReadOnlyCollection<CRecordDevice> devices = _Record.RecordDevices();
|
||||
var devices = _Record.RecordDevices();
|
||||
|
||||
if (devices != null)
|
||||
{
|
||||
foreach (CRecordDevice device in devices)
|
||||
foreach (var device in devices)
|
||||
{
|
||||
for(int ch = 0; ch < device.Channels; ++ch)
|
||||
device.PlayerChannel[ch] = _GetPlayerFromMicConfig(device.Name, device.Driver, ch+1);
|
||||
for (var ch = 0; ch < device.Channels; ++ch)
|
||||
{
|
||||
device.PlayerChannel[ch] = _GetPlayerFromMicConfig(device.Name, device.Driver, ch + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
@@ -137,13 +144,16 @@ namespace Vocaluxe.Base
|
||||
|
||||
private static int _GetPlayerFromMicConfig(string device, string devicedriver, int channel)
|
||||
{
|
||||
for (int p = 0; p < CSettings.MaxNumPlayer; p++)
|
||||
for (var p = 0; p < CSettings.MaxNumPlayer; p++)
|
||||
{
|
||||
if (CConfig.Config.Record.MicConfig[p].DeviceName == device &&
|
||||
CConfig.Config.Record.MicConfig[p].DeviceDriver == devicedriver &&
|
||||
CConfig.Config.Record.MicConfig[p].Channel == channel)
|
||||
{
|
||||
return p + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
+19
-25
@@ -20,11 +20,9 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Log;
|
||||
using VocaluxeLib.Xml;
|
||||
|
||||
namespace Vocaluxe.Base
|
||||
{
|
||||
@@ -38,8 +36,6 @@ namespace Vocaluxe.Base
|
||||
// ReSharper restore UnusedMember.Global
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// This class contains settings for the program
|
||||
/// These are not editable, everything that can be changed by the user is in CConfig
|
||||
@@ -57,7 +53,6 @@ namespace Vocaluxe.Base
|
||||
//TODO: This should not be here as it can change
|
||||
//State of the program
|
||||
public static EProgramState ProgramState = EProgramState.Start;
|
||||
|
||||
|
||||
public static ERevision VersionRevision
|
||||
{
|
||||
@@ -67,14 +62,17 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
return ERevision.Alpha;
|
||||
}
|
||||
|
||||
if (Version.ToLower().Contains("beta"))
|
||||
{
|
||||
return ERevision.Beta;
|
||||
}
|
||||
|
||||
if (Version.ToLower().Contains("rc"))
|
||||
{
|
||||
return ERevision.RC;
|
||||
}
|
||||
|
||||
return ERevision.Release;
|
||||
}
|
||||
}
|
||||
@@ -113,7 +111,7 @@ namespace Vocaluxe.Base
|
||||
|
||||
public const string FileNameOldHighscoreDB = "Ultrastar.db";
|
||||
public const string FileNameCoverDB = "CoverDB.sqlite";
|
||||
|
||||
|
||||
public const string FileNameMainLog = "Vocaluxe.log";
|
||||
public const string FileNameSongLog = "Song.log";
|
||||
public const string FileNameCrashMarker = "Marker";
|
||||
@@ -204,20 +202,14 @@ namespace Vocaluxe.Base
|
||||
|
||||
public static string Version
|
||||
{
|
||||
get
|
||||
{
|
||||
return Application.ProductVersion.Split('-').First();
|
||||
}
|
||||
get { return Application.ProductVersion.Split('-').First(); }
|
||||
}
|
||||
|
||||
public static string FullVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return Application.ProductVersion;
|
||||
}
|
||||
get { return Application.ProductVersion; }
|
||||
}
|
||||
|
||||
|
||||
public static string GetFullVersionText()
|
||||
{
|
||||
return ((AssemblyTitleAttribute)Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false).First()).Title;
|
||||
@@ -231,19 +223,21 @@ namespace Vocaluxe.Base
|
||||
public static void CreateFolders()
|
||||
{
|
||||
var folders = new List<string>
|
||||
{
|
||||
Path.Combine(ProgramFolder, FolderNameCover),
|
||||
Path.Combine(ProgramFolder, FolderNameFonts),
|
||||
Path.Combine(DataFolder, FolderNameScreenshots),
|
||||
Path.Combine(ProgramFolder, FolderNameBackgroundMusic),
|
||||
Path.Combine(ProgramFolder, FolderNameSounds),
|
||||
Path.Combine(DataFolder, CConfig.FolderPlaylists)
|
||||
};
|
||||
{
|
||||
Path.Combine(ProgramFolder, FolderNameCover),
|
||||
Path.Combine(ProgramFolder, FolderNameFonts),
|
||||
Path.Combine(DataFolder, FolderNameScreenshots),
|
||||
Path.Combine(ProgramFolder, FolderNameBackgroundMusic),
|
||||
Path.Combine(ProgramFolder, FolderNameSounds),
|
||||
Path.Combine(DataFolder, CConfig.FolderPlaylists)
|
||||
};
|
||||
folders.AddRange(CConfig.ProfileFolders);
|
||||
folders.AddRange(CConfig.SongFolders);
|
||||
|
||||
foreach (string folder in folders)
|
||||
foreach (var folder in folders)
|
||||
{
|
||||
_CreateFolder(folder);
|
||||
}
|
||||
}
|
||||
|
||||
private static void _CreateFolder(string path)
|
||||
@@ -261,4 +255,4 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,10 +48,16 @@ namespace Vocaluxe.Base
|
||||
set
|
||||
{
|
||||
if (value == _Tabs)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Tabs = value;
|
||||
if (_Tabs == EOffOn.TR_CONFIG_ON)
|
||||
{
|
||||
CSongs.Category = -1;
|
||||
}
|
||||
|
||||
_SetChanged();
|
||||
}
|
||||
}
|
||||
@@ -67,7 +73,7 @@ namespace Vocaluxe.Base
|
||||
|
||||
CCategory lastCategory = null;
|
||||
CCategory noCategory = null;
|
||||
foreach (CSongPointer songPointer in CSongs.Sorter.SortedSongs)
|
||||
foreach (var songPointer in CSongs.Sorter.SortedSongs)
|
||||
{
|
||||
if (songPointer.SortString != "")
|
||||
{
|
||||
@@ -76,6 +82,7 @@ namespace Vocaluxe.Base
|
||||
lastCategory = new CCategory(songPointer.SortString);
|
||||
_Categories.Add(lastCategory);
|
||||
}
|
||||
|
||||
lastCategory.Songs.Add(songPointer);
|
||||
}
|
||||
else
|
||||
@@ -85,6 +92,7 @@ namespace Vocaluxe.Base
|
||||
noCategory = new CCategory(_GetNoCategoryName());
|
||||
_Categories.Add(noCategory);
|
||||
}
|
||||
|
||||
noCategory.Songs.Add(songPointer);
|
||||
}
|
||||
}
|
||||
@@ -95,28 +103,35 @@ namespace Vocaluxe.Base
|
||||
/// </summary>
|
||||
private static void _AdjustCategoryNames()
|
||||
{
|
||||
ESongSorting sorting = CSongs.Sorter.SongSorting;
|
||||
var sorting = CSongs.Sorter.SongSorting;
|
||||
switch (sorting)
|
||||
{
|
||||
case ESongSorting.TR_CONFIG_DECADE:
|
||||
foreach (CSongPointer songPointer in CSongs.Sorter.SortedSongs)
|
||||
foreach (var songPointer in CSongs.Sorter.SortedSongs)
|
||||
{
|
||||
string year = songPointer.SortString;
|
||||
var year = songPointer.SortString;
|
||||
if (year != "")
|
||||
{
|
||||
year = year.Substring(0, 3);
|
||||
songPointer.SortString = year + "0 - " + year + "9";
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case ESongSorting.TR_CONFIG_TITLE_LETTER:
|
||||
case ESongSorting.TR_CONFIG_ARTIST_LETTER:
|
||||
foreach (CSongPointer songPointer in CSongs.Sorter.SortedSongs)
|
||||
songPointer.SortString = (songPointer.SortString.Length == 0 || !Char.IsLetter(songPointer.SortString, 0)) ? "#" : songPointer.SortString[0].ToString();
|
||||
foreach (var songPointer in CSongs.Sorter.SortedSongs)
|
||||
{
|
||||
songPointer.SortString = songPointer.SortString.Length == 0 || !Char.IsLetter(songPointer.SortString, 0) ? "#" : songPointer.SortString[0].ToString();
|
||||
}
|
||||
|
||||
break;
|
||||
case ESongSorting.TR_CONFIG_DATEADDED:
|
||||
foreach (CSongPointer songPointer in CSongs.Sorter.SortedSongs)
|
||||
songPointer.SortString = CSongs.GetSong(songPointer.SongID).DateAdded.ToString("dd/MM/yyyy");
|
||||
foreach (var songPointer in CSongs.Sorter.SortedSongs)
|
||||
{
|
||||
songPointer.SortString = CSongs.GetSong(songPointer.SongId).DateAdded.ToString("dd/MM/yyyy");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -161,18 +176,23 @@ namespace Vocaluxe.Base
|
||||
Debug.Assert(false, "Forgot category option");
|
||||
break;
|
||||
}
|
||||
|
||||
return noCategoryName;
|
||||
}
|
||||
|
||||
private void _FillCategories()
|
||||
{
|
||||
if (!_Changed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Categories.Clear();
|
||||
|
||||
if (_Tabs != EOffOn.TR_CONFIG_OFF)
|
||||
{
|
||||
_CreateCategories();
|
||||
}
|
||||
else
|
||||
{
|
||||
//No categories. So don't create them!
|
||||
@@ -180,13 +200,16 @@ namespace Vocaluxe.Base
|
||||
_Categories[0].Songs.AddRange(CSongs.Sorter.SortedSongs);
|
||||
}
|
||||
|
||||
foreach (CCategory cat in _Categories)
|
||||
foreach (var cat in _Categories)
|
||||
{
|
||||
cat.CoverTextureSmall = CCover.Cover(cat.Name);
|
||||
if (cat.CoverTextureSmall == CCover.NoCover)
|
||||
{
|
||||
cat.CoverTextureSmall = CCover.GenerateCover(cat.Name, CCover._SongSortingToType(CSongs.Sorter.SongSorting), cat.GetSong(0));
|
||||
}
|
||||
}
|
||||
|
||||
_Changed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,9 +27,9 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
private readonly List<CSong> _FilteredSongs = new List<CSong>();
|
||||
|
||||
private String _SearchString = String.Empty;
|
||||
private String _SearchString = string.Empty;
|
||||
private EDuetOptions _DuetOptions = EDuetOptions.All;
|
||||
private int _PlaylistID = -1;
|
||||
private int _PlaylistId = -1;
|
||||
|
||||
public List<CSong> FilteredSongs
|
||||
{
|
||||
@@ -71,13 +71,13 @@ namespace Vocaluxe.Base
|
||||
SetOptions(searchString, duetOptions, -1);
|
||||
}
|
||||
|
||||
public void SetOptions(String searchString, EDuetOptions duetOptions, int playlistID)
|
||||
public void SetOptions(String searchString, EDuetOptions duetOptions, int playlistId)
|
||||
{
|
||||
if (searchString != _SearchString || duetOptions != _DuetOptions || playlistID != _PlaylistID)
|
||||
if (searchString != _SearchString || duetOptions != _DuetOptions || playlistId != _PlaylistId)
|
||||
{
|
||||
_SearchString = searchString;
|
||||
_DuetOptions = duetOptions;
|
||||
_PlaylistID = playlistID;
|
||||
_PlaylistId = playlistId;
|
||||
_SetChanged();
|
||||
}
|
||||
}
|
||||
@@ -85,36 +85,42 @@ namespace Vocaluxe.Base
|
||||
private void _FilterSongs()
|
||||
{
|
||||
if (!_Changed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_FilteredSongs.Clear();
|
||||
|
||||
string[] searchStrings = null;
|
||||
if (_SearchString != "")
|
||||
searchStrings = _SearchString.ToUpper().Split(new char[] {' '});
|
||||
{
|
||||
searchStrings = _SearchString.ToUpper().Split(new char[] { ' ' });
|
||||
}
|
||||
|
||||
String searchForArtist = null; // a:
|
||||
String searchForTitle = null; // t:
|
||||
String searchForGenre = null; // g:
|
||||
String searchForYear = null; // y:
|
||||
String searchForLanguage = null; // l:
|
||||
String searchForCreator = null; // c:
|
||||
String searchForEdition = null; // e:
|
||||
String searchForTags = null; // #:
|
||||
String searchForAlbum = null; // al:
|
||||
String searchForFileName = null; // fi:
|
||||
String searchForFolderName = null; // fo:
|
||||
bool expertSearch = false;
|
||||
String searchForArtist = null; // a:
|
||||
String searchForTitle = null; // t:
|
||||
String searchForGenre = null; // g:
|
||||
String searchForYear = null; // y:
|
||||
String searchForLanguage = null; // l:
|
||||
String searchForCreator = null; // c:
|
||||
String searchForEdition = null; // e:
|
||||
String searchForTags = null; // #:
|
||||
String searchForAlbum = null; // al:
|
||||
String searchForFileName = null; // fi:
|
||||
String searchForFolderName = null; // fo:
|
||||
var expertSearch = false;
|
||||
|
||||
if (searchStrings != null)
|
||||
{
|
||||
foreach (String searchToken in searchStrings)
|
||||
foreach (var searchToken in searchStrings)
|
||||
{
|
||||
if (searchToken.Length < 3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String temp = searchToken.Substring(0, 2);
|
||||
bool foundIt = true;
|
||||
var temp = searchToken.Substring(0, 2);
|
||||
var foundIt = true;
|
||||
|
||||
switch (temp)
|
||||
{
|
||||
@@ -149,12 +155,18 @@ namespace Vocaluxe.Base
|
||||
|
||||
if (foundIt)
|
||||
{
|
||||
if (!expertSearch) expertSearch = true;
|
||||
if (!expertSearch)
|
||||
{
|
||||
expertSearch = true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (searchToken.Length < 4)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foundIt = true;
|
||||
temp = searchToken.Substring(0, 3);
|
||||
@@ -176,114 +188,163 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
|
||||
if (foundIt && !expertSearch)
|
||||
{
|
||||
expertSearch = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (CSong song in CSongs.Songs)
|
||||
foreach (var song in CSongs.Songs)
|
||||
{
|
||||
if (_PlaylistID != -1 && !CBase.Playlist.ContainsSong(_PlaylistID, song.ID))
|
||||
if (_PlaylistId != -1 && !CBase.Playlist.ContainsSong(_PlaylistId, song.Id))
|
||||
{
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
if ((song.IsDuet && _DuetOptions != EDuetOptions.NoDuets) || (!song.IsDuet && _DuetOptions != EDuetOptions.Duets))
|
||||
{
|
||||
if (searchStrings == null)
|
||||
{
|
||||
_FilteredSongs.Add(song);
|
||||
}
|
||||
else if (expertSearch)
|
||||
{
|
||||
// Stefan1200: Stop at a maximum of 800 search result to prevent performance issues
|
||||
if (_FilteredSongs.Count >= 800)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (searchForAlbum != null && song.Album.ToUpper().Contains(searchForAlbum))
|
||||
{
|
||||
_FilteredSongs.Add(song);
|
||||
}
|
||||
|
||||
if (searchForArtist != null && song.Artist.ToUpper().Contains(searchForArtist))
|
||||
{
|
||||
_FilteredSongs.Add(song);
|
||||
}
|
||||
|
||||
if (searchForTitle != null && song.Title.ToUpper().Contains(searchForTitle))
|
||||
{
|
||||
_FilteredSongs.Add(song);
|
||||
}
|
||||
|
||||
if (searchForCreator != null && song.Creator.ToUpper().Contains(searchForCreator))
|
||||
{
|
||||
_FilteredSongs.Add(song);
|
||||
}
|
||||
|
||||
if (searchForFileName != null && song.FileName.ToUpper().Contains(searchForFileName))
|
||||
{
|
||||
_FilteredSongs.Add(song);
|
||||
}
|
||||
|
||||
if (searchForFolderName != null && song.FolderName.ToUpper().Contains(searchForFolderName))
|
||||
{
|
||||
_FilteredSongs.Add(song);
|
||||
}
|
||||
|
||||
if (searchForGenre != null)
|
||||
{
|
||||
foreach (String genre in song.Genres)
|
||||
foreach (var genre in song.Genres)
|
||||
{
|
||||
if (genre.ToUpper().Contains(searchForGenre))
|
||||
{
|
||||
_FilteredSongs.Add(song);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (searchForLanguage != null)
|
||||
{
|
||||
foreach (String language in song.Languages)
|
||||
foreach (var language in song.Languages)
|
||||
{
|
||||
if (language.ToUpper().Contains(searchForLanguage))
|
||||
{
|
||||
_FilteredSongs.Add(song);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (searchForEdition != null)
|
||||
{
|
||||
foreach (String edition in song.Editions)
|
||||
foreach (var edition in song.Editions)
|
||||
{
|
||||
if (edition.ToUpper().Contains(searchForEdition))
|
||||
{
|
||||
_FilteredSongs.Add(song);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (searchForTags != null)
|
||||
{
|
||||
foreach (String tag in song.Tags)
|
||||
foreach (var tag in song.Tags)
|
||||
{
|
||||
if (tag.ToUpper().Contains(searchForTags))
|
||||
{
|
||||
_FilteredSongs.Add(song);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (searchForYear != null)
|
||||
{
|
||||
int pos = searchForYear.IndexOf("-");
|
||||
var pos = searchForYear.IndexOf("-");
|
||||
if (pos == -1)
|
||||
{
|
||||
if (song.Year.Contains(searchForYear))
|
||||
{
|
||||
_FilteredSongs.Add(song);
|
||||
}
|
||||
}
|
||||
else if (searchForYear.Length == 9)
|
||||
{
|
||||
int yearStart = -1;
|
||||
int yearEnd = -1;
|
||||
var yearStart = -1;
|
||||
var yearEnd = -1;
|
||||
if (!Int32.TryParse(searchForYear.Substring(0, pos), out yearStart))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!Int32.TryParse(searchForYear.Substring(pos + 1), out yearEnd))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Stefan1200: Prevent searches like 0000-9999, limit for a max distance of 100 years
|
||||
if (yearEnd - yearStart > 100)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int yearSearch = -1;
|
||||
var yearSearch = -1;
|
||||
if (!Int32.TryParse(song.Year, out yearSearch))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (yearSearch >= yearStart && yearSearch <= yearEnd)
|
||||
{
|
||||
_FilteredSongs.Add(song);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string search = song.Title.ToUpper() + " " + song.Artist.ToUpper();
|
||||
var search = song.Title.ToUpper() + " " + song.Artist.ToUpper();
|
||||
|
||||
if (searchStrings.All(search.Contains))
|
||||
{
|
||||
_FilteredSongs.Add(song);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_Changed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,10 @@ namespace Vocaluxe.Base
|
||||
set
|
||||
{
|
||||
if (value == _IgnoreArticles)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_IgnoreArticles = value;
|
||||
_SetChanged();
|
||||
}
|
||||
@@ -62,7 +65,10 @@ namespace Vocaluxe.Base
|
||||
set
|
||||
{
|
||||
if (value == _SongSorting)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_SongSorting = value;
|
||||
_SetChanged();
|
||||
}
|
||||
@@ -85,29 +91,32 @@ namespace Vocaluxe.Base
|
||||
|
||||
private int _SortByFieldArtistTitle(CSongPointer s1, CSongPointer s2)
|
||||
{
|
||||
int res = String.Compare(s1.SortString, s2.SortString, StringComparison.CurrentCultureIgnoreCase);
|
||||
var res = String.Compare(s1.SortString, s2.SortString, StringComparison.CurrentCultureIgnoreCase);
|
||||
if (res == 0)
|
||||
{
|
||||
if (_IgnoreArticles == EOffOn.TR_CONFIG_ON)
|
||||
{
|
||||
res = String.Compare(CSongs.Songs[s1.SongID].ArtistSorting, CSongs.Songs[s2.SongID].ArtistSorting, StringComparison.CurrentCultureIgnoreCase);
|
||||
return res != 0 ? res : String.Compare(CSongs.Songs[s1.SongID].TitleSorting, CSongs.Songs[s2.SongID].TitleSorting, StringComparison.CurrentCultureIgnoreCase);
|
||||
res = String.Compare(CSongs.Songs[s1.SongId].ArtistSorting, CSongs.Songs[s2.SongId].ArtistSorting, StringComparison.CurrentCultureIgnoreCase);
|
||||
return res != 0 ? res : String.Compare(CSongs.Songs[s1.SongId].TitleSorting, CSongs.Songs[s2.SongId].TitleSorting, StringComparison.CurrentCultureIgnoreCase);
|
||||
}
|
||||
res = String.Compare(CSongs.Songs[s1.SongID].Artist, CSongs.Songs[s2.SongID].Artist, StringComparison.CurrentCultureIgnoreCase);
|
||||
return res != 0 ? res : String.Compare(CSongs.Songs[s1.SongID].Title, CSongs.Songs[s2.SongID].Title, StringComparison.CurrentCultureIgnoreCase);
|
||||
|
||||
res = String.Compare(CSongs.Songs[s1.SongId].Artist, CSongs.Songs[s2.SongId].Artist, StringComparison.CurrentCultureIgnoreCase);
|
||||
return res != 0 ? res : String.Compare(CSongs.Songs[s1.SongId].Title, CSongs.Songs[s2.SongId].Title, StringComparison.CurrentCultureIgnoreCase);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private int _SortByFieldTitle(CSongPointer s1, CSongPointer s2)
|
||||
{
|
||||
int res = String.Compare(s1.SortString, s2.SortString, StringComparison.CurrentCultureIgnoreCase);
|
||||
var res = String.Compare(s1.SortString, s2.SortString, StringComparison.CurrentCultureIgnoreCase);
|
||||
if (res == 0)
|
||||
{
|
||||
return _IgnoreArticles == EOffOn.TR_CONFIG_ON
|
||||
? String.Compare(CSongs.Songs[s1.SongID].TitleSorting, CSongs.Songs[s2.SongID].TitleSorting, StringComparison.CurrentCultureIgnoreCase) :
|
||||
String.Compare(CSongs.Songs[s1.SongID].Title, CSongs.Songs[s2.SongID].Title, StringComparison.CurrentCultureIgnoreCase);
|
||||
? String.Compare(CSongs.Songs[s1.SongId].TitleSorting, CSongs.Songs[s2.SongId].TitleSorting, StringComparison.CurrentCultureIgnoreCase) :
|
||||
String.Compare(CSongs.Songs[s1.SongId].Title, CSongs.Songs[s2.SongId].Title, StringComparison.CurrentCultureIgnoreCase);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -116,7 +125,7 @@ namespace Vocaluxe.Base
|
||||
/// </summary>
|
||||
private int _SortByLetterFieldTitle(CSongPointer s1, CSongPointer s2)
|
||||
{
|
||||
int res = String.Compare(s1.SortString[0].ToString(), s2.SortString[0].ToString(), StringComparison.CurrentCultureIgnoreCase);
|
||||
var res = String.Compare(s1.SortString[0].ToString(), s2.SortString[0].ToString(), StringComparison.CurrentCultureIgnoreCase);
|
||||
return res != 0 ? res : _SortByFieldTitle(s1, s2);
|
||||
}
|
||||
|
||||
@@ -125,7 +134,7 @@ namespace Vocaluxe.Base
|
||||
/// </summary>
|
||||
private int _SortByLetterFieldArtistTitle(CSongPointer s1, CSongPointer s2)
|
||||
{
|
||||
int res = String.Compare(s1.SortString[0].ToString(), s2.SortString[0].ToString(), StringComparison.CurrentCultureIgnoreCase);
|
||||
var res = String.Compare(s1.SortString[0].ToString(), s2.SortString[0].ToString(), StringComparison.CurrentCultureIgnoreCase);
|
||||
return res != 0 ? res : _SortByFieldArtistTitle(s1, s2);
|
||||
}
|
||||
|
||||
@@ -171,26 +180,38 @@ namespace Vocaluxe.Base
|
||||
Debug.Assert(false, "Forgot sorting option");
|
||||
break;
|
||||
}
|
||||
|
||||
Debug.Assert(value != null || values != null, "Sorting implementation faulty");
|
||||
if (value != null)
|
||||
list.Add(new CSongPointer(song.ID, value));
|
||||
{
|
||||
list.Add(new CSongPointer(song.Id, value));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (values.Count == 0)
|
||||
list.Add(new CSongPointer(song.ID, ""));
|
||||
{
|
||||
list.Add(new CSongPointer(song.Id, ""));
|
||||
}
|
||||
else
|
||||
list.AddRange(values.Select(val => new CSongPointer(song.ID, val)));
|
||||
{
|
||||
list.AddRange(values.Select(val => new CSongPointer(song.Id, val)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void _SortSongs()
|
||||
{
|
||||
if (!_Changed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
List<CSongPointer> sortList = new List<CSongPointer>();
|
||||
foreach (CSong song in CSongs.Filter.FilteredSongs)
|
||||
var sortList = new List<CSongPointer>();
|
||||
foreach (var song in CSongs.Filter.FilteredSongs)
|
||||
{
|
||||
_AddSongToList(song, sortList);
|
||||
}
|
||||
|
||||
switch (_SongSorting)
|
||||
{
|
||||
case ESongSorting.TR_CONFIG_ARTIST:
|
||||
@@ -209,10 +230,12 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
|
||||
if (_SongSorting == ESongSorting.TR_CONFIG_DATEADDED)
|
||||
{
|
||||
sortList.Reverse();
|
||||
}
|
||||
|
||||
_SortedSongs = sortList.ToArray();
|
||||
_Changed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+130
-67
@@ -19,9 +19,9 @@ using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Log;
|
||||
@@ -33,7 +33,6 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
public delegate void CategoryChangedHandler();
|
||||
|
||||
private static readonly List<CSong> _Songs = new List<CSong>();
|
||||
private static readonly List<CSong> _SongsForRandom = new List<CSong>();
|
||||
|
||||
private static bool _CoverLoaded;
|
||||
@@ -47,10 +46,7 @@ namespace Vocaluxe.Base
|
||||
private static Thread _CoverLoaderThread;
|
||||
public static event CategoryChangedHandler OnCategoryChanged;
|
||||
|
||||
public static List<CSong> Songs
|
||||
{
|
||||
get { return _Songs; }
|
||||
}
|
||||
public static List<CSong> Songs { get; } = new List<CSong>();
|
||||
|
||||
public static bool SongsLoaded { get; private set; }
|
||||
|
||||
@@ -59,14 +55,17 @@ namespace Vocaluxe.Base
|
||||
get
|
||||
{
|
||||
if (SongsLoaded && NumAllSongs == 0)
|
||||
{
|
||||
_CoverLoaded = true;
|
||||
}
|
||||
|
||||
return _CoverLoaded;
|
||||
}
|
||||
}
|
||||
|
||||
public static int NumAllSongs
|
||||
{
|
||||
get { return _Songs.Count; }
|
||||
get { return Songs.Count; }
|
||||
}
|
||||
|
||||
public static int NumSongsVisible
|
||||
@@ -84,18 +83,26 @@ namespace Vocaluxe.Base
|
||||
get
|
||||
{
|
||||
if (_CatIndex >= Categories.Count)
|
||||
{
|
||||
_CatIndex = -1;
|
||||
}
|
||||
|
||||
return _CatIndex;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (value == _CatIndex)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (value == -1 || _IsCatIndexValid(value))
|
||||
{
|
||||
_CatIndex = value;
|
||||
if (OnCategoryChanged != null)
|
||||
{
|
||||
OnCategoryChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,17 +140,25 @@ namespace Vocaluxe.Base
|
||||
public static void NextCategory()
|
||||
{
|
||||
if (Category == Categories.Count - 1)
|
||||
{
|
||||
Category = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Category++;
|
||||
}
|
||||
}
|
||||
|
||||
public static void PrevCategory()
|
||||
{
|
||||
if (Category == 0)
|
||||
{
|
||||
Category = Categories.Count - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Category--;
|
||||
}
|
||||
}
|
||||
|
||||
private static int _NumSongsWithCoverLoaded;
|
||||
@@ -164,20 +179,23 @@ namespace Vocaluxe.Base
|
||||
return _IsCatIndexValid(_CatIndex) ? Categories[_CatIndex].Name : "";
|
||||
}
|
||||
|
||||
public static CSong GetSong(int songID)
|
||||
public static CSong GetSong(int songId)
|
||||
{
|
||||
return songID >= 0 && songID < _Songs.Count ? _Songs[songID] : null;
|
||||
return songId >= 0 && songId < Songs.Count ? Songs[songId] : null;
|
||||
}
|
||||
|
||||
public static void AddPartySongSung(int songID)
|
||||
public static void AddPartySongSung(int songId)
|
||||
{
|
||||
foreach (CCategory category in Categories)
|
||||
foreach (var category in Categories)
|
||||
{
|
||||
foreach (CSongPointer song in category.Songs.Where(song => song.SongID == songID))
|
||||
foreach (var song in category.Songs.Where(song => song.SongId == songId))
|
||||
{
|
||||
song.IsSung = true;
|
||||
if (category.GetNumSongsNotSung() == 0)
|
||||
{
|
||||
ResetPartySongSung(_GetCategoryNumber(category));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -185,74 +203,95 @@ namespace Vocaluxe.Base
|
||||
|
||||
public static void ResetPartySongSung()
|
||||
{
|
||||
foreach (CSongPointer song in Sorter.SortedSongs)
|
||||
foreach (var song in Sorter.SortedSongs)
|
||||
{
|
||||
song.IsSung = false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ResetPartySongSung(int catIndex)
|
||||
{
|
||||
if (_IsCatIndexValid(catIndex))
|
||||
{
|
||||
foreach (CSongPointer song in Categories[catIndex].Songs)
|
||||
foreach (var song in Categories[catIndex].Songs)
|
||||
{
|
||||
song.IsSung = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetVisibleSongNumber(int songID)
|
||||
public static int GetVisibleSongNumber(int songId)
|
||||
{
|
||||
int i = -1;
|
||||
foreach (CSong song in VisibleSongs)
|
||||
var i = -1;
|
||||
foreach (var song in VisibleSongs)
|
||||
{
|
||||
i++;
|
||||
if (song.ID == songID)
|
||||
if (song.Id == songId)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public static int GetRandomSong()
|
||||
{
|
||||
if (_SongsForRandom.Count == 0)
|
||||
{
|
||||
UpdateRandomSongList();
|
||||
}
|
||||
|
||||
if (_SongsForRandom.Count == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
CSong song = _SongsForRandom[CGame.Rand.Next(0, _SongsForRandom.Count - 1)];
|
||||
var song = _SongsForRandom[CGame.Rand.Next(0, _SongsForRandom.Count - 1)];
|
||||
_SongsForRandom.Remove(song);
|
||||
return GetVisibleSongNumber(song.ID);
|
||||
return GetVisibleSongNumber(song.Id);
|
||||
}
|
||||
|
||||
public static void UpdateRandomSongList()
|
||||
{
|
||||
_SongsForRandom.Clear();
|
||||
List<CSong> visibleSongs = VisibleSongs.ToList();
|
||||
var visibleSongs = VisibleSongs.ToList();
|
||||
if (visibleSongs.Count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Calc average sing-count
|
||||
int totalCounts = visibleSongs.Sum(song => song.NumPlayedSession);
|
||||
int averageCount = totalCounts / visibleSongs.Count;
|
||||
var totalCounts = visibleSongs.Sum(song => song.NumPlayedSession);
|
||||
var averageCount = totalCounts / visibleSongs.Count;
|
||||
|
||||
foreach (CSong song in visibleSongs)
|
||||
foreach (var song in visibleSongs)
|
||||
{
|
||||
if (song.NumPlayedSession <= averageCount)
|
||||
{
|
||||
_SongsForRandom.Add(song);
|
||||
}
|
||||
}
|
||||
|
||||
if (_SongsForRandom.Count == 0)
|
||||
{
|
||||
_SongsForRandom.AddRange(visibleSongs);
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetRandomCategory()
|
||||
{
|
||||
if (_CategoriesForRandom.Count == 0)
|
||||
{
|
||||
UpdateRandomCategoryList();
|
||||
}
|
||||
|
||||
if (_CategoriesForRandom.Count == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
CCategory category = _CategoriesForRandom[CGame.Rand.Next(0, _CategoriesForRandom.Count - 1)];
|
||||
var category = _CategoriesForRandom[CGame.Rand.Next(0, _CategoriesForRandom.Count - 1)];
|
||||
_CategoriesForRandom.Remove(category);
|
||||
return _GetCategoryNumber(category);
|
||||
}
|
||||
@@ -265,17 +304,20 @@ namespace Vocaluxe.Base
|
||||
|
||||
private static int _GetCategoryNumber(CCategory category)
|
||||
{
|
||||
for (int i = 0; i < Categories.Count; i++)
|
||||
for (var i = 0; i < Categories.Count; i++)
|
||||
{
|
||||
if (Categories[i] == category)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static ReadOnlyCollection<CSong> AllSongs
|
||||
{
|
||||
get { return _Songs.AsReadOnly(); }
|
||||
get { return Songs.AsReadOnly(); }
|
||||
}
|
||||
|
||||
public static ReadOnlyCollection<CSong> VisibleSongs
|
||||
@@ -286,13 +328,16 @@ namespace Vocaluxe.Base
|
||||
if (_IsCatIndexValid(_CatIndex))
|
||||
{
|
||||
// ReSharper disable LoopCanBeConvertedToQuery
|
||||
foreach (CSongPointer sp in Categories[_CatIndex].Songs)
|
||||
foreach (var sp in Categories[_CatIndex].Songs)
|
||||
// ReSharper restore LoopCanBeConvertedToQuery
|
||||
{
|
||||
if (!sp.IsSung)
|
||||
songs.Add(_Songs[sp.SongID]);
|
||||
{
|
||||
songs.Add(Songs[sp.SongId]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return songs.AsReadOnly();
|
||||
}
|
||||
}
|
||||
@@ -310,7 +355,9 @@ namespace Vocaluxe.Base
|
||||
public static CCategory GetCategoryByIndex(int index)
|
||||
{
|
||||
if (!_IsCatIndexValid(index))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return Categorizer.Categories[index];
|
||||
}
|
||||
@@ -323,9 +370,12 @@ namespace Vocaluxe.Base
|
||||
public static CSong GetVisibleSongByIndex(int index)
|
||||
{
|
||||
if (index < 0)
|
||||
{
|
||||
return null;
|
||||
ReadOnlyCollection<CSong> visSongs = VisibleSongs;
|
||||
return (index < visSongs.Count) ? visSongs[index] : null;
|
||||
}
|
||||
|
||||
var visSongs = VisibleSongs;
|
||||
return index < visSongs.Count ? visSongs[index] : null;
|
||||
}
|
||||
|
||||
private static void _HandleCategoriesChanged(object sender, EventArgs args)
|
||||
@@ -333,9 +383,9 @@ namespace Vocaluxe.Base
|
||||
_CategoriesForRandom.Clear();
|
||||
}
|
||||
|
||||
public static void Sort(ESongSorting sorting, EOffOn tabs, EOffOn ignoreArticles, String searchString, EDuetOptions duetOptions, int playlistID)
|
||||
public static void Sort(ESongSorting sorting, EOffOn tabs, EOffOn ignoreArticles, String searchString, EDuetOptions duetOptions, int playlistId)
|
||||
{
|
||||
Filter.SetOptions(searchString, duetOptions, playlistID);
|
||||
Filter.SetOptions(searchString, duetOptions, playlistId);
|
||||
Sorter.SetOptions(sorting, ignoreArticles);
|
||||
Categorizer.Tabs = tabs;
|
||||
}
|
||||
@@ -345,22 +395,26 @@ namespace Vocaluxe.Base
|
||||
using (CBenchmark.Time("Load Songs"))
|
||||
{
|
||||
SongsLoaded = false;
|
||||
_Songs.Clear();
|
||||
Songs.Clear();
|
||||
_NumSongsLoaded = 0;
|
||||
|
||||
IEnumerable<string> files;
|
||||
|
||||
|
||||
using (CBenchmark.Time("List Songs"))
|
||||
{
|
||||
var fileSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
foreach (string path in CConfig.SongFolders)
|
||||
foreach (var path in CConfig.SongFolders)
|
||||
{
|
||||
if (!Directory.Exists(path))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (string file in CHelper.ListTextFiles(path, true, true))
|
||||
foreach (var file in CHelper.ListTextFiles(path, true, true))
|
||||
{
|
||||
fileSet.Add(file);
|
||||
}
|
||||
}
|
||||
|
||||
files = fileSet;
|
||||
@@ -377,9 +431,11 @@ namespace Vocaluxe.Base
|
||||
|
||||
Parallel.ForEach(fileList, options, file =>
|
||||
{
|
||||
CSong song = CSong.LoadSong(file);
|
||||
var song = CSong.LoadSong(file);
|
||||
if (song == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (song.LoadNotes())
|
||||
{
|
||||
@@ -388,45 +444,50 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
});
|
||||
|
||||
int id = 0;
|
||||
foreach (CSong song in bag.OrderBy(s => s.Folder).ThenBy(s => s.FileName))
|
||||
var id = 0;
|
||||
foreach (var song in bag.OrderBy(s => s.Folder).ThenBy(s => s.FileName))
|
||||
{
|
||||
song.ID = id++;
|
||||
_Songs.Add(song);
|
||||
song.Id = id++;
|
||||
Songs.Add(song);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
using (CBenchmark.Time("Sorted Songs"))
|
||||
{
|
||||
Sorter.SongSorting = CConfig.Config.Game.SongSorting;
|
||||
Sorter.IgnoreArticles = CConfig.Config.Game.IgnoreArticles;
|
||||
Categorizer.Tabs = CConfig.Config.Game.Tabs;
|
||||
Categorizer.ObjectChanged += _HandleCategoriesChanged;
|
||||
}
|
||||
|
||||
Category = -1;
|
||||
SongsLoaded = true;
|
||||
using (CBenchmark.Time("Sorted Songs"))
|
||||
{
|
||||
Sorter.SongSorting = CConfig.Config.Game.SongSorting;
|
||||
Sorter.IgnoreArticles = CConfig.Config.Game.IgnoreArticles;
|
||||
Categorizer.Tabs = CConfig.Config.Game.Tabs;
|
||||
Categorizer.ObjectChanged += _HandleCategoriesChanged;
|
||||
}
|
||||
|
||||
switch (CConfig.Config.Theme.CoverLoading)
|
||||
{
|
||||
case ECoverLoading.TR_CONFIG_COVERLOADING_ATSTART:
|
||||
_LoadCovers();
|
||||
break;
|
||||
case ECoverLoading.TR_CONFIG_COVERLOADING_DYNAMIC:
|
||||
_LoadCoversAsync();
|
||||
break;
|
||||
}
|
||||
Category = -1;
|
||||
SongsLoaded = true;
|
||||
|
||||
switch (CConfig.Config.Theme.CoverLoading)
|
||||
{
|
||||
case ECoverLoading.TR_CONFIG_COVERLOADING_ATSTART:
|
||||
_LoadCovers();
|
||||
break;
|
||||
case ECoverLoading.TR_CONFIG_COVERLOADING_DYNAMIC:
|
||||
_LoadCoversAsync();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void _LoadCoversAsync()
|
||||
{
|
||||
if (!SongsLoaded || CoverLoaded)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_CoverLoaderThread != null)
|
||||
{
|
||||
return;
|
||||
_CoverLoaderThread = new Thread(_LoadCovers) {Name = "CoverLoader", Priority = ThreadPriority.BelowNormal, IsBackground = true};
|
||||
}
|
||||
|
||||
_CoverLoaderThread = new Thread(_LoadCovers) { Name = "CoverLoader", Priority = ThreadPriority.BelowNormal, IsBackground = true };
|
||||
_CoverLoaderThread.Start();
|
||||
}
|
||||
|
||||
@@ -434,18 +495,20 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
using (CBenchmark.Time("Loaded Covers"))
|
||||
{
|
||||
int songCount = _Songs.Count;
|
||||
AutoResetEvent ev = new AutoResetEvent(songCount == 0);
|
||||
var songCount = Songs.Count;
|
||||
var ev = new AutoResetEvent(songCount == 0);
|
||||
|
||||
NumSongsWithCoverLoaded = 0;
|
||||
foreach (CSong song in _Songs)
|
||||
foreach (var song in Songs)
|
||||
{
|
||||
CSong tmp = song;
|
||||
var tmp = song;
|
||||
Task.Factory.StartNew(() =>
|
||||
{
|
||||
tmp.LoadSmallCover();
|
||||
if (Interlocked.Increment(ref _NumSongsWithCoverLoaded) >= songCount)
|
||||
{
|
||||
ev.Set();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -455,4 +518,4 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+26
-8
@@ -16,13 +16,13 @@
|
||||
#endregion
|
||||
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using Vocaluxe.Lib.Sound;
|
||||
using Vocaluxe.Lib.Sound.Playback;
|
||||
using Vocaluxe.Lib.Sound.Playback.GstreamerSharp;
|
||||
using Vocaluxe.Lib.Sound.Playback.OpenAL;
|
||||
using Vocaluxe.Lib.Sound.Playback.PortAudio;
|
||||
using VocaluxeLib;
|
||||
using System.Threading;
|
||||
using Vocaluxe.Lib.Sound;
|
||||
|
||||
namespace Vocaluxe.Base
|
||||
{
|
||||
@@ -45,7 +45,10 @@ namespace Vocaluxe.Base
|
||||
public static bool Init()
|
||||
{
|
||||
if (_Playback != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (CConfig.Config.Sound.PlayBackLib)
|
||||
{
|
||||
case EPlaybackLib.PortAudio:
|
||||
@@ -64,6 +67,7 @@ namespace Vocaluxe.Base
|
||||
_Playback = new CPortAudioPlay();
|
||||
break;
|
||||
}
|
||||
|
||||
return _Playback.Init();
|
||||
}
|
||||
|
||||
@@ -84,13 +88,18 @@ namespace Vocaluxe.Base
|
||||
public static void CloseAllStreams()
|
||||
{
|
||||
if (_Playback != null)
|
||||
{
|
||||
_Playback.CloseAll();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Close()
|
||||
{
|
||||
if (_Playback != null)
|
||||
{
|
||||
_Playback.Close();
|
||||
}
|
||||
|
||||
_Playback = null;
|
||||
}
|
||||
|
||||
@@ -180,13 +189,12 @@ namespace Vocaluxe.Base
|
||||
_Playback.SetPosition(stream, position);
|
||||
}
|
||||
#endregion Stream Handling
|
||||
|
||||
#endregion Playback
|
||||
|
||||
#region Sounds
|
||||
public static int PlaySound(ESounds sound, bool fade = true)
|
||||
{
|
||||
string file = Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameSounds);
|
||||
var file = Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameSounds);
|
||||
switch (sound)
|
||||
{
|
||||
case ESounds.T440:
|
||||
@@ -215,30 +223,40 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
|
||||
if (!File.Exists(file))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int stream = Load(file, false, fade);
|
||||
var stream = Load(file, false, fade);
|
||||
if (stream < 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
Play(stream);
|
||||
if (fade)
|
||||
{
|
||||
float length = -1f;
|
||||
for (int i = 0; i < 5; i++)
|
||||
var length = -1f;
|
||||
for (var i = 0; i < 5; i++)
|
||||
{
|
||||
length = GetLength(stream);
|
||||
if (length >= 0f)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(1);
|
||||
}
|
||||
|
||||
if (length > 0f)
|
||||
{
|
||||
SetStreamVolume(stream, 0);
|
||||
Fade(stream, 100, length);
|
||||
}
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
#endregion Sounds
|
||||
}
|
||||
}
|
||||
}
|
||||
+58
-25
@@ -27,18 +27,18 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
private static readonly Stopwatch _Stopwatch = new Stopwatch();
|
||||
private static float _Fps;
|
||||
private static readonly double _NanosecPerTick = (1000.0 * 1000.0 * 1000.0) / Stopwatch.Frequency;
|
||||
private static readonly double _NanosecPerTick = 1000.0 * 1000.0 * 1000.0 / Stopwatch.Frequency;
|
||||
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
public static void Reset()
|
||||
// ReSharper restore MemberCanBePrivate.Global
|
||||
// ReSharper restore MemberCanBePrivate.Global
|
||||
{
|
||||
_Stopwatch.Reset();
|
||||
}
|
||||
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
public static void Start()
|
||||
// ReSharper restore MemberCanBePrivate.Global
|
||||
// ReSharper restore MemberCanBePrivate.Global
|
||||
{
|
||||
_Stopwatch.Start();
|
||||
}
|
||||
@@ -58,20 +58,26 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
if (_Stopwatch.IsRunning)
|
||||
{
|
||||
long ticks = _Stopwatch.ElapsedTicks;
|
||||
var ticks = _Stopwatch.ElapsedTicks;
|
||||
if (Stopwatch.IsHighResolution && ticks != 0)
|
||||
return (float)((_NanosecPerTick * ticks) / (1000.0 * 1000.0));
|
||||
{
|
||||
return (float)(_NanosecPerTick * ticks / (1000.0 * 1000.0));
|
||||
}
|
||||
|
||||
return _Stopwatch.ElapsedMilliseconds;
|
||||
}
|
||||
|
||||
return 0f;
|
||||
}
|
||||
|
||||
public static void CalculateFPS()
|
||||
{
|
||||
float ms = GetMilliseconds();
|
||||
var ms = GetMilliseconds();
|
||||
|
||||
if (ms > 0)
|
||||
{
|
||||
_Fps = 1 / ms;
|
||||
}
|
||||
}
|
||||
|
||||
public static double GetFPS()
|
||||
@@ -111,15 +117,19 @@ namespace Vocaluxe.Base
|
||||
|
||||
private void _Add(bool alt, bool shift, bool ctrl, bool pressed, char unicode, Keys key)
|
||||
{
|
||||
bool keyRepeat = false;
|
||||
if ((_Char == unicode) && _KeyPressed)
|
||||
keyRepeat = true;
|
||||
else if (_Keys == key)
|
||||
keyRepeat = true;
|
||||
|
||||
if (!_Timer.IsRunning || (_Timer.ElapsedMilliseconds > 75) || !keyRepeat)
|
||||
var keyRepeat = false;
|
||||
if (_Char == unicode && _KeyPressed)
|
||||
{
|
||||
var pool = new SKeyEvent(ESender.Keyboard, alt, shift, ctrl, pressed && (unicode != Char.MinValue), unicode, key);
|
||||
keyRepeat = true;
|
||||
}
|
||||
else if (_Keys == key)
|
||||
{
|
||||
keyRepeat = true;
|
||||
}
|
||||
|
||||
if (!_Timer.IsRunning || _Timer.ElapsedMilliseconds > 75 || !keyRepeat)
|
||||
{
|
||||
var pool = new SKeyEvent(ESender.Keyboard, alt, shift, ctrl, pressed && unicode != Char.MinValue, unicode, key);
|
||||
|
||||
lock (_CopyLock)
|
||||
{
|
||||
@@ -142,7 +152,7 @@ namespace Vocaluxe.Base
|
||||
|
||||
private void _CheckModifiers()
|
||||
{
|
||||
Keys keys = Control.ModifierKeys;
|
||||
var keys = Control.ModifierKeys;
|
||||
|
||||
_ModShift = (keys & Keys.Shift) == Keys.Shift;
|
||||
_ModAlt = (keys & Keys.Alt) == Keys.Alt;
|
||||
@@ -153,9 +163,9 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
_CheckModifiers();
|
||||
|
||||
bool repeat = _Keys == e.KeyCode;
|
||||
var repeat = _Keys == e.KeyCode;
|
||||
|
||||
if (!_Timer.IsRunning || (_Timer.ElapsedMilliseconds > 75) || !repeat)
|
||||
if (!_Timer.IsRunning || _Timer.ElapsedMilliseconds > 75 || !repeat)
|
||||
{
|
||||
_Keys = e.KeyCode;
|
||||
_Add(_ModAlt, _ModShift, _ModCtrl, _KeyPressed, repeat ? _Char : Char.MinValue, _Keys);
|
||||
@@ -173,7 +183,7 @@ namespace Vocaluxe.Base
|
||||
|
||||
// ReSharper disable UnusedParameter.Global
|
||||
public void KeyUp(KeyEventArgs e)
|
||||
// ReSharper restore UnusedParameter.Global
|
||||
// ReSharper restore UnusedParameter.Global
|
||||
{
|
||||
_CheckModifiers();
|
||||
_KeyPressed = false;
|
||||
@@ -187,6 +197,7 @@ namespace Vocaluxe.Base
|
||||
_Del(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -194,8 +205,11 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
lock (_CopyLock)
|
||||
{
|
||||
foreach (SKeyEvent e in _KeysPool)
|
||||
foreach (var e in _KeysPool)
|
||||
{
|
||||
_ActualPool.Add(e);
|
||||
}
|
||||
|
||||
_KeysPool.Clear();
|
||||
}
|
||||
}
|
||||
@@ -227,7 +241,10 @@ namespace Vocaluxe.Base
|
||||
_CheckModifiers();
|
||||
x = (int)(x * (float)CSettings.RenderW * CConfig.Config.Graphics.NumScreens / CDraw.GetScreenWidth());
|
||||
while (x > CSettings.RenderW)
|
||||
{
|
||||
x -= CSettings.RenderW;
|
||||
}
|
||||
|
||||
y = (int)(y * (float)CSettings.RenderH / CDraw.GetScreenHeight());
|
||||
|
||||
var pool = new SMouseEvent(ESender.Mouse, _Mod, x, y, lb, ld, rb, -wheel / 120, lbh, rbh, mb, mbh);
|
||||
@@ -245,15 +262,23 @@ namespace Vocaluxe.Base
|
||||
|
||||
private void _CheckModifiers()
|
||||
{
|
||||
Keys keys = Control.ModifierKeys;
|
||||
var keys = Control.ModifierKeys;
|
||||
_Mod = EModifier.None;
|
||||
|
||||
if ((keys & Keys.Shift) != 0)
|
||||
{
|
||||
_Mod |= EModifier.Shift;
|
||||
}
|
||||
|
||||
if ((keys & Keys.Alt) != 0)
|
||||
{
|
||||
_Mod |= EModifier.Alt;
|
||||
}
|
||||
|
||||
if ((keys & Keys.Control) != 0)
|
||||
{
|
||||
_Mod |= EModifier.Ctrl;
|
||||
}
|
||||
}
|
||||
|
||||
public void MouseMove(MouseEventArgs e)
|
||||
@@ -268,8 +293,8 @@ namespace Vocaluxe.Base
|
||||
|
||||
public void MouseDown(MouseEventArgs e)
|
||||
{
|
||||
bool lb = e.Button == MouseButtons.Left;
|
||||
bool ld = false;
|
||||
var lb = e.Button == MouseButtons.Left;
|
||||
var ld = false;
|
||||
if (lb)
|
||||
{
|
||||
if (_Timer.IsRunning && _Timer.ElapsedMilliseconds < 450)
|
||||
@@ -284,15 +309,17 @@ namespace Vocaluxe.Base
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_Timer.Reset();
|
||||
}
|
||||
|
||||
_Add(e.X, e.Y, lb, ld, e.Button == MouseButtons.Right, e.Delta, false, false,
|
||||
e.Button == MouseButtons.Middle, false);
|
||||
e.Button == MouseButtons.Middle, false);
|
||||
}
|
||||
|
||||
// ReSharper disable UnusedParameter.Global
|
||||
public void MouseUp(MouseEventArgs e)
|
||||
// ReSharper restore UnusedParameter.Global
|
||||
// ReSharper restore UnusedParameter.Global
|
||||
{
|
||||
//CheckModifiers();
|
||||
//Add(_ModALT, _ModSHIFT, _ModCTRL, e.X, e.Y, e.Button == MouseButtons.Left, e.Button == MouseButtons.Right, e.Delta);
|
||||
@@ -301,7 +328,10 @@ namespace Vocaluxe.Base
|
||||
public bool PollEvent(ref SMouseEvent mouseEvent)
|
||||
{
|
||||
if (_CurrentPool.Count <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mouseEvent = _CurrentPool[0];
|
||||
_Del(0);
|
||||
return true;
|
||||
@@ -311,8 +341,11 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
lock (_CopyLock)
|
||||
{
|
||||
foreach (SMouseEvent e in _EventsPool)
|
||||
foreach (var e in _EventsPool)
|
||||
{
|
||||
_CurrentPool.Add(e);
|
||||
}
|
||||
|
||||
_EventsPool.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
+13
-1
@@ -30,7 +30,10 @@ namespace Vocaluxe.Base
|
||||
public static bool Init()
|
||||
{
|
||||
if (_VideoDecoder != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (CConfig.Config.Video.VideoDecoder)
|
||||
{
|
||||
case EVideoDecoder.FFmpeg:
|
||||
@@ -66,6 +69,7 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
throw new NotSupportedException("_VideoDecoder is null (already closed?)");
|
||||
}
|
||||
|
||||
return _VideoDecoder.Load(videoFileName);
|
||||
}
|
||||
|
||||
@@ -73,7 +77,9 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
//Check for null because the videostreams may close themselves on destroy (GC)
|
||||
if (_VideoDecoder != null)
|
||||
{
|
||||
_VideoDecoder.Close(ref stream);
|
||||
}
|
||||
}
|
||||
|
||||
public static float GetLength(CVideoStream stream)
|
||||
@@ -82,6 +88,7 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
throw new ArgumentException("stream is null");
|
||||
}
|
||||
|
||||
if (_VideoDecoder == null)
|
||||
{
|
||||
throw new NotSupportedException("_VideoDecoder is null (already closed?)");
|
||||
@@ -96,6 +103,7 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
throw new ArgumentException("stream is null");
|
||||
}
|
||||
|
||||
if (_VideoDecoder == null)
|
||||
{
|
||||
throw new NotSupportedException("_VideoDecoder is null (already closed?)");
|
||||
@@ -110,6 +118,7 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
throw new ArgumentException("stream is null");
|
||||
}
|
||||
|
||||
if (_VideoDecoder == null)
|
||||
{
|
||||
throw new NotSupportedException("_VideoDecoder is null (already closed?)");
|
||||
@@ -124,6 +133,7 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
throw new ArgumentException("stream is null");
|
||||
}
|
||||
|
||||
if (_VideoDecoder == null)
|
||||
{
|
||||
throw new NotSupportedException("_VideoDecoder is null (already closed?)");
|
||||
@@ -138,6 +148,7 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
throw new ArgumentException("stream is null");
|
||||
}
|
||||
|
||||
if (_VideoDecoder == null)
|
||||
{
|
||||
throw new NotSupportedException("_VideoDecoder is null (already closed?)");
|
||||
@@ -152,6 +163,7 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
throw new ArgumentException("stream is null");
|
||||
}
|
||||
|
||||
if (_VideoDecoder == null)
|
||||
{
|
||||
throw new NotSupportedException("_VideoDecoder is null (already closed?)");
|
||||
@@ -166,6 +178,7 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
throw new ArgumentException("stream is null");
|
||||
}
|
||||
|
||||
if (_VideoDecoder == null)
|
||||
{
|
||||
throw new NotSupportedException("_VideoDecoder is null (already closed?)");
|
||||
@@ -184,7 +197,6 @@ namespace Vocaluxe.Base
|
||||
_VideoDecoder.Update();
|
||||
}
|
||||
#endregion Interface
|
||||
|
||||
#endregion VideoDecoder
|
||||
}
|
||||
}
|
||||
@@ -45,6 +45,7 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Loaded = true;
|
||||
CVideo.Pause(_VideoStream);
|
||||
}
|
||||
@@ -57,6 +58,7 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//CVideo.VdSkip(_VideoStream, 0f, 0f);
|
||||
_VideoTimer.Start();
|
||||
CVideo.Resume(_VideoStream);
|
||||
@@ -68,6 +70,7 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
CVideo.Pause(_VideoStream);
|
||||
}
|
||||
|
||||
_VideoTimer.Stop();
|
||||
}
|
||||
|
||||
@@ -77,6 +80,7 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CVideo.Resume(_VideoStream);
|
||||
_VideoTimer.Start();
|
||||
}
|
||||
@@ -90,13 +94,16 @@ namespace Vocaluxe.Base
|
||||
|
||||
if (!_Finished)
|
||||
{
|
||||
float videoTime = _VideoTimer.ElapsedMilliseconds / 1000f;
|
||||
var videoTime = _VideoTimer.ElapsedMilliseconds / 1000f;
|
||||
_Finished = CVideo.Finished(_VideoStream);
|
||||
|
||||
CVideo.GetFrame(_VideoStream, videoTime);
|
||||
}
|
||||
|
||||
if (_VideoStream.Texture == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CDraw.DrawTexture(_VideoStream.Texture, CSettings.RenderRect, EAspect.Crop);
|
||||
}
|
||||
@@ -107,17 +114,24 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
return;
|
||||
}
|
||||
bool paused = _VideoTimer.IsRunning;
|
||||
|
||||
var paused = _VideoTimer.IsRunning;
|
||||
if (paused)
|
||||
{
|
||||
CVideo.Resume(_VideoStream);
|
||||
float videoTime = 0f;
|
||||
}
|
||||
|
||||
var videoTime = 0f;
|
||||
while (_VideoStream.Texture == null && videoTime < 1f)
|
||||
{
|
||||
CVideo.GetFrame(_VideoStream, 0);
|
||||
videoTime += 0.05f;
|
||||
}
|
||||
|
||||
if (paused)
|
||||
{
|
||||
CVideo.Pause(_VideoStream);
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
@@ -126,6 +140,7 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
CVideo.Close(ref _VideoStream);
|
||||
}
|
||||
|
||||
_Loaded = false;
|
||||
_Finished = false;
|
||||
_VideoTimer.Reset();
|
||||
|
||||
@@ -29,7 +29,10 @@ namespace Vocaluxe.Base
|
||||
public static bool Init()
|
||||
{
|
||||
if (_Webcam != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (CConfig.Config.Video.WebcamLib)
|
||||
{
|
||||
case EWebcamLib.AForgeNet:
|
||||
@@ -40,8 +43,12 @@ namespace Vocaluxe.Base
|
||||
_Webcam = new CAForgeNet();
|
||||
break;
|
||||
}
|
||||
|
||||
if (!_Webcam.Init())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_Webcam.Select(CConfig.Config.Video.WebcamConfig.HasValue ? CConfig.Config.Video.WebcamConfig.Value : new SWebcamConfig());
|
||||
|
||||
CConfig.Config.Video.WebcamConfig = _Webcam.GetConfig();
|
||||
@@ -52,7 +59,10 @@ namespace Vocaluxe.Base
|
||||
public static void Close()
|
||||
{
|
||||
if (_Webcam == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Webcam.Close();
|
||||
_Webcam = null;
|
||||
}
|
||||
@@ -70,19 +80,25 @@ namespace Vocaluxe.Base
|
||||
public static void Pause()
|
||||
{
|
||||
if (_Webcam != null)
|
||||
{
|
||||
_Webcam.Pause();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Start()
|
||||
{
|
||||
if (_Webcam != null)
|
||||
{
|
||||
_Webcam.Start();
|
||||
}
|
||||
}
|
||||
|
||||
public static void Stop()
|
||||
{
|
||||
if (_Webcam != null)
|
||||
{
|
||||
_Webcam.Stop();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool Select(SWebcamConfig c)
|
||||
@@ -93,7 +109,9 @@ namespace Vocaluxe.Base
|
||||
public static void DeSelect()
|
||||
{
|
||||
if (_Webcam != null)
|
||||
{
|
||||
_Webcam.DeSelect();
|
||||
}
|
||||
}
|
||||
|
||||
public static SWebcamDevice[] GetDevices()
|
||||
@@ -103,12 +121,12 @@ namespace Vocaluxe.Base
|
||||
|
||||
public static bool IsDeviceAvailable()
|
||||
{
|
||||
return (_Webcam != null) && _Webcam.IsDeviceAvailable();
|
||||
return _Webcam != null && _Webcam.IsDeviceAvailable();
|
||||
}
|
||||
|
||||
public static bool IsCapturing()
|
||||
{
|
||||
return (_Webcam != null) && _Webcam.IsCapturing();
|
||||
return _Webcam != null && _Webcam.IsCapturing();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,6 +79,7 @@ namespace Vocaluxe.Base.Fonts
|
||||
case EStyle.BoldItalic:
|
||||
return FontStyle.Bold | FontStyle.Italic;
|
||||
}
|
||||
|
||||
throw new ArgumentException("Invalid style: " + _Style);
|
||||
}
|
||||
|
||||
@@ -97,6 +98,7 @@ namespace Vocaluxe.Base.Fonts
|
||||
CLog.Error("Error opening font file " + _FilePath + ": " + e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return new Font(_Family, height, _GetSystemFontStyle(), GraphicsUnit.Pixel);
|
||||
}
|
||||
|
||||
@@ -139,23 +141,28 @@ namespace Vocaluxe.Base.Fonts
|
||||
CGlyph glyph;
|
||||
if (!_Glyphs.TryGetValue(chr, out glyph))
|
||||
{
|
||||
float maxHeight = (height < 0 || _MaxGlyphHeight + 50 >= height) ? _MaxGlyphHeight : (float)Math.Round(height / 50) * 50;
|
||||
var maxHeight = height < 0 || _MaxGlyphHeight + 50 >= height ? _MaxGlyphHeight : (float)Math.Round(height / 50) * 50;
|
||||
glyph = new CGlyph(chr, this, maxHeight);
|
||||
_Glyphs.Add(chr, glyph);
|
||||
}
|
||||
|
||||
if (glyph.MaxHeight + 50 < height)
|
||||
{
|
||||
glyph.UnloadTexture();
|
||||
glyph = new CGlyph(chr, this, (float)Math.Round(height / 50) * 50);
|
||||
_Glyphs[chr] = glyph;
|
||||
}
|
||||
|
||||
return glyph;
|
||||
}
|
||||
|
||||
private void _UnloadGlyphs()
|
||||
{
|
||||
foreach (CGlyph glyph in _Glyphs.Values)
|
||||
foreach (var glyph in _Glyphs.Values)
|
||||
{
|
||||
glyph.UnloadTexture();
|
||||
}
|
||||
|
||||
_Glyphs.Clear();
|
||||
}
|
||||
|
||||
@@ -170,9 +177,11 @@ namespace Vocaluxe.Base.Fonts
|
||||
_Fonts.Dispose();
|
||||
_Fonts = null;
|
||||
}
|
||||
|
||||
_UnloadGlyphs();
|
||||
_Disposed = true;
|
||||
}
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,20 +34,26 @@ namespace Vocaluxe.Base.Fonts
|
||||
private static readonly List<SFontFamily> _FontFamilies = new List<SFontFamily>();
|
||||
private static readonly List<String> _LoggedMissingFonts = new List<string>();
|
||||
|
||||
public static int PartyModeID { get; set; }
|
||||
public static int PartyModeId { get; set; }
|
||||
|
||||
public static bool Init()
|
||||
{
|
||||
if (_IsInitialized)
|
||||
{
|
||||
return false;
|
||||
PartyModeID = -1;
|
||||
}
|
||||
|
||||
PartyModeId = -1;
|
||||
return _LoadDefaultFonts();
|
||||
}
|
||||
|
||||
public static void Close()
|
||||
{
|
||||
foreach (SFontFamily font in _FontFamilies)
|
||||
foreach (var font in _FontFamilies)
|
||||
{
|
||||
font.Dispose();
|
||||
}
|
||||
|
||||
_FontFamilies.Clear();
|
||||
_IsInitialized = false;
|
||||
}
|
||||
@@ -78,12 +84,14 @@ namespace Vocaluxe.Base.Fonts
|
||||
public static void DrawText(string text, CFont font, float x, float y, float z, SColorF color, bool allMonitors = true)
|
||||
{
|
||||
if (font.Height <= 0f || text == "")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CFontStyle fontStyle = _GetFontStyle(font);
|
||||
var fontStyle = _GetFontStyle(font);
|
||||
|
||||
float dx = x;
|
||||
foreach (char chr in text)
|
||||
var dx = x;
|
||||
foreach (var chr in text)
|
||||
{
|
||||
fontStyle.DrawGlyph(chr, font.Height, dx, y, z, color, allMonitors);
|
||||
dx += fontStyle.GetWidth(chr, font.Height);
|
||||
@@ -93,12 +101,14 @@ namespace Vocaluxe.Base.Fonts
|
||||
public static void DrawTextReflection(string text, CFont font, float x, float y, float z, SColorF color, float rspace, float rheight)
|
||||
{
|
||||
if (font.Height <= 0f || text == "")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CFontStyle fontStyle = _GetFontStyle(font);
|
||||
var fontStyle = _GetFontStyle(font);
|
||||
|
||||
float dx = x;
|
||||
foreach (char chr in text)
|
||||
var dx = x;
|
||||
foreach (var chr in text)
|
||||
{
|
||||
fontStyle.DrawGlyphReflection(chr, font.Height, dx, y, z, color, rspace, rheight);
|
||||
dx += fontStyle.GetWidth(chr, font.Height);
|
||||
@@ -108,35 +118,46 @@ namespace Vocaluxe.Base.Fonts
|
||||
public static void DrawText(string text, CFont font, float x, float y, float z, SColorF color, float begin, float end)
|
||||
{
|
||||
if (font.Height <= 0f || text == "")
|
||||
return;
|
||||
|
||||
float w = GetTextWidth(text, font);
|
||||
if (w <= 0f)
|
||||
return;
|
||||
|
||||
float xStart = x + w * begin;
|
||||
float xEnd = x + w * end;
|
||||
float xCur = x;
|
||||
|
||||
CFontStyle fontStyle = _GetFontStyle(font);
|
||||
|
||||
foreach (char chr in text)
|
||||
{
|
||||
float w2 = fontStyle.GetWidth(chr, font.Height);
|
||||
float b = (xStart - xCur) / w2;
|
||||
return;
|
||||
}
|
||||
|
||||
var w = GetTextWidth(text, font);
|
||||
if (w <= 0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var xStart = x + w * begin;
|
||||
var xEnd = x + w * end;
|
||||
var xCur = x;
|
||||
|
||||
var fontStyle = _GetFontStyle(font);
|
||||
|
||||
foreach (var chr in text)
|
||||
{
|
||||
var w2 = fontStyle.GetWidth(chr, font.Height);
|
||||
var b = (xStart - xCur) / w2;
|
||||
|
||||
if (b < 1f)
|
||||
{
|
||||
if (b < 0f)
|
||||
{
|
||||
b = 0f;
|
||||
float e = (xEnd - xCur) / w2;
|
||||
}
|
||||
|
||||
var e = (xEnd - xCur) / w2;
|
||||
if (e > 0f)
|
||||
{
|
||||
if (e > 1f)
|
||||
{
|
||||
e = 1f;
|
||||
}
|
||||
|
||||
fontStyle.DrawGlyph(chr, font.Height, xCur, y, z, color, b, e);
|
||||
}
|
||||
}
|
||||
|
||||
xCur += w2;
|
||||
}
|
||||
}
|
||||
@@ -169,7 +190,7 @@ namespace Vocaluxe.Base.Fonts
|
||||
|
||||
private static CFontStyle _GetFontStyle(CFont font)
|
||||
{
|
||||
int index = _GetFontIndex(font.Name);
|
||||
var index = _GetFontIndex(font.Name);
|
||||
|
||||
switch (font.Style)
|
||||
{
|
||||
@@ -182,18 +203,19 @@ namespace Vocaluxe.Base.Fonts
|
||||
case EStyle.BoldItalic:
|
||||
return _FontFamilies[index].BoldItalic;
|
||||
}
|
||||
|
||||
throw new ArgumentException("Invalid Style: " + font.Style);
|
||||
}
|
||||
|
||||
public static float GetTextWidth(string text, CFont font)
|
||||
{
|
||||
CFontStyle fontStyle = _GetFontStyle(font);
|
||||
var fontStyle = _GetFontStyle(font);
|
||||
return text.Sum(chr => fontStyle.GetWidth(chr, font.Height));
|
||||
}
|
||||
|
||||
public static float GetTextHeight(string text, CFont font)
|
||||
{
|
||||
CFontStyle fontStyle = _GetFontStyle(font);
|
||||
var fontStyle = _GetFontStyle(font);
|
||||
return text == "" ? 0 : text.Select(chr => fontStyle.GetHeight(chr, font.Height)).Max();
|
||||
}
|
||||
|
||||
@@ -201,16 +223,25 @@ namespace Vocaluxe.Base.Fonts
|
||||
{
|
||||
if (fontName != "")
|
||||
{
|
||||
int index = _GetPartyFontIndex(fontName, PartyModeID);
|
||||
var index = _GetPartyFontIndex(fontName, PartyModeId);
|
||||
if (index < 0)
|
||||
{
|
||||
index = _GetThemeFontIndex(fontName, CConfig.Config.Theme.Theme);
|
||||
}
|
||||
|
||||
if (index >= 0)
|
||||
{
|
||||
return index;
|
||||
for (int i = 0; i < _FontFamilies.Count; i++)
|
||||
}
|
||||
|
||||
for (var i = 0; i < _FontFamilies.Count; i++)
|
||||
{
|
||||
if (_FontFamilies[i].Name == fontName)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
if (!_LoggedMissingFonts.Contains(fontName))
|
||||
{
|
||||
_LoggedMissingFonts.Add(fontName);
|
||||
@@ -218,10 +249,14 @@ namespace Vocaluxe.Base.Fonts
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CLog.Error("Empty fontName requested");
|
||||
}
|
||||
|
||||
if (_FontFamilies.Count == 0)
|
||||
{
|
||||
CLog.Fatal("No fonts found!");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -230,23 +265,27 @@ namespace Vocaluxe.Base.Fonts
|
||||
{
|
||||
Debug.Assert(fontName != "" && themeName != "");
|
||||
|
||||
for (int i = 0; i < _FontFamilies.Count; i++)
|
||||
for (var i = 0; i < _FontFamilies.Count; i++)
|
||||
{
|
||||
if (_FontFamilies[i].Name == fontName && _FontFamilies[i].ThemeName == themeName)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static int _GetPartyFontIndex(string fontName, int partyModeID)
|
||||
private static int _GetPartyFontIndex(string fontName, int partyModeId)
|
||||
{
|
||||
Debug.Assert(fontName != "");
|
||||
|
||||
for (int i = 0; i < _FontFamilies.Count; i++)
|
||||
for (var i = 0; i < _FontFamilies.Count; i++)
|
||||
{
|
||||
if (_FontFamilies[i].PartyModeID == partyModeID && _FontFamilies[i].Name == fontName)
|
||||
if (_FontFamilies[i].PartyModeId == partyModeId && _FontFamilies[i].Name == fontName)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
@@ -279,8 +318,11 @@ namespace Vocaluxe.Base.Fonts
|
||||
public static bool LoadThemeFonts(IEnumerable<SFontFamily> fontFamilies, string fontFolder, string themeName, int partyModeId)
|
||||
{
|
||||
if (fontFamilies == null)
|
||||
{
|
||||
return true;
|
||||
foreach (SFontFamily fontFamily in fontFamilies)
|
||||
}
|
||||
|
||||
foreach (var fontFamily in fontFamilies)
|
||||
{
|
||||
if (!_LoadFont(fontFamily, fontFolder, themeName, partyModeId))
|
||||
{
|
||||
@@ -288,7 +330,7 @@ namespace Vocaluxe.Base.Fonts
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
using (CBenchmark.Time("Build Glyphs"))
|
||||
{
|
||||
_BuildGlyphs();
|
||||
@@ -300,19 +342,19 @@ namespace Vocaluxe.Base.Fonts
|
||||
private static bool _LoadFont(SFontFamily fontFamily, string fontFolder, string themeName, int partyModeId)
|
||||
{
|
||||
fontFamily.ThemeName = themeName;
|
||||
fontFamily.PartyModeID = partyModeId;
|
||||
fontFamily.PartyModeId = partyModeId;
|
||||
fontFamily.Normal = new CFontStyle(Path.Combine(fontFolder, fontFamily.Folder, fontFamily.FileNormal), EStyle.Normal, fontFamily.Outline, fontFamily.OutlineColor);
|
||||
fontFamily.Italic = new CFontStyle(Path.Combine(fontFolder, fontFamily.Folder, fontFamily.FileItalic), EStyle.Italic, fontFamily.Outline, fontFamily.OutlineColor);
|
||||
fontFamily.Bold = new CFontStyle(Path.Combine(fontFolder, fontFamily.Folder, fontFamily.FileBold), EStyle.Bold, fontFamily.Outline, fontFamily.OutlineColor);
|
||||
fontFamily.BoldItalic = new CFontStyle(Path.Combine(fontFolder, fontFamily.Folder, fontFamily.FileBoldItalic), EStyle.BoldItalic, fontFamily.Outline,
|
||||
fontFamily.OutlineColor);
|
||||
fontFamily.OutlineColor);
|
||||
_FontFamilies.Add(fontFamily);
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void UnloadThemeFonts(string themeName)
|
||||
{
|
||||
int index = 0;
|
||||
var index = 0;
|
||||
while (index < _FontFamilies.Count)
|
||||
{
|
||||
if (_FontFamilies[index].ThemeName == themeName)
|
||||
@@ -321,23 +363,27 @@ namespace Vocaluxe.Base.Fonts
|
||||
_FontFamilies.RemoveAt(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void UnloadPartyModeFonts(int partyModeID)
|
||||
public static void UnloadPartyModeFonts(int partyModeId)
|
||||
{
|
||||
Debug.Assert(partyModeID >= 0);
|
||||
int index = 0;
|
||||
Debug.Assert(partyModeId >= 0);
|
||||
var index = 0;
|
||||
while (index < _FontFamilies.Count)
|
||||
{
|
||||
if (_FontFamilies[index].PartyModeID == partyModeID)
|
||||
if (_FontFamilies[index].PartyModeId == partyModeId)
|
||||
{
|
||||
_FontFamilies[index].Dispose();
|
||||
_FontFamilies.RemoveAt(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -345,9 +391,9 @@ namespace Vocaluxe.Base.Fonts
|
||||
{
|
||||
const string text = " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
|
||||
|
||||
foreach (SFontFamily fontFamily in _FontFamilies)
|
||||
foreach (var fontFamily in _FontFamilies)
|
||||
{
|
||||
foreach (char chr in text)
|
||||
foreach (var chr in text)
|
||||
{
|
||||
fontFamily.Normal.GetOrAddGlyph(chr, -1);
|
||||
fontFamily.Bold.GetOrAddGlyph(chr, -1);
|
||||
|
||||
@@ -39,21 +39,21 @@ namespace Vocaluxe.Base.Fonts
|
||||
public CGlyph(char chr, CFontStyle fontStyle, float maxHeight)
|
||||
{
|
||||
MaxHeight = maxHeight;
|
||||
float outlineSize = fontStyle.Outline * maxHeight;
|
||||
string chrString = chr.ToString();
|
||||
var outlineSize = fontStyle.Outline * maxHeight;
|
||||
var chrString = chr.ToString();
|
||||
|
||||
Font fo = fontStyle.GetSystemFont(maxHeight);
|
||||
var fo = fontStyle.GetSystemFont(maxHeight);
|
||||
SizeF fullSize;
|
||||
Size bmpSize;
|
||||
using (Graphics g = Graphics.FromHwnd(IntPtr.Zero))
|
||||
using (var g = Graphics.FromHwnd(IntPtr.Zero))
|
||||
{
|
||||
fullSize = g.MeasureString(chrString, fo);
|
||||
if (chr != ' ')
|
||||
{
|
||||
//Gets exact height and width for drawing more than 1 char. But width is to small to draw char on bitmap as e.g. italic chars will get cropped
|
||||
//See https://stackoverflow.com/questions/11708621/how-to-measure-width-of-a-string-precisely
|
||||
StringFormat format = StringFormat.GenericTypographic;
|
||||
RectangleF rect = new RectangleF(0, 0, 2000, 2000);
|
||||
var format = StringFormat.GenericTypographic;
|
||||
var rect = new RectangleF(0, 0, 2000, 2000);
|
||||
CharacterRange[] ranges = { new CharacterRange(0, chrString.Length) };
|
||||
format.SetMeasurableCharacterRanges(ranges);
|
||||
_BoundingBox = g.MeasureCharacterRanges(chrString, fo, rect, format)[0].GetBounds(g).Size;
|
||||
@@ -61,7 +61,10 @@ namespace Vocaluxe.Base.Fonts
|
||||
// ReSharper disable CompareOfFloatsByEqualityOperator
|
||||
if (_BoundingBox.Height == 0)
|
||||
// ReSharper restore CompareOfFloatsByEqualityOperator
|
||||
{
|
||||
_BoundingBox.Height = fullSize.Height;
|
||||
}
|
||||
|
||||
_BoundingBox.Width += outlineSize / 2;
|
||||
_BoundingBox.Height += outlineSize;
|
||||
fullSize.Width += outlineSize;
|
||||
@@ -74,8 +77,9 @@ namespace Vocaluxe.Base.Fonts
|
||||
bmpSize = new Size(1, 1);
|
||||
}
|
||||
}
|
||||
|
||||
using (var bmp = new Bitmap(bmpSize.Width, bmpSize.Height, PixelFormat.Format32bppArgb))
|
||||
using (Graphics g = Graphics.FromImage(bmp))
|
||||
using (var g = Graphics.FromImage(bmp))
|
||||
{
|
||||
g.Clear(Color.Transparent);
|
||||
|
||||
@@ -95,7 +99,7 @@ namespace Vocaluxe.Base.Fonts
|
||||
using (var path = new GraphicsPath())
|
||||
{
|
||||
//Have to use size in em not pixels!
|
||||
float emSize = fo.Size * fo.FontFamily.GetCellAscent(fo.Style) / fo.FontFamily.GetEmHeight(fo.Style);
|
||||
var emSize = fo.Size * fo.FontFamily.GetCellAscent(fo.Style) / fo.FontFamily.GetEmHeight(fo.Style);
|
||||
path.AddString(chrString, fo.FontFamily, (int)fo.Style, emSize, point, new StringFormat());
|
||||
|
||||
using (var pen = new Pen(fontStyle.OutlineColor.AsColor(), outlineSize))
|
||||
@@ -105,10 +109,11 @@ namespace Vocaluxe.Base.Fonts
|
||||
g.FillPath(Brushes.White, path);
|
||||
}
|
||||
}
|
||||
|
||||
_DrawBounding = _GetRealBounds(bmp);
|
||||
using (Bitmap bmpCropped = bmp.Clone(_DrawBounding, PixelFormat.Format32bppArgb))
|
||||
using (var bmpCropped = bmp.Clone(_DrawBounding, PixelFormat.Format32bppArgb))
|
||||
{
|
||||
float dx = (fullSize.Width - _BoundingBox.Width - 1) / 2;
|
||||
var dx = (fullSize.Width - _BoundingBox.Width - 1) / 2;
|
||||
_DrawBounding.X -= dx;
|
||||
_Texture = CDraw.AddTexture(bmpCropped);
|
||||
/*_DrawBounding.X *= _Texture.Width / _DrawBounding.Width;
|
||||
@@ -152,27 +157,27 @@ namespace Vocaluxe.Base.Fonts
|
||||
public void GetTextureAndRect(float fontHeight, float x, float y, float z, out CTextureRef texture, out SRectF rect)
|
||||
{
|
||||
texture = _Texture;
|
||||
float factor = _GetFactor(fontHeight);
|
||||
var factor = _GetFactor(fontHeight);
|
||||
x += _DrawBounding.X * factor;
|
||||
y += _DrawBounding.Y * factor;
|
||||
float h = _DrawBounding.Height * factor;
|
||||
float w = _DrawBounding.Width * factor;
|
||||
var h = _DrawBounding.Height * factor;
|
||||
var w = _DrawBounding.Width * factor;
|
||||
rect = new SRectF(x, y, w, h, z);
|
||||
}
|
||||
|
||||
private static Rectangle _GetRealBounds(Bitmap bmp)
|
||||
{
|
||||
int minX = 0, maxX = bmp.Width - 1, minY = 0;
|
||||
BitmapData bmpData = bmp.LockBits(bmp.GetRect(), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||||
int values = bmpData.Width * bmp.Height;
|
||||
var bmpData = bmp.LockBits(bmp.GetRect(), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||||
var values = bmpData.Width * bmp.Height;
|
||||
var rgbValues = new Int32[values];
|
||||
Marshal.Copy(bmpData.Scan0, rgbValues, 0, values);
|
||||
int index = 0;
|
||||
bool found = false;
|
||||
var index = 0;
|
||||
var found = false;
|
||||
//find from top
|
||||
for (int y = 0; y < bmp.Height && !found; y++)
|
||||
for (var y = 0; y < bmp.Height && !found; y++)
|
||||
{
|
||||
for (int x = 0; x < bmp.Width; x++)
|
||||
for (var x = 0; x < bmp.Width; x++)
|
||||
{
|
||||
if (rgbValues[index] != 0)
|
||||
{
|
||||
@@ -182,15 +187,17 @@ namespace Vocaluxe.Base.Fonts
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
found = false;
|
||||
//find left
|
||||
for (int x = 0; x < minX && !found; x++)
|
||||
for (var x = 0; x < minX && !found; x++)
|
||||
{
|
||||
index = x + minY * bmp.Width;
|
||||
for (int y = minY; y < bmp.Height; y++)
|
||||
for (var y = minY; y < bmp.Height; y++)
|
||||
{
|
||||
if (rgbValues[index] != 0)
|
||||
{
|
||||
@@ -198,15 +205,17 @@ namespace Vocaluxe.Base.Fonts
|
||||
minX = x;
|
||||
break;
|
||||
}
|
||||
|
||||
index += bmp.Width;
|
||||
}
|
||||
}
|
||||
|
||||
found = false;
|
||||
//find right
|
||||
for (int x = bmp.Width - 1; x > maxX && !found; x--)
|
||||
for (var x = bmp.Width - 1; x > maxX && !found; x--)
|
||||
{
|
||||
index = x + minY * bmp.Width;
|
||||
for (int y = minY; y < bmp.Height; y++)
|
||||
for (var y = minY; y < bmp.Height; y++)
|
||||
{
|
||||
if (rgbValues[index] != 0)
|
||||
{
|
||||
@@ -214,6 +223,7 @@ namespace Vocaluxe.Base.Fonts
|
||||
maxX = x;
|
||||
break;
|
||||
}
|
||||
|
||||
index += bmp.Width;
|
||||
}
|
||||
}
|
||||
@@ -222,15 +232,23 @@ namespace Vocaluxe.Base.Fonts
|
||||
const int d = 4;
|
||||
minX = minX - d;
|
||||
if (minX < 0)
|
||||
{
|
||||
minX = 0;
|
||||
}
|
||||
|
||||
minY = minY - d;
|
||||
if (minY < 0)
|
||||
{
|
||||
minY = 0;
|
||||
}
|
||||
|
||||
maxX = maxX + d;
|
||||
if (maxX > bmp.Width)
|
||||
{
|
||||
maxX = bmp.Width;
|
||||
}
|
||||
|
||||
return new Rectangle(minX, minY, maxX - minX, bmp.Height - minY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -22,7 +22,6 @@ using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography;
|
||||
using System.ServiceModel;
|
||||
using System.ServiceModel.Web;
|
||||
@@ -52,34 +51,32 @@ namespace Vocaluxe.Base.Server
|
||||
return "App controller";
|
||||
}
|
||||
|
||||
public override void Connect() {}
|
||||
public override void Connect() { }
|
||||
|
||||
public override void Disconnect() {}
|
||||
public override void Disconnect() { }
|
||||
|
||||
public override bool IsConnected()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void SetRumble(float duration) {}
|
||||
public override void SetRumble(float duration) { }
|
||||
}
|
||||
|
||||
public static readonly CControllerFramework Controller = new CServerController();
|
||||
|
||||
|
||||
#region server control
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
int port = CConfig.Config.Server.ServerPort;
|
||||
bool encrypted = CConfig.Config.Server.ServerEncryption == EOffOn.TR_CONFIG_ON;
|
||||
string hostname = Dns.GetHostName();
|
||||
string protocol = (encrypted) ? "https" : "http";
|
||||
var port = CConfig.Config.Server.ServerPort;
|
||||
var encrypted = CConfig.Config.Server.ServerEncryption == EOffOn.TR_CONFIG_ON;
|
||||
var hostname = Dns.GetHostName();
|
||||
var protocol = encrypted ? "https" : "http";
|
||||
_BaseAddress = new Uri(protocol + "://" + hostname + ":" + port + "/");
|
||||
_Encrypted = encrypted;
|
||||
_Host = new WebServiceHost(typeof(CWebservice), _BaseAddress);
|
||||
|
||||
WebHttpBinding wb = new WebHttpBinding
|
||||
var wb = new WebHttpBinding
|
||||
{
|
||||
MaxReceivedMessageSize = 10485760,
|
||||
MaxBufferSize = 10485760,
|
||||
@@ -91,6 +88,7 @@ namespace Vocaluxe.Base.Server
|
||||
wb.Security.Mode = WebHttpSecurityMode.Transport;
|
||||
wb.Security.Transport = new HttpTransportSecurity { ClientCredentialType = HttpClientCredentialType.None };
|
||||
}
|
||||
|
||||
_Host.AddServiceEndpoint(typeof(ICWebservice), wb, "");
|
||||
|
||||
Start();
|
||||
@@ -125,7 +123,9 @@ namespace Vocaluxe.Base.Server
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_Host.Abort();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -148,8 +148,7 @@ namespace Vocaluxe.Base.Server
|
||||
private static void _RegisterUrlAndCert(int port, bool reserve)
|
||||
{
|
||||
#if WIN
|
||||
|
||||
ProcessStartInfo info = new ProcessStartInfo
|
||||
var info = new ProcessStartInfo
|
||||
{
|
||||
FileName = "VocaluxeServerConfig.exe",
|
||||
WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory,
|
||||
@@ -160,11 +159,14 @@ namespace Vocaluxe.Base.Server
|
||||
};
|
||||
try
|
||||
{
|
||||
using (Process p = Process.Start(info))
|
||||
using (var p = Process.Start(info))
|
||||
{
|
||||
p.WaitForExit();
|
||||
if (p.ExitCode != 0)
|
||||
{
|
||||
MessageBox.Show("Registering the Server failed (Code " + p.ExitCode + ")!\r\nThe Server might not work correctly.");
|
||||
}
|
||||
|
||||
p.Close();
|
||||
}
|
||||
}
|
||||
@@ -173,8 +175,7 @@ namespace Vocaluxe.Base.Server
|
||||
MessageBox.Show("Registering the Server failed (" + e + ")!\r\nThe Server might not work correctly.");
|
||||
}
|
||||
#else
|
||||
|
||||
//Required?
|
||||
//Required?
|
||||
|
||||
#endif
|
||||
}
|
||||
@@ -187,28 +188,27 @@ namespace Vocaluxe.Base.Server
|
||||
public static bool IsServerRunning()
|
||||
{
|
||||
if (_Host == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return _Host.State == CommunicationState.Opened;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region task control
|
||||
|
||||
public static void ProcessServerTasks()
|
||||
{
|
||||
//Serial processing - one by one
|
||||
while (_ServerTaskQueue.Count > 0)
|
||||
{
|
||||
//Get a task from the queue
|
||||
Task task = _ServerTaskQueue.Dequeue();
|
||||
var task = _ServerTaskQueue.Dequeue();
|
||||
//Start the task
|
||||
task.RunSynchronously(TaskScheduler.FromCurrentSynchronizationContext());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static TReturnType DoTask<TReturnType>(Func<TReturnType> action)
|
||||
{
|
||||
var task = new Task<TReturnType>(action);
|
||||
@@ -225,7 +225,8 @@ namespace Vocaluxe.Base.Server
|
||||
return task.Result;
|
||||
}
|
||||
|
||||
public static TReturnType DoTask<TReturnType, TParameterType1, TParameterType2>(Func<TParameterType1, TParameterType2, TReturnType> action, TParameterType1 parameter1, TParameterType2 parameter2)
|
||||
public static TReturnType DoTask<TReturnType, TParameterType1, TParameterType2>(Func<TParameterType1, TParameterType2, TReturnType> action, TParameterType1 parameter1,
|
||||
TParameterType2 parameter2)
|
||||
{
|
||||
var task = new Task<TReturnType>(() => action(parameter1, parameter2));
|
||||
_ServerTaskQueue.Enqueue(task);
|
||||
@@ -233,7 +234,8 @@ namespace Vocaluxe.Base.Server
|
||||
return task.Result;
|
||||
}
|
||||
|
||||
public static TReturnType DoTask<TReturnType, TParameterType1, TParameterType2, TParameterType3>(Func<TParameterType1, TParameterType2, TParameterType3, TReturnType> action, TParameterType1 parameter1, TParameterType2 parameter2, TParameterType3 parameter3)
|
||||
public static TReturnType DoTask<TReturnType, TParameterType1, TParameterType2, TParameterType3>(
|
||||
Func<TParameterType1, TParameterType2, TParameterType3, TReturnType> action, TParameterType1 parameter1, TParameterType2 parameter2, TParameterType3 parameter3)
|
||||
{
|
||||
var task = new Task<TReturnType>(() => action(parameter1, parameter2, parameter3));
|
||||
_ServerTaskQueue.Enqueue(task);
|
||||
@@ -241,7 +243,9 @@ namespace Vocaluxe.Base.Server
|
||||
return task.Result;
|
||||
}
|
||||
|
||||
public static TReturnType DoTask<TReturnType, TParameterType1, TParameterType2, TParameterType3, TParameterType4>(Func<TParameterType1, TParameterType2, TParameterType3, TParameterType4, TReturnType> action, TParameterType1 parameter1, TParameterType2 parameter2, TParameterType3 parameter3, TParameterType4 parameter4)
|
||||
public static TReturnType DoTask<TReturnType, TParameterType1, TParameterType2, TParameterType3, TParameterType4>(
|
||||
Func<TParameterType1, TParameterType2, TParameterType3, TParameterType4, TReturnType> action, TParameterType1 parameter1, TParameterType2 parameter2,
|
||||
TParameterType3 parameter3, TParameterType4 parameter4)
|
||||
{
|
||||
var task = new Task<TReturnType>(() => action(parameter1, parameter2, parameter3, parameter4));
|
||||
_ServerTaskQueue.Enqueue(task);
|
||||
@@ -249,7 +253,6 @@ namespace Vocaluxe.Base.Server
|
||||
return task.Result;
|
||||
}
|
||||
|
||||
|
||||
public static void DoTaskWithoutReturn(Action action)
|
||||
{
|
||||
var task = new Task(action);
|
||||
@@ -264,33 +267,36 @@ namespace Vocaluxe.Base.Server
|
||||
task.Wait(); //wait until the task is completed
|
||||
}
|
||||
|
||||
public static void DoTaskWithoutReturn<TParameterType1, TParameterType2>(Action<TParameterType1, TParameterType2> action, TParameterType1 parameter1, TParameterType2 parameter2)
|
||||
public static void DoTaskWithoutReturn<TParameterType1, TParameterType2>(Action<TParameterType1, TParameterType2> action, TParameterType1 parameter1,
|
||||
TParameterType2 parameter2)
|
||||
{
|
||||
var task = new Task(() => action(parameter1, parameter2));
|
||||
_ServerTaskQueue.Enqueue(task);
|
||||
task.Wait(); //wait until the task is completed
|
||||
}
|
||||
|
||||
public static void DoTaskWithoutReturn<TParameterType1, TParameterType2, TParameterType3>(Action<TParameterType1, TParameterType2, TParameterType3> action, TParameterType1 parameter1, TParameterType2 parameter2, TParameterType3 parameter3)
|
||||
public static void DoTaskWithoutReturn<TParameterType1, TParameterType2, TParameterType3>(Action<TParameterType1, TParameterType2, TParameterType3> action,
|
||||
TParameterType1 parameter1, TParameterType2 parameter2, TParameterType3 parameter3)
|
||||
{
|
||||
var task = new Task(() => action(parameter1, parameter2, parameter3));
|
||||
_ServerTaskQueue.Enqueue(task);
|
||||
task.Wait(); //wait until the task is completed
|
||||
}
|
||||
|
||||
public static void DoTaskWithoutReturn<TParameterType1, TParameterType2, TParameterType3, TParameterType4>(Action<TParameterType1, TParameterType2, TParameterType3, TParameterType4> action, TParameterType1 parameter1, TParameterType2 parameter2, TParameterType3 parameter3, TParameterType4 parameter4)
|
||||
public static void DoTaskWithoutReturn<TParameterType1, TParameterType2, TParameterType3, TParameterType4>(
|
||||
Action<TParameterType1, TParameterType2, TParameterType3, TParameterType4> action, TParameterType1 parameter1, TParameterType2 parameter2, TParameterType3 parameter3,
|
||||
TParameterType4 parameter4)
|
||||
{
|
||||
var task = new Task(() => action(parameter1, parameter2, parameter3, parameter4));
|
||||
_ServerTaskQueue.Enqueue(task);
|
||||
task.Wait(); //wait until the task is completed
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public static bool SendKeyEvent(string key)
|
||||
{
|
||||
bool result = false;
|
||||
string lowerKey = key.ToLower();
|
||||
var result = false;
|
||||
var lowerKey = key.ToLower();
|
||||
|
||||
if (!string.IsNullOrEmpty(lowerKey))
|
||||
{
|
||||
@@ -331,18 +337,19 @@ namespace Vocaluxe.Base.Server
|
||||
default:
|
||||
if (lowerKey.StartsWith("f"))
|
||||
{
|
||||
string numberString = lowerKey.Substring(1);
|
||||
var numberString = lowerKey.Substring(1);
|
||||
int number;
|
||||
Keys fKey;
|
||||
|
||||
if (Int32.TryParse(numberString, out number) && number >= 1
|
||||
&& number <= 12
|
||||
&& Enum.TryParse("F" + number, true, out fKey))
|
||||
&& number <= 12
|
||||
&& Enum.TryParse("F" + number, true, out fKey))
|
||||
{
|
||||
Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, false, false, false, false, Char.MinValue, fKey));
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -352,15 +359,15 @@ namespace Vocaluxe.Base.Server
|
||||
|
||||
public static bool SendKeyStringEvent(string keyString, bool isShiftPressed, bool isAltPressed, bool isCtrlPressed)
|
||||
{
|
||||
bool result = false;
|
||||
var result = false;
|
||||
|
||||
foreach (char key in keyString)
|
||||
foreach (var key in keyString)
|
||||
{
|
||||
Controller.AddKeyEvent(new SKeyEvent(ESender.Keyboard, isAltPressed,
|
||||
Char.IsUpper(key) || isShiftPressed,
|
||||
isCtrlPressed, true,
|
||||
isShiftPressed ? Char.ToUpper(key) : key,
|
||||
_ParseKeys(key)));
|
||||
Char.IsUpper(key) || isShiftPressed,
|
||||
isCtrlPressed, true,
|
||||
isShiftPressed ? Char.ToUpper(key) : key,
|
||||
_ParseKeys(key)));
|
||||
result = true;
|
||||
}
|
||||
|
||||
@@ -390,42 +397,47 @@ namespace Vocaluxe.Base.Server
|
||||
#region profile
|
||||
public static SProfileData GetProfileData(Guid profileId, bool isReadonly)
|
||||
{
|
||||
CProfile profile = CProfiles.GetProfile(profileId);
|
||||
var profile = CProfiles.GetProfile(profileId);
|
||||
if (profile == null)
|
||||
{
|
||||
return new SProfileData();
|
||||
}
|
||||
|
||||
return _CreateProfileData(profile, isReadonly);
|
||||
}
|
||||
|
||||
public static bool SendProfileData(SProfileData profile)
|
||||
{
|
||||
CProfile newProfile;
|
||||
CProfile existingProfile = CProfiles.GetProfile(profile.ProfileId);
|
||||
var existingProfile = CProfiles.GetProfile(profile.ProfileId);
|
||||
|
||||
if (existingProfile != null)
|
||||
{
|
||||
newProfile = new CProfile
|
||||
{
|
||||
ID = existingProfile.ID,
|
||||
FilePath = existingProfile.FilePath,
|
||||
Active = existingProfile.Active,
|
||||
Avatar = existingProfile.Avatar,
|
||||
Difficulty = existingProfile.Difficulty,
|
||||
UserRole = existingProfile.UserRole,
|
||||
PlayerName = existingProfile.PlayerName
|
||||
};
|
||||
{
|
||||
Id = existingProfile.Id,
|
||||
FilePath = existingProfile.FilePath,
|
||||
Active = existingProfile.Active,
|
||||
Avatar = existingProfile.Avatar,
|
||||
Difficulty = existingProfile.Difficulty,
|
||||
UserRole = existingProfile.UserRole,
|
||||
PlayerName = existingProfile.PlayerName
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
newProfile = new CProfile
|
||||
{
|
||||
Active = EOffOn.TR_CONFIG_ON,
|
||||
UserRole = EUserRole.TR_USERROLE_NORMAL
|
||||
};
|
||||
{
|
||||
Active = EOffOn.TR_CONFIG_ON,
|
||||
UserRole = EUserRole.TR_USERROLE_NORMAL
|
||||
};
|
||||
}
|
||||
|
||||
if (profile.Avatar != null)
|
||||
{
|
||||
newProfile.Avatar = _AddAvatar(profile.Avatar);
|
||||
else if (newProfile.Avatar == null || newProfile.Avatar.ID == -1)
|
||||
}
|
||||
else if (newProfile.Avatar == null || newProfile.Avatar.Id == -1)
|
||||
{
|
||||
newProfile.Avatar = CProfiles.GetAvatars().First();
|
||||
|
||||
@@ -436,16 +448,22 @@ namespace Vocaluxe.Base.Server
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(profile.PlayerName))
|
||||
{
|
||||
newProfile.PlayerName = profile.PlayerName;
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(newProfile.PlayerName))
|
||||
{
|
||||
newProfile.PlayerName = "DummyName";
|
||||
}
|
||||
|
||||
if (profile.Difficulty >= 0 && profile.Difficulty <= 2)
|
||||
{
|
||||
newProfile.Difficulty = (EGameDifficulty)profile.Difficulty;
|
||||
}
|
||||
|
||||
if (profile.Type >= 0 && profile.Type <= 1)
|
||||
{
|
||||
EUserRole option = profile.Type == 0 ? EUserRole.TR_USERROLE_GUEST : EUserRole.TR_USERROLE_NORMAL;
|
||||
var option = profile.Type == 0 ? EUserRole.TR_USERROLE_GUEST : EUserRole.TR_USERROLE_NORMAL;
|
||||
//Only allow the change of TR_USERROLE_GUEST and TR_USERROLE_NORMAL
|
||||
const EUserRole mask = EUserRole.TR_USERROLE_NORMAL;
|
||||
newProfile.UserRole = (newProfile.UserRole & mask) | option;
|
||||
@@ -460,11 +478,11 @@ namespace Vocaluxe.Base.Server
|
||||
}
|
||||
else
|
||||
{
|
||||
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
|
||||
byte[] buffer = new byte[32];
|
||||
var rng = new RNGCryptoServiceProvider();
|
||||
var buffer = new byte[32];
|
||||
rng.GetNonZeroBytes(buffer);
|
||||
byte[] salt = buffer;
|
||||
byte[] hashedPassword = _Hash((new UTF8Encoding()).GetBytes(profile.Password), salt);
|
||||
var salt = buffer;
|
||||
var hashedPassword = _Hash(new UTF8Encoding().GetBytes(profile.Password), salt);
|
||||
|
||||
newProfile.PasswordSalt = salt;
|
||||
newProfile.PasswordHash = hashedPassword;
|
||||
@@ -478,14 +496,16 @@ namespace Vocaluxe.Base.Server
|
||||
CProfiles.SaveProfiles();
|
||||
}
|
||||
else
|
||||
{
|
||||
CProfiles.AddProfile(newProfile);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static SProfileData[] GetProfileList()
|
||||
{
|
||||
List<SProfileData> result = new List<SProfileData>(CProfiles.NumProfiles);
|
||||
var result = new List<SProfileData>(CProfiles.NumProfiles);
|
||||
|
||||
result.AddRange(CProfiles.GetProfiles().Select(profile => _CreateProfileData(profile, true)));
|
||||
|
||||
@@ -494,22 +514,25 @@ namespace Vocaluxe.Base.Server
|
||||
|
||||
private static SProfileData _CreateProfileData(CProfile profile, bool isReadonly)
|
||||
{
|
||||
SProfileData profileData = new SProfileData
|
||||
{
|
||||
IsEditable = !isReadonly,
|
||||
ProfileId = profile.ID,
|
||||
PlayerName = profile.PlayerName,
|
||||
//Is TR_USERROLE_GUEST or TR_USERROLE_NORMAL?
|
||||
Type = (profile.UserRole.HasFlag(EUserRole.TR_USERROLE_NORMAL) ? 1 : 0),
|
||||
Difficulty = (int)profile.Difficulty
|
||||
};
|
||||
var profileData = new SProfileData
|
||||
{
|
||||
IsEditable = !isReadonly,
|
||||
ProfileId = profile.Id,
|
||||
PlayerName = profile.PlayerName,
|
||||
//Is TR_USERROLE_GUEST or TR_USERROLE_NORMAL?
|
||||
Type = profile.UserRole.HasFlag(EUserRole.TR_USERROLE_NORMAL) ? 1 : 0,
|
||||
Difficulty = (int)profile.Difficulty
|
||||
};
|
||||
|
||||
CAvatar avatar = profile.Avatar;
|
||||
var avatar = profile.Avatar;
|
||||
if (avatar != null)
|
||||
{
|
||||
if (File.Exists(avatar.FileName))
|
||||
{
|
||||
profileData.Avatar = new CBase64Image(_CreateDelayedImage(avatar.FileName));
|
||||
}
|
||||
}
|
||||
|
||||
return profileData;
|
||||
}
|
||||
|
||||
@@ -517,14 +540,15 @@ namespace Vocaluxe.Base.Server
|
||||
{
|
||||
try
|
||||
{
|
||||
string filename = _SaveImage(avatarData, "snapshot", CConfig.ProfileFolders[0]);
|
||||
var filename = _SaveImage(avatarData, "snapshot", CConfig.ProfileFolders[0]);
|
||||
|
||||
CAvatar avatar = CAvatar.GetAvatar(filename);
|
||||
var avatar = CAvatar.GetAvatar(filename);
|
||||
if (avatar != null)
|
||||
{
|
||||
CProfiles.AddAvatar(avatar);
|
||||
return avatar;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
catch
|
||||
@@ -540,10 +564,12 @@ namespace Vocaluxe.Base.Server
|
||||
public static bool SendPhoto(SPhotoData photoData)
|
||||
{
|
||||
if (photoData.Photo == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
string name = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
|
||||
string filePath = _SaveImage(photoData.Photo, name, CSettings.FolderNamePhotos);
|
||||
var name = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss");
|
||||
var filePath = _SaveImage(photoData.Photo, name, CSettings.FolderNamePhotos);
|
||||
if (!string.IsNullOrEmpty(filePath))
|
||||
{
|
||||
_PhotosOfThisRound.Add(filePath);
|
||||
@@ -555,7 +581,7 @@ namespace Vocaluxe.Base.Server
|
||||
|
||||
internal static string[] GetPhotosOfThisRound()
|
||||
{
|
||||
string[] result = _PhotosOfThisRound.ToArray();
|
||||
var result = _PhotosOfThisRound.ToArray();
|
||||
_PhotosOfThisRound.Clear();
|
||||
return result;
|
||||
}
|
||||
@@ -566,11 +592,13 @@ namespace Vocaluxe.Base.Server
|
||||
|
||||
public static byte[] GetSiteFile(string filename)
|
||||
{
|
||||
string path = "Website/" + filename;
|
||||
var path = "Website/" + filename;
|
||||
path = path.Replace("..", "");
|
||||
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/*string content = File.ReadAllText(path);
|
||||
|
||||
@@ -584,15 +612,20 @@ namespace Vocaluxe.Base.Server
|
||||
|
||||
private static string _CreateDelayedImage(string filename)
|
||||
{
|
||||
byte[] by = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(filename));
|
||||
var by = SHA1.Create().ComputeHash(Encoding.UTF8.GetBytes(filename));
|
||||
var sb = new StringBuilder();
|
||||
foreach (byte b in by)
|
||||
foreach (var b in by)
|
||||
{
|
||||
sb.Append(b.ToString("x2"));
|
||||
}
|
||||
|
||||
string hashedFilename = sb.ToString();
|
||||
var hashedFilename = sb.ToString();
|
||||
|
||||
if (!_DelayedImagePath.ContainsKey(hashedFilename))
|
||||
{
|
||||
_DelayedImagePath.Add(hashedFilename, filename);
|
||||
}
|
||||
|
||||
return hashedFilename;
|
||||
}
|
||||
|
||||
@@ -604,15 +637,18 @@ namespace Vocaluxe.Base.Server
|
||||
public static CBase64Image GetDelayedImage(string hashedFilename)
|
||||
{
|
||||
if (!_DelayedImagePath.ContainsKey(hashedFilename))
|
||||
{
|
||||
throw new FileNotFoundException("Image not found");
|
||||
}
|
||||
|
||||
string fileName = _DelayedImagePath[hashedFilename];
|
||||
var fileName = _DelayedImagePath[hashedFilename];
|
||||
|
||||
if (File.Exists(fileName))
|
||||
{
|
||||
Image image = Image.FromFile(fileName);
|
||||
var image = Image.FromFile(fileName);
|
||||
return new CBase64Image(image, image.RawFormat);
|
||||
}
|
||||
|
||||
throw new FileNotFoundException("Image not found");
|
||||
}
|
||||
#endregion
|
||||
@@ -620,43 +656,46 @@ namespace Vocaluxe.Base.Server
|
||||
#region songs
|
||||
public static SSongInfo GetSong(int songId)
|
||||
{
|
||||
CSong song = CSongs.GetSong(songId);
|
||||
var song = CSongs.GetSong(songId);
|
||||
return _GetSongInfo(song, true);
|
||||
}
|
||||
|
||||
|
||||
private static SSongInfo[] _SongInfoCache = null;
|
||||
|
||||
public static SSongInfo[] GetAllSongs()
|
||||
{
|
||||
bool sendCovers = CConfig.Config.Server.SongCountCoverThreshold == -1 || CConfig.Config.Server.SongCountCoverThreshold > CSongs.Songs.Count;
|
||||
var sendCovers = CConfig.Config.Server.SongCountCoverThreshold == -1 || CConfig.Config.Server.SongCountCoverThreshold > CSongs.Songs.Count;
|
||||
|
||||
if (_SongInfoCache == null)
|
||||
{
|
||||
List<CSong> songs = CSongs.Songs;
|
||||
var songs = CSongs.Songs;
|
||||
_SongInfoCache = (from s in songs
|
||||
select _GetSongInfo(s, sendCovers)).AsParallel().ToArray<SSongInfo>();
|
||||
}
|
||||
|
||||
|
||||
return _SongInfoCache;
|
||||
}
|
||||
|
||||
public static string GetMp3Path(int songId)
|
||||
{
|
||||
CSong song = CSongs.GetSong(songId);
|
||||
var song = CSongs.GetSong(songId);
|
||||
return song.GetMP3();
|
||||
}
|
||||
|
||||
public static int GetCurrentSongId()
|
||||
{
|
||||
CSong song = CGame.GetSong();
|
||||
var song = CGame.GetSong();
|
||||
if (song == null)
|
||||
{
|
||||
return -1;
|
||||
return song.ID;
|
||||
}
|
||||
|
||||
return song.Id;
|
||||
}
|
||||
|
||||
private static SSongInfo _GetSongInfo(CSong song, bool includeCover)
|
||||
{
|
||||
SSongInfo result = new SSongInfo();
|
||||
var result = new SSongInfo();
|
||||
if (song != null)
|
||||
{
|
||||
result.Title = song.Title;
|
||||
@@ -665,7 +704,7 @@ namespace Vocaluxe.Base.Server
|
||||
result.Language = song.Languages.FirstOrDefault();
|
||||
result.Year = song.Year;
|
||||
result.IsDuet = song.IsDuet;
|
||||
result.SongId = song.ID;
|
||||
result.SongId = song.Id;
|
||||
if (includeCover)
|
||||
{
|
||||
if (song.CoverFileName == "")
|
||||
@@ -677,8 +716,8 @@ namespace Vocaluxe.Base.Server
|
||||
result.Cover = new CBase64Image(_CreateDelayedImage(song.Folder + "\\" + song.CoverFileName));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
@@ -687,20 +726,25 @@ namespace Vocaluxe.Base.Server
|
||||
public static SPlaylistData[] GetPlaylists()
|
||||
{
|
||||
return (from p in CPlaylists.Playlists
|
||||
select _GetPlaylistInfo(p)).ToArray();
|
||||
select _GetPlaylistInfo(p)).ToArray();
|
||||
}
|
||||
|
||||
public static SPlaylistData GetPlaylist(int playlistId)
|
||||
{
|
||||
if (CPlaylists.Get(playlistId) == null)
|
||||
{
|
||||
throw new ArgumentException("invalid playlistId");
|
||||
}
|
||||
|
||||
return _GetPlaylistInfo(CPlaylists.Get(playlistId));
|
||||
}
|
||||
|
||||
public static void AddSongToPlaylist(int songId, int playlistId, bool allowDuplicates)
|
||||
{
|
||||
if (CPlaylists.Get(playlistId) == null)
|
||||
{
|
||||
throw new ArgumentException("invalid playlistId");
|
||||
}
|
||||
|
||||
if (allowDuplicates || !PlaylistContainsSong(songId, playlistId))
|
||||
{
|
||||
@@ -708,98 +752,128 @@ namespace Vocaluxe.Base.Server
|
||||
CPlaylists.Save(playlistId);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("song exists in this playlist");
|
||||
}
|
||||
}
|
||||
|
||||
public static void RemoveSongFromPlaylist(int position, int playlistId, int songId)
|
||||
{
|
||||
CPlaylistFile pl = CPlaylists.Get(playlistId);
|
||||
var pl = CPlaylists.Get(playlistId);
|
||||
if (pl == null)
|
||||
{
|
||||
throw new ArgumentException("invalid playlistId");
|
||||
}
|
||||
|
||||
if (!PlaylistContainsSong(songId, playlistId))
|
||||
{
|
||||
throw new ArgumentException("invalid songId");
|
||||
}
|
||||
|
||||
if (position < 0 || pl.Songs.Count <= position
|
||||
|| pl.Songs[position].SongID != songId)
|
||||
|| pl.Songs[position].SongId != songId)
|
||||
{
|
||||
throw new ArgumentException("invalid position");
|
||||
}
|
||||
|
||||
pl.DeleteSong(position);
|
||||
pl.Save();
|
||||
}
|
||||
|
||||
public static void MoveSongInPlaylist(int newPosition, int playlistId, int songId)
|
||||
{
|
||||
CPlaylistFile pl = CPlaylists.Get(playlistId);
|
||||
var pl = CPlaylists.Get(playlistId);
|
||||
if (pl == null)
|
||||
{
|
||||
throw new ArgumentException("invalid playlistId");
|
||||
}
|
||||
|
||||
if (!PlaylistContainsSong(songId, playlistId))
|
||||
{
|
||||
throw new ArgumentException("invalid songId");
|
||||
}
|
||||
|
||||
if (pl.Songs.Count < newPosition)
|
||||
{
|
||||
throw new ArgumentException("invalid newPosition");
|
||||
}
|
||||
|
||||
int oldPosition = pl.Songs.FindIndex(s => s.SongID == songId);
|
||||
var oldPosition = pl.Songs.FindIndex(s => s.SongId == songId);
|
||||
pl.MoveSong(oldPosition, newPosition);
|
||||
pl.Save();
|
||||
}
|
||||
|
||||
public static bool PlaylistContainsSong(int songId, int playlistId)
|
||||
{
|
||||
CPlaylistFile pl = CPlaylists.Get(playlistId);
|
||||
var pl = CPlaylists.Get(playlistId);
|
||||
if (pl == null)
|
||||
{
|
||||
throw new ArgumentException("invalid playlistId");
|
||||
return pl.Songs.Any(s => s.SongID == songId);
|
||||
}
|
||||
|
||||
return pl.Songs.Any(s => s.SongId == songId);
|
||||
}
|
||||
|
||||
public static SPlaylistSongInfo[] GetPlaylistSongs(int playlistId)
|
||||
{
|
||||
CPlaylistFile pl = CPlaylists.Get(playlistId);
|
||||
var pl = CPlaylists.Get(playlistId);
|
||||
if (pl == null)
|
||||
{
|
||||
throw new ArgumentException("invalid playlistId");
|
||||
}
|
||||
|
||||
return _GetPlaylistSongInfos(pl);
|
||||
}
|
||||
|
||||
private static SPlaylistSongInfo _GetPlaylistSongInfo(CPlaylistSong playlistSong, int playlistId, int playlistPos)
|
||||
{
|
||||
SPlaylistSongInfo result = new SPlaylistSongInfo();
|
||||
var result = new SPlaylistSongInfo();
|
||||
if (playlistSong != null)
|
||||
{
|
||||
result.PlaylistId = playlistId;
|
||||
result.GameMode = (int)playlistSong.GameMode;
|
||||
result.PlaylistPosition = playlistPos;
|
||||
result.Song = _GetSongInfo(CSongs.GetSong(playlistSong.SongID), true);
|
||||
result.Song = _GetSongInfo(CSongs.GetSong(playlistSong.SongId), true);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static SPlaylistSongInfo[] _GetPlaylistSongInfos(CPlaylistFile playlist)
|
||||
{
|
||||
SPlaylistSongInfo[] result = new SPlaylistSongInfo[playlist.Songs.Count];
|
||||
for (int i = 0; i < playlist.Songs.Count; i++)
|
||||
var result = new SPlaylistSongInfo[playlist.Songs.Count];
|
||||
for (var i = 0; i < playlist.Songs.Count; i++)
|
||||
{
|
||||
result[i] = _GetPlaylistSongInfo(playlist.Songs[i], playlist.Id, i);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static SPlaylistData _GetPlaylistInfo(CPlaylistFile playlist)
|
||||
{
|
||||
return new SPlaylistData
|
||||
{
|
||||
PlaylistId = playlist.Id,
|
||||
PlaylistName = playlist.Name,
|
||||
SongCount = playlist.Songs.Count,
|
||||
LastChanged = DateTime.Now.ToLongDateString()
|
||||
};
|
||||
{
|
||||
PlaylistId = playlist.Id,
|
||||
PlaylistName = playlist.Name,
|
||||
SongCount = playlist.Songs.Count,
|
||||
LastChanged = DateTime.Now.ToLongDateString()
|
||||
};
|
||||
}
|
||||
|
||||
public static void RemovePlaylist(int playlistId)
|
||||
{
|
||||
if (CPlaylists.Get(playlistId) == null)
|
||||
{
|
||||
throw new ArgumentException("invalid playlistId");
|
||||
}
|
||||
|
||||
CPlaylists.Delete(playlistId);
|
||||
}
|
||||
|
||||
public static int AddPlaylist(string playlistName)
|
||||
{
|
||||
int newPlaylistId = CPlaylists.NewPlaylist(playlistName);
|
||||
var newPlaylistId = CPlaylists.NewPlaylist(playlistName);
|
||||
CPlaylists.Save(newPlaylistId);
|
||||
|
||||
return newPlaylistId;
|
||||
@@ -809,31 +883,41 @@ namespace Vocaluxe.Base.Server
|
||||
#region user management
|
||||
public static bool ValidatePassword(Guid profileId, string password)
|
||||
{
|
||||
CProfile profile = CProfiles.GetProfile(profileId);
|
||||
var profile = CProfiles.GetProfile(profileId);
|
||||
if (profile == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (profile.PasswordHash == null)
|
||||
{
|
||||
if (string.IsNullOrEmpty(password))
|
||||
{
|
||||
return true; //Allow empty passwords
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
byte[] salt = profile.PasswordSalt;
|
||||
return _Hash((new UTF8Encoding()).GetBytes(password), salt).SequenceEqual(profile.PasswordHash);
|
||||
var salt = profile.PasswordSalt;
|
||||
return _Hash(new UTF8Encoding().GetBytes(password), salt).SequenceEqual(profile.PasswordHash);
|
||||
}
|
||||
|
||||
public static bool ValidatePassword(Guid profileId, byte[] hashedPassword)
|
||||
{
|
||||
CProfile profile = CProfiles.GetProfile(profileId);
|
||||
var profile = CProfiles.GetProfile(profileId);
|
||||
if (profile == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (profile.PasswordHash == null)
|
||||
{
|
||||
if (hashedPassword == null)
|
||||
{
|
||||
return true; //Allow empty passwords
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -843,38 +927,46 @@ namespace Vocaluxe.Base.Server
|
||||
|
||||
private static byte[] _GetPasswordSalt(Guid profileId)
|
||||
{
|
||||
CProfile profile = CProfiles.GetProfile(profileId);
|
||||
var profile = CProfiles.GetProfile(profileId);
|
||||
if (profile == null)
|
||||
{
|
||||
throw new ArgumentException("Invalid profileId");
|
||||
}
|
||||
|
||||
if (profile.PasswordHash == null)
|
||||
{
|
||||
throw new ArgumentException("Empty password");
|
||||
}
|
||||
|
||||
return profile.PasswordSalt;
|
||||
}
|
||||
|
||||
public static int GetUserRole(Guid profileId)
|
||||
{
|
||||
CProfile profile = CProfiles.GetProfile(profileId);
|
||||
var profile = CProfiles.GetProfile(profileId);
|
||||
if (profile == null)
|
||||
{
|
||||
throw new ArgumentException("Invalid profileId");
|
||||
}
|
||||
|
||||
//Hide TR_USERROLE_GUEST and TR_USERROLE_NORMAL
|
||||
//const EUserRole mask = (EUserRole.TR_USERROLE_GUEST | EUserRole.TR_USERROLE_NORMAL);
|
||||
|
||||
return (int)(profile.UserRole);
|
||||
return (int)profile.UserRole;
|
||||
}
|
||||
|
||||
public static void SetUserRole(Guid profileId, int userRole)
|
||||
{
|
||||
CProfile profile = CProfiles.GetProfile(profileId);
|
||||
var profile = CProfiles.GetProfile(profileId);
|
||||
if (profile == null)
|
||||
{
|
||||
throw new ArgumentException("Invalid profileId");
|
||||
}
|
||||
|
||||
var option = (EUserRole)userRole;
|
||||
|
||||
//Only allow the change of all options exept TR_USERROLE_GUEST and TR_USERROLE_NORMAL
|
||||
const EUserRole mask = (EUserRole.TR_USERROLE_GUEST | EUserRole.TR_USERROLE_NORMAL);
|
||||
const EUserRole mask = EUserRole.TR_USERROLE_GUEST | EUserRole.TR_USERROLE_NORMAL;
|
||||
option &= ~mask;
|
||||
|
||||
profile.UserRole = (profile.UserRole & mask) | option;
|
||||
@@ -886,9 +978,9 @@ namespace Vocaluxe.Base.Server
|
||||
|
||||
public static Guid GetUserIdFromUsername(string username)
|
||||
{
|
||||
IEnumerable<Guid> playerIds = (from p in CProfiles.GetProfiles()
|
||||
where String.Equals(p.PlayerName, username, StringComparison.OrdinalIgnoreCase)
|
||||
select p.ID);
|
||||
var playerIds = from p in CProfiles.GetProfiles()
|
||||
where String.Equals(p.PlayerName, username, StringComparison.OrdinalIgnoreCase)
|
||||
select p.Id;
|
||||
return playerIds.FirstOrDefault();
|
||||
}
|
||||
|
||||
@@ -896,7 +988,7 @@ namespace Vocaluxe.Base.Server
|
||||
{
|
||||
HashAlgorithm hashAlgo = new SHA256Managed();
|
||||
|
||||
byte[] data = new byte[password.Length + salt.Length];
|
||||
var data = new byte[password.Length + salt.Length];
|
||||
|
||||
password.CopyTo(data, 0);
|
||||
salt.CopyTo(data, password.Length);
|
||||
@@ -907,13 +999,15 @@ namespace Vocaluxe.Base.Server
|
||||
|
||||
private static string _SaveImage(CBase64Image imageDate, string name, string folder)
|
||||
{
|
||||
Image avatarImage = imageDate.GetImage();
|
||||
string extension = imageDate.GetImageType();
|
||||
var avatarImage = imageDate.GetImage();
|
||||
var extension = imageDate.GetImageType();
|
||||
|
||||
if (!Directory.Exists(folder))
|
||||
{
|
||||
Directory.CreateDirectory(folder);
|
||||
}
|
||||
|
||||
string file = CHelper.GetUniqueFileName(folder, name + "." + extension);
|
||||
var file = CHelper.GetUniqueFileName(folder, name + "." + extension);
|
||||
|
||||
avatarImage.Save(file);
|
||||
return file;
|
||||
|
||||
@@ -28,17 +28,20 @@ namespace Vocaluxe.Base.Server
|
||||
{
|
||||
private static Guid _GetSession()
|
||||
{
|
||||
Guid sessionKey = Guid.Empty;
|
||||
string sessionHeader =
|
||||
var sessionKey = Guid.Empty;
|
||||
var sessionHeader =
|
||||
((HttpRequestMessageProperty)OperationContext.Current.IncomingMessageProperties["httpRequest"]).Headers["session"];
|
||||
if (string.IsNullOrEmpty(sessionHeader))
|
||||
{
|
||||
return sessionKey;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
sessionKey = Guid.Parse(sessionHeader);
|
||||
}
|
||||
catch (Exception)
|
||||
{ }
|
||||
catch (Exception) { }
|
||||
|
||||
CSessionControl.ResetSessionTimeout(sessionKey);
|
||||
return sessionKey;
|
||||
}
|
||||
@@ -46,24 +49,28 @@ namespace Vocaluxe.Base.Server
|
||||
public void SendKeyEvent(string key)
|
||||
{
|
||||
if (!_CheckRight(EUserRights.UseKeyboard))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
CVocaluxeServer.DoTask(CVocaluxeServer.SendKeyEvent,key);
|
||||
CVocaluxeServer.DoTask(CVocaluxeServer.SendKeyEvent, key);
|
||||
}
|
||||
|
||||
public void SendKeyStringEvent(string keyString, bool isShiftPressed = false, bool isAltPressed = false, bool isCtrlPressed = false)
|
||||
{
|
||||
if (!_CheckRight(EUserRights.UseKeyboard))
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
CVocaluxeServer.DoTask(CVocaluxeServer.SendKeyStringEvent, keyString, isShiftPressed, isAltPressed, isCtrlPressed);
|
||||
}
|
||||
|
||||
#region profile
|
||||
public Guid GetOwnProfileId()
|
||||
{
|
||||
Guid sessionKey = _GetSession();
|
||||
var sessionKey = _GetSession();
|
||||
if (sessionKey == Guid.Empty)
|
||||
{
|
||||
if (WebOperationContext.Current != null)
|
||||
@@ -71,9 +78,11 @@ namespace Vocaluxe.Base.Server
|
||||
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
|
||||
WebOperationContext.Current.OutgoingResponse.StatusDescription = "No session";
|
||||
}
|
||||
|
||||
return Guid.Empty;
|
||||
}
|
||||
Guid profileId = CSessionControl.GetUserIdFromSession(sessionKey);
|
||||
|
||||
var profileId = CSessionControl.GetUserIdFromSession(sessionKey);
|
||||
if (profileId == Guid.Empty)
|
||||
{
|
||||
if (WebOperationContext.Current != null)
|
||||
@@ -81,20 +90,24 @@ namespace Vocaluxe.Base.Server
|
||||
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
|
||||
WebOperationContext.Current.OutgoingResponse.StatusDescription = "No session";
|
||||
}
|
||||
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
||||
return profileId;
|
||||
}
|
||||
|
||||
public void SendProfile(SProfileData profile)
|
||||
{
|
||||
Guid sessionKey = _GetSession();
|
||||
var sessionKey = _GetSession();
|
||||
|
||||
if (profile.ProfileId != Guid.Empty) //Guid.Empty is the id for a new profile
|
||||
{
|
||||
if (CSessionControl.GetUserIdFromSession(sessionKey) != profile.ProfileId
|
||||
&& !(_CheckRight(EUserRights.EditAllProfiles)))
|
||||
&& !_CheckRight(EUserRights.EditAllProfiles))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
CVocaluxeServer.DoTask(CVocaluxeServer.SendProfileData, profile);
|
||||
@@ -102,15 +115,16 @@ namespace Vocaluxe.Base.Server
|
||||
|
||||
public SProfileData GetProfile(Guid profileId)
|
||||
{
|
||||
Guid sessionKey = _GetSession();
|
||||
var sessionKey = _GetSession();
|
||||
if (CSessionControl.GetUserIdFromSession(sessionKey) == profileId || _CheckRight(EUserRights.ViewOtherProfiles))
|
||||
{
|
||||
bool isReadonly = (!CSessionControl.RequestRight(sessionKey, EUserRights.EditAllProfiles) &&
|
||||
CSessionControl.GetUserIdFromSession(sessionKey) != profileId);
|
||||
var isReadonly = !CSessionControl.RequestRight(sessionKey, EUserRights.EditAllProfiles) &&
|
||||
CSessionControl.GetUserIdFromSession(sessionKey) != profileId;
|
||||
|
||||
|
||||
return CVocaluxeServer.DoTask(CVocaluxeServer.GetProfileData,profileId, isReadonly);
|
||||
return CVocaluxeServer.DoTask(CVocaluxeServer.GetProfileData, profileId, isReadonly);
|
||||
}
|
||||
|
||||
return new SProfileData();
|
||||
}
|
||||
|
||||
@@ -124,14 +138,16 @@ namespace Vocaluxe.Base.Server
|
||||
public void SendPhoto(SPhotoData photo)
|
||||
{
|
||||
if (_CheckRight(EUserRights.UploadPhotos))
|
||||
{
|
||||
CVocaluxeServer.DoTask(CVocaluxeServer.SendPhoto, photo);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region website
|
||||
public Guid Login(string username, string password)
|
||||
{
|
||||
Guid sessionId = CSessionControl.OpenSession(username, password);
|
||||
var sessionId = CSessionControl.OpenSession(username, password);
|
||||
if (sessionId == Guid.Empty)
|
||||
{
|
||||
if (WebOperationContext.Current != null)
|
||||
@@ -140,21 +156,24 @@ namespace Vocaluxe.Base.Server
|
||||
WebOperationContext.Current.OutgoingResponse.StatusDescription = "Wrong username or password";
|
||||
}
|
||||
}
|
||||
|
||||
return sessionId;
|
||||
}
|
||||
|
||||
public void Logout()
|
||||
{
|
||||
Guid sessionKey = _GetSession();
|
||||
CSessionControl.InvalidateSessionByID(sessionKey);
|
||||
var sessionKey = _GetSession();
|
||||
CSessionControl.InvalidateSessionById(sessionKey);
|
||||
}
|
||||
|
||||
public Stream Index()
|
||||
{
|
||||
if (WebOperationContext.Current != null)
|
||||
{
|
||||
WebOperationContext.Current.OutgoingResponse.ContentType = "text/html";
|
||||
}
|
||||
|
||||
return new MemoryStream(CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile,"index.html"));
|
||||
return new MemoryStream(CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "index.html"));
|
||||
}
|
||||
|
||||
public Stream GetJsFile(string filename)
|
||||
@@ -168,13 +187,18 @@ namespace Vocaluxe.Base.Server
|
||||
DateTime.UtcNow.AddHours(4).ToString("r"));
|
||||
}
|
||||
|
||||
byte[] data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "js/" + filename);
|
||||
var data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "js/" + filename);
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
return new MemoryStream(data);
|
||||
}
|
||||
|
||||
if (WebOperationContext.Current != null)
|
||||
{
|
||||
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -189,12 +213,18 @@ namespace Vocaluxe.Base.Server
|
||||
DateTime.UtcNow.AddHours(4).ToString("r"));
|
||||
}
|
||||
|
||||
byte[] data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "css/" + filename);
|
||||
var data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "css/" + filename);
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
return new MemoryStream(data);
|
||||
}
|
||||
|
||||
if (WebOperationContext.Current != null)
|
||||
{
|
||||
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -209,12 +239,18 @@ namespace Vocaluxe.Base.Server
|
||||
DateTime.UtcNow.AddYears(1).ToString("r"));
|
||||
}
|
||||
|
||||
byte[] data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "css\\images\\" + filename);
|
||||
var data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "css\\images\\" + filename);
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
return new MemoryStream(data);
|
||||
}
|
||||
|
||||
if (WebOperationContext.Current != null)
|
||||
{
|
||||
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -229,12 +265,18 @@ namespace Vocaluxe.Base.Server
|
||||
DateTime.UtcNow.AddYears(1).ToString("r"));
|
||||
}
|
||||
|
||||
byte[] data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "img/" + filename);
|
||||
var data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "img/" + filename);
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
return new MemoryStream(data);
|
||||
}
|
||||
|
||||
if (WebOperationContext.Current != null)
|
||||
{
|
||||
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -249,13 +291,18 @@ namespace Vocaluxe.Base.Server
|
||||
DateTime.UtcNow.AddHours(4).ToString("r"));
|
||||
}
|
||||
|
||||
byte[] data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "locales/" + filename);
|
||||
var data = CVocaluxeServer.DoTask(CVocaluxeServer.GetSiteFile, "locales/" + filename);
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
return new MemoryStream(data);
|
||||
}
|
||||
|
||||
if (WebOperationContext.Current != null)
|
||||
{
|
||||
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -303,18 +350,21 @@ namespace Vocaluxe.Base.Server
|
||||
}
|
||||
|
||||
|
||||
String path = CVocaluxeServer.DoTask(CVocaluxeServer.GetMp3Path,songId);
|
||||
var path = CVocaluxeServer.DoTask(CVocaluxeServer.GetMp3Path, songId);
|
||||
path = path.Replace("..", "");
|
||||
|
||||
|
||||
if (!File.Exists(path)
|
||||
|| !(path.EndsWith(".mp3", StringComparison.InvariantCulture)
|
||||
|| path.EndsWith(".ogg", StringComparison.InvariantCulture)
|
||||
|| path.EndsWith(".wav", StringComparison.InvariantCulture)
|
||||
|| path.EndsWith(".webm", StringComparison.InvariantCulture)))
|
||||
if (!File.Exists(path)
|
||||
|| !(path.EndsWith(".mp3", StringComparison.InvariantCulture)
|
||||
|| path.EndsWith(".ogg", StringComparison.InvariantCulture)
|
||||
|| path.EndsWith(".wav", StringComparison.InvariantCulture)
|
||||
|| path.EndsWith(".webm", StringComparison.InvariantCulture)))
|
||||
{
|
||||
if (WebOperationContext.Current != null)
|
||||
{
|
||||
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.NotFound;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -364,13 +414,14 @@ namespace Vocaluxe.Base.Server
|
||||
|
||||
return new SPlaylistData();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void AddSongToPlaylist(int songId, int playlistId, bool allowDuplicates)
|
||||
{
|
||||
if (!_CheckRight(EUserRights.AddSongToPlaylist))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -389,7 +440,9 @@ namespace Vocaluxe.Base.Server
|
||||
public void RemoveSongFromPlaylist(int position, int playlistId, int songId)
|
||||
{
|
||||
if (!_CheckRight(EUserRights.RemoveSongsFromPlaylists))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -408,7 +461,9 @@ namespace Vocaluxe.Base.Server
|
||||
public void MoveSongInPlaylist(int newPosition, int playlistId, int songId)
|
||||
{
|
||||
if (!_CheckRight(EUserRights.ReorderPlaylists))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -455,6 +510,7 @@ namespace Vocaluxe.Base.Server
|
||||
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
|
||||
WebOperationContext.Current.OutgoingResponse.StatusDescription = e.Message;
|
||||
}
|
||||
|
||||
return new SPlaylistSongInfo[0];
|
||||
}
|
||||
}
|
||||
@@ -462,7 +518,9 @@ namespace Vocaluxe.Base.Server
|
||||
public void RemovePlaylist(int playlistId)
|
||||
{
|
||||
if (!_CheckRight(EUserRights.DeletePlaylists))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -481,7 +539,9 @@ namespace Vocaluxe.Base.Server
|
||||
public int AddPlaylist(string playlistName)
|
||||
{
|
||||
if (!_CheckRight(EUserRights.CreatePlaylists))
|
||||
return -1;
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -509,7 +569,9 @@ namespace Vocaluxe.Base.Server
|
||||
public void SetUserRole(Guid profileId, int userRole)
|
||||
{
|
||||
if (_CheckRight(EUserRights.EditAllProfiles))
|
||||
{
|
||||
CVocaluxeServer.DoTaskWithoutReturn(CVocaluxeServer.SetUserRole, profileId, userRole);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasUserRight(int right)
|
||||
@@ -519,7 +581,7 @@ namespace Vocaluxe.Base.Server
|
||||
|
||||
private static bool _CheckRight(EUserRights requestedRight)
|
||||
{
|
||||
Guid sessionKey = _GetSession();
|
||||
var sessionKey = _GetSession();
|
||||
|
||||
if (sessionKey == Guid.Empty)
|
||||
{
|
||||
@@ -528,6 +590,7 @@ namespace Vocaluxe.Base.Server
|
||||
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
|
||||
WebOperationContext.Current.OutgoingResponse.StatusDescription = "No session";
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -538,20 +601,26 @@ namespace Vocaluxe.Base.Server
|
||||
WebOperationContext.Current.OutgoingResponse.StatusCode = HttpStatusCode.Forbidden;
|
||||
WebOperationContext.Current.OutgoingResponse.StatusDescription = "Not allowed";
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool _CheckRightWithNoErrorMessage(EUserRights requestedRight)
|
||||
{
|
||||
Guid sessionKey = _GetSession();
|
||||
var sessionKey = _GetSession();
|
||||
|
||||
if (sessionKey == Guid.Empty)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!CSessionControl.RequestRight(sessionKey, requestedRight))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -26,185 +26,185 @@ namespace Vocaluxe.Base.Server
|
||||
public interface ICWebservice
|
||||
{
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/sendKeyEvent?key={key}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/sendKeyEvent?key={key}")]
|
||||
void SendKeyEvent(string key);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/sendKeyStringEvent?keyString={keyString}&shift={isShiftPressed}&alt={isAltPressed}&ctrl={isCtrlPressed}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/sendKeyStringEvent?keyString={keyString}&shift={isShiftPressed}&alt={isAltPressed}&ctrl={isCtrlPressed}")]
|
||||
void SendKeyStringEvent(string keyString, bool isShiftPressed = false, bool isAltPressed = false, bool isCtrlPressed = false);
|
||||
|
||||
#region profile
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getOwnProfileId")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getOwnProfileId")]
|
||||
Guid GetOwnProfileId();
|
||||
|
||||
[OperationContract, WebInvoke(Method = "POST",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/sendProfile")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/sendProfile")]
|
||||
void SendProfile(SProfileData profile);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getProfile?profileId={profileId}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getProfile?profileId={profileId}")]
|
||||
SProfileData GetProfile(Guid profileId);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getProfileList")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getProfileList")]
|
||||
SProfileData[] GetProfileList();
|
||||
#endregion
|
||||
|
||||
#region photo
|
||||
[OperationContract, WebInvoke(Method = "POST",
|
||||
RequestFormat = WebMessageFormat.Json,
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/sendPhoto")]
|
||||
RequestFormat = WebMessageFormat.Json,
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/sendPhoto")]
|
||||
void SendPhoto(SPhotoData photo);
|
||||
#endregion
|
||||
|
||||
#region website
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/login?username={username}&password={password}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/login?username={username}&password={password}")]
|
||||
Guid Login(string username, string password);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/logout")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/logout")]
|
||||
void Logout();
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "")]
|
||||
Stream Index();
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/js/{filename}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/js/{filename}")]
|
||||
Stream GetJsFile(String filename);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/css/{filename}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/css/{filename}")]
|
||||
Stream GetCssFile(String filename);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/css/images/{filename}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/css/images/{filename}")]
|
||||
Stream GetCssImageFile(String filename);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/img/{filename}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/img/{filename}")]
|
||||
Stream GetImgFile(String filename);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/locales/{filename}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/locales/{filename}")]
|
||||
Stream GetLocaleFile(String filename);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/delayedImage?id={id}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/delayedImage?id={id}")]
|
||||
CBase64Image GetDelayedImage(String id);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/isServerOnline")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/isServerOnline")]
|
||||
bool IsServerOnline();
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getServerVersion")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getServerVersion")]
|
||||
String GetServerVersion();
|
||||
#endregion
|
||||
|
||||
#region songs
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getSong?songId={songId}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getSong?songId={songId}")]
|
||||
SSongInfo GetSong(int songId);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getCurrentSongId")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getCurrentSongId")]
|
||||
int GetCurrentSongId();
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getAllSongs")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getAllSongs")]
|
||||
SSongInfo[] GetAllSongs();
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getMp3?songId={songId}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getMp3?songId={songId}")]
|
||||
Stream GetMp3File(int songId);
|
||||
#endregion
|
||||
|
||||
#region playlist
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getPlaylists")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getPlaylists")]
|
||||
SPlaylistData[] GetPlaylists();
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getPlaylist?id={playlistId}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getPlaylist?id={playlistId}")]
|
||||
SPlaylistData GetPlaylist(int playlistId);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/addSongToPlaylist?songId={songId}&playlistId={playlistId}&duplicates={allowDuplicates}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/addSongToPlaylist?songId={songId}&playlistId={playlistId}&duplicates={allowDuplicates}")]
|
||||
void AddSongToPlaylist(int songId, int playlistId, bool allowDuplicates);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/removeSongFromPlaylist?position={position}&playlistId={playlistId}&songId={songId}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/removeSongFromPlaylist?position={position}&playlistId={playlistId}&songId={songId}")]
|
||||
void RemoveSongFromPlaylist(int position, int playlistId, int songId);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/moveSongInPlaylist?newPosition={newPosition}&playlistId={playlistId}&songId={songId}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/moveSongInPlaylist?newPosition={newPosition}&playlistId={playlistId}&songId={songId}")]
|
||||
void MoveSongInPlaylist(int newPosition, int playlistId, int songId);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/playlistContainsSong?songId={songId}&playlistId={playlistId}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/playlistContainsSong?songId={songId}&playlistId={playlistId}")]
|
||||
bool PlaylistContainsSong(int songId, int playlistId);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getPlaylistSongs?playlistId={playlistId}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getPlaylistSongs?playlistId={playlistId}")]
|
||||
SPlaylistSongInfo[] GetPlaylistSongs(int playlistId);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/removePlaylist?playlistId={playlistId}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/removePlaylist?playlistId={playlistId}")]
|
||||
void RemovePlaylist(int playlistId);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/addPlaylist?playlistName={playlistName}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/addPlaylist?playlistName={playlistName}")]
|
||||
int AddPlaylist(string playlistName);
|
||||
#endregion
|
||||
|
||||
#region user management
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getUserRole?profileId={profileId}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/getUserRole?profileId={profileId}")]
|
||||
int GetUserRole(Guid profileId);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/setUserRole?profileId={profileId}&userRole={userRole}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/setUserRole?profileId={profileId}&userRole={userRole}")]
|
||||
void SetUserRole(Guid profileId, int userRole);
|
||||
|
||||
[OperationContract, WebInvoke(Method = "GET",
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/hasUserRight?right={right}")]
|
||||
ResponseFormat = WebMessageFormat.Json,
|
||||
UriTemplate = "/hasUserRight?right={right}")]
|
||||
bool HasUserRight(int right);
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -21,37 +21,20 @@ namespace Vocaluxe.Base.Server
|
||||
{
|
||||
class CSession
|
||||
{
|
||||
private readonly Guid _ID;
|
||||
public Guid Id
|
||||
{
|
||||
get { return _ID; }
|
||||
}
|
||||
public Guid Id { get; }
|
||||
|
||||
private readonly Guid _ProfileId;
|
||||
public Guid ProfileId
|
||||
{
|
||||
get { return _ProfileId; }
|
||||
}
|
||||
public Guid ProfileId { get; }
|
||||
|
||||
private readonly EUserRoles _Roles;
|
||||
internal EUserRoles Roles
|
||||
{
|
||||
get { return _Roles; }
|
||||
}
|
||||
|
||||
private DateTime _LastSeen;
|
||||
public DateTime LastSeen
|
||||
{
|
||||
get { return _LastSeen; }
|
||||
internal set { _LastSeen = value; }
|
||||
}
|
||||
internal EUserRoles Roles { get; }
|
||||
|
||||
public DateTime LastSeen { get; internal set; }
|
||||
|
||||
public CSession(Guid id, Guid profileId, EUserRoles roles)
|
||||
{
|
||||
_ID = id;
|
||||
_ProfileId = profileId;
|
||||
_Roles = roles;
|
||||
_LastSeen = DateTime.Now;
|
||||
Id = id;
|
||||
ProfileId = profileId;
|
||||
Roles = roles;
|
||||
LastSeen = DateTime.Now;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,32 +31,34 @@ namespace Vocaluxe.Base.Server
|
||||
static CSessionControl()
|
||||
{
|
||||
_ActiveSessions = new Dictionary<Guid, CSession>();
|
||||
Timer timer = new Timer(_UserTimeoutCheckIntervall) {AutoReset = true, Enabled = true};
|
||||
var timer = new Timer(_UserTimeoutCheckIntervall) { AutoReset = true, Enabled = true };
|
||||
timer.Elapsed += _CheckForUserTimeouts;
|
||||
timer.Start();
|
||||
}
|
||||
|
||||
private static void _CheckForUserTimeouts(object sender, ElapsedEventArgs e)
|
||||
{
|
||||
var sessionIdsToRemove = _ActiveSessions.Where(pair => (DateTime.Now-pair.Value.LastSeen).TotalMilliseconds > _UserTimeout)
|
||||
.Select(pair => pair.Key)
|
||||
.ToList();
|
||||
var sessionIdsToRemove = _ActiveSessions.Where(pair => (DateTime.Now - pair.Value.LastSeen).TotalMilliseconds > _UserTimeout)
|
||||
.Select(pair => pair.Key)
|
||||
.ToList();
|
||||
|
||||
foreach (var sessionToRemove in sessionIdsToRemove)
|
||||
{
|
||||
InvalidateSessionByID(sessionToRemove);
|
||||
InvalidateSessionById(sessionToRemove);
|
||||
}
|
||||
}
|
||||
|
||||
public static Guid OpenSession(string userName, string password)
|
||||
{
|
||||
if (!_ValidateUserAndPassword(userName, password))
|
||||
{
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
||||
Guid newId = Guid.NewGuid();
|
||||
Guid id = _GetProfileIdFormUsername(userName);
|
||||
EUserRoles roles = _GetUserRoles(id);
|
||||
CSession session = new CSession(newId, id, roles);
|
||||
var newId = Guid.NewGuid();
|
||||
var id = _GetProfileIdFormUsername(userName);
|
||||
var roles = _GetUserRoles(id);
|
||||
var session = new CSession(newId, id, roles);
|
||||
//InvalidateSessions(id);
|
||||
_ActiveSessions.Add(newId, session);
|
||||
|
||||
@@ -80,13 +82,15 @@ namespace Vocaluxe.Base.Server
|
||||
|
||||
internal static void InvalidateSessionByProfile(Guid profileId)
|
||||
{
|
||||
foreach (KeyValuePair<Guid, CSession> s in (from kv in _ActiveSessions
|
||||
where kv.Value.ProfileId == profileId
|
||||
select kv).ToList())
|
||||
foreach (var s in (from kv in _ActiveSessions
|
||||
where kv.Value.ProfileId == profileId
|
||||
select kv).ToList())
|
||||
{
|
||||
_ActiveSessions.Remove(s.Key);
|
||||
}
|
||||
}
|
||||
|
||||
internal static void InvalidateSessionByID(Guid sessionId)
|
||||
internal static void InvalidateSessionById(Guid sessionId)
|
||||
{
|
||||
if (_ActiveSessions.ContainsKey(sessionId))
|
||||
{
|
||||
@@ -96,14 +100,17 @@ namespace Vocaluxe.Base.Server
|
||||
|
||||
internal static bool RequestRight(Guid sessionId, EUserRights requestedRight)
|
||||
{
|
||||
return ((CUserRoleControl.GetUserRightsFromUserRole(_ActiveSessions[sessionId].Roles)
|
||||
.HasFlag(requestedRight)));
|
||||
return CUserRoleControl.GetUserRightsFromUserRole(_ActiveSessions[sessionId].Roles)
|
||||
.HasFlag(requestedRight);
|
||||
}
|
||||
|
||||
internal static Guid GetUserIdFromSession(Guid sessionId)
|
||||
{
|
||||
if (!_ActiveSessions.ContainsKey(sessionId))
|
||||
{
|
||||
return Guid.Empty;
|
||||
}
|
||||
|
||||
return _ActiveSessions[sessionId].ProfileId;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,55 +23,55 @@ namespace Vocaluxe.Base.Server
|
||||
static class CUserRoleControl
|
||||
{
|
||||
private static readonly Dictionary<EUserRoles, EUserRights> _RoleRightsMapping = new Dictionary<EUserRoles, EUserRights>
|
||||
{
|
||||
{
|
||||
{
|
||||
EUserRoles.TR_USERROLE_ADMIN,
|
||||
(EUserRights.EditAllProfiles |
|
||||
EUserRights.UploadPhotos |
|
||||
EUserRights.ViewOtherProfiles |
|
||||
EUserRights.UseKeyboard |
|
||||
EUserRights.AddSongToPlaylist |
|
||||
EUserRights.ReorderPlaylists |
|
||||
EUserRights.CreatePlaylists |
|
||||
EUserRights.DeletePlaylists |
|
||||
EUserRights.RemoveSongsFromPlaylists)
|
||||
},
|
||||
{
|
||||
EUserRoles.TR_USERROLE_GUEST,
|
||||
EUserRights.None
|
||||
},
|
||||
{
|
||||
EUserRoles.TR_USERROLE_NORMAL,
|
||||
(EUserRights.UploadPhotos |
|
||||
EUserRights.ViewOtherProfiles)
|
||||
},
|
||||
{
|
||||
EUserRoles.TR_USERROLE_KEYBOARDUSER,
|
||||
EUserRights.UseKeyboard
|
||||
},
|
||||
{
|
||||
EUserRoles.TR_USERROLE_ADDSONGSUSER,
|
||||
EUserRights.AddSongToPlaylist
|
||||
},
|
||||
{
|
||||
EUserRoles.TR_USERROLE_PLAYLISTEDITOR,
|
||||
(EUserRights.AddSongToPlaylist |
|
||||
EUserRights.ReorderPlaylists |
|
||||
EUserRights.CreatePlaylists |
|
||||
EUserRights.DeletePlaylists |
|
||||
EUserRights.RemoveSongsFromPlaylists)
|
||||
},
|
||||
{
|
||||
EUserRoles.TR_USERROLE_PROFILEEDITOR,
|
||||
EUserRights.EditAllProfiles
|
||||
}
|
||||
};
|
||||
EUserRoles.TR_USERROLE_ADMIN,
|
||||
EUserRights.EditAllProfiles |
|
||||
EUserRights.UploadPhotos |
|
||||
EUserRights.ViewOtherProfiles |
|
||||
EUserRights.UseKeyboard |
|
||||
EUserRights.AddSongToPlaylist |
|
||||
EUserRights.ReorderPlaylists |
|
||||
EUserRights.CreatePlaylists |
|
||||
EUserRights.DeletePlaylists |
|
||||
EUserRights.RemoveSongsFromPlaylists
|
||||
},
|
||||
{
|
||||
EUserRoles.TR_USERROLE_GUEST,
|
||||
EUserRights.None
|
||||
},
|
||||
{
|
||||
EUserRoles.TR_USERROLE_NORMAL,
|
||||
EUserRights.UploadPhotos |
|
||||
EUserRights.ViewOtherProfiles
|
||||
},
|
||||
{
|
||||
EUserRoles.TR_USERROLE_KEYBOARDUSER,
|
||||
EUserRights.UseKeyboard
|
||||
},
|
||||
{
|
||||
EUserRoles.TR_USERROLE_ADDSONGSUSER,
|
||||
EUserRights.AddSongToPlaylist
|
||||
},
|
||||
{
|
||||
EUserRoles.TR_USERROLE_PLAYLISTEDITOR,
|
||||
EUserRights.AddSongToPlaylist |
|
||||
EUserRights.ReorderPlaylists |
|
||||
EUserRights.CreatePlaylists |
|
||||
EUserRights.DeletePlaylists |
|
||||
EUserRights.RemoveSongsFromPlaylists
|
||||
},
|
||||
{
|
||||
EUserRoles.TR_USERROLE_PROFILEEDITOR,
|
||||
EUserRights.EditAllProfiles
|
||||
}
|
||||
};
|
||||
|
||||
internal static EUserRights GetUserRightsFromUserRole(EUserRoles userRole)
|
||||
{
|
||||
return _RoleRightsMapping.Where(role => userRole.HasFlag(role.Key))
|
||||
.Select(role => role.Value)
|
||||
.Aggregate(EUserRights.None, (current, r) => current | r);
|
||||
.Select(role => role.Value)
|
||||
.Aggregate(EUserRights.None, (current, r) => current | r);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,9 +83,9 @@ namespace Vocaluxe.Base.Server
|
||||
|
||||
public CBase64Image(Image img, ImageFormat format)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
var ms = new MemoryStream();
|
||||
img.Save(ms, format);
|
||||
string formatString = ImageCodecInfo.GetImageEncoders().FirstOrDefault(x => x.FormatID == format.Guid).FilenameExtension.Replace("*.", "").ToLower();
|
||||
var formatString = ImageCodecInfo.GetImageEncoders().FirstOrDefault(x => x.FormatID == format.Guid).FilenameExtension.Replace("*.", "").ToLower();
|
||||
base64Data = "data:image/" + formatString + ";base64," + Convert.ToBase64String(ms.ToArray());
|
||||
}
|
||||
|
||||
@@ -96,17 +96,17 @@ namespace Vocaluxe.Base.Server
|
||||
|
||||
public Image GetImage()
|
||||
{
|
||||
string onlyBase64Data = base64Data.Substring(base64Data.IndexOf(";base64,") + (";base64,").Length);
|
||||
byte[] imageData = Convert.FromBase64String(onlyBase64Data);
|
||||
MemoryStream ms = new MemoryStream(imageData, 0, imageData.Length);
|
||||
var onlyBase64Data = base64Data.Substring(base64Data.IndexOf(";base64,") + ";base64,".Length);
|
||||
var imageData = Convert.FromBase64String(onlyBase64Data);
|
||||
var ms = new MemoryStream(imageData, 0, imageData.Length);
|
||||
ms.Write(imageData, 0, imageData.Length);
|
||||
Image image = Image.FromStream(ms, true);
|
||||
var image = Image.FromStream(ms, true);
|
||||
return image;
|
||||
}
|
||||
|
||||
public string GetImageType()
|
||||
{
|
||||
Match match = Regex.Match(base64Data, "(?<=data:image/)[a-zA-Z]+(?=;base64)");
|
||||
var match = Regex.Match(base64Data, "(?<=data:image/)[a-zA-Z]+(?=;base64)");
|
||||
return match.Success ? match.Groups[0].Value : "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,19 +16,20 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using VocaluxeLib.Log;
|
||||
|
||||
namespace Vocaluxe.Base.ThemeSystem
|
||||
{
|
||||
class CBaseSkin : CSkin
|
||||
{
|
||||
public CBaseSkin(string folder, string file, CTheme parent) : base(folder, file, parent) {}
|
||||
public CBaseSkin(string folder, string file, CTheme parent) : base(folder, file, parent) { }
|
||||
|
||||
public override bool Load()
|
||||
{
|
||||
if (!base.Load())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_CheckRequiredElements())
|
||||
{
|
||||
@@ -41,18 +42,30 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
|
||||
private bool _CheckRequiredElements()
|
||||
{
|
||||
List<string> missingTextures = _Required.Textures.FindAll(name => !_Textures.ContainsKey(name));
|
||||
List<string> missingVideos = _Required.Videos.FindAll(name => !_Videos.ContainsKey(name));
|
||||
List<string> missingColors = _Required.Colors.FindAll(name => !_Data.Colors.ContainsKey(name));
|
||||
var missingTextures = _Required.Textures.FindAll(name => !_Textures.ContainsKey(name));
|
||||
var missingVideos = _Required.Videos.FindAll(name => !_Videos.ContainsKey(name));
|
||||
var missingColors = _Required.Colors.FindAll(name => !_Data.Colors.ContainsKey(name));
|
||||
if (missingTextures.Count + missingVideos.Count + missingColors.Count == 0)
|
||||
{
|
||||
return true;
|
||||
string msg = "The skin \"" + this + "\" is missing the following elements: ";
|
||||
}
|
||||
|
||||
var msg = "The skin \"" + this + "\" is missing the following elements: ";
|
||||
if (missingTextures.Count > 0)
|
||||
{
|
||||
msg += Environment.NewLine + "Textures: " + String.Join(", ", missingTextures);
|
||||
}
|
||||
|
||||
if (missingVideos.Count > 0)
|
||||
{
|
||||
msg += Environment.NewLine + "Videos: " + String.Join(", ", missingVideos);
|
||||
}
|
||||
|
||||
if (missingColors.Count > 0)
|
||||
{
|
||||
msg += Environment.NewLine + "Colors: " + String.Join(", ", missingColors);
|
||||
}
|
||||
|
||||
CLog.Error(msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
}
|
||||
}
|
||||
|
||||
public CBaseTheme(string filePath) : base(filePath, -1) {}
|
||||
public CBaseTheme(string filePath) : base(filePath, -1) { }
|
||||
|
||||
protected override CSkin _GetNewSkin(string path, string file)
|
||||
{
|
||||
@@ -50,7 +50,9 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
protected override bool _Load()
|
||||
{
|
||||
if (!_Data.Cursor.HasValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return CFonts.LoadThemeFonts(_Data.Fonts, Path.Combine(_Folder, Name, CSettings.FolderNameThemeFonts), Name, -1);
|
||||
}
|
||||
@@ -59,18 +61,28 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
{
|
||||
CSkin skin;
|
||||
if (!_Skins.TryGetValue(CConfig.Config.Theme.Skin, out skin))
|
||||
{
|
||||
skin = _Skins.Values.FirstOrDefault();
|
||||
}
|
||||
|
||||
while (skin != null)
|
||||
{
|
||||
if (skin.Load())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
skin.Unload();
|
||||
CLog.Error("Failed to load skin " + skin + "! Removing...", true);
|
||||
_Skins.Remove(skin.Name);
|
||||
skin = _Skins.Values.FirstOrDefault();
|
||||
}
|
||||
|
||||
if (skin == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CurrentSkin = skin;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -25,41 +25,57 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
{
|
||||
private CSkin _BaseSkin;
|
||||
|
||||
public CPartySkin(string folder, string file, CTheme parent) : base(folder, file, parent) {}
|
||||
public CPartySkin(string folder, string file, CTheme parent) : base(folder, file, parent) { }
|
||||
|
||||
public override bool Load()
|
||||
{
|
||||
_BaseSkin = CThemes.CurrentThemes[-1].CurrentSkin;
|
||||
if (!base.Load())
|
||||
{
|
||||
return false;
|
||||
for (int i = 1; i <= CSettings.MaxNumPlayer; i++)
|
||||
}
|
||||
|
||||
for (var i = 1; i <= CSettings.MaxNumPlayer; i++)
|
||||
{
|
||||
if (!_Data.Colors.ContainsKey("Player" + i))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
CLog.Debug("Party themes cannot contain player colors. They will be ignored!");
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool GetColor(string name, out SColorF color)
|
||||
{
|
||||
if (_Parent.Name == "Default" && !_Required.Colors.Contains(name))
|
||||
{
|
||||
CLog.Debug("Non-Default color: " + name);
|
||||
}
|
||||
|
||||
return base.GetColor(name, out color) || _BaseSkin.GetColor(name, out color);
|
||||
}
|
||||
|
||||
public override CVideoStream GetVideo(string name, bool loop)
|
||||
{
|
||||
if (_Parent.Name == "Default" && !_Required.Videos.Contains(name))
|
||||
{
|
||||
CLog.Debug("Non-Default color: " + name);
|
||||
}
|
||||
|
||||
return base.GetVideo(name, loop) ?? _BaseSkin.GetVideo(name, loop);
|
||||
}
|
||||
|
||||
public override CTextureRef GetTexture(string name)
|
||||
{
|
||||
if (_Parent.Name == "Default" && !_Required.Textures.Contains(name))
|
||||
{
|
||||
CLog.Debug("Non-Default color: " + name);
|
||||
}
|
||||
|
||||
return base.GetTexture(name) ?? _BaseSkin.GetTexture(name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,12 +25,12 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
{
|
||||
class CPartyTheme : CTheme
|
||||
{
|
||||
public CPartyTheme(string filePath, int partyModeID) : base(filePath, partyModeID) {}
|
||||
public CPartyTheme(string filePath, int partyModeId) : base(filePath, partyModeId) { }
|
||||
|
||||
public override void Unload()
|
||||
{
|
||||
base.Unload();
|
||||
CFonts.UnloadPartyModeFonts(PartyModeID);
|
||||
CFonts.UnloadPartyModeFonts(PartyModeId);
|
||||
}
|
||||
|
||||
protected override CSkin _GetNewSkin(string path, string file)
|
||||
@@ -40,7 +40,7 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
|
||||
protected override bool _Load()
|
||||
{
|
||||
return CFonts.LoadThemeFonts(_Data.Fonts, Path.Combine(_Folder, "..", CSettings.FolderNamePartyModeFonts), Name, PartyModeID);
|
||||
return CFonts.LoadThemeFonts(_Data.Fonts, Path.Combine(_Folder, "..", CSettings.FolderNamePartyModeFonts), Name, PartyModeId);
|
||||
}
|
||||
|
||||
private CSkin _GetSkinToLoad(int fallbackNum)
|
||||
@@ -60,25 +60,36 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
default:
|
||||
throw new ArgumentException();
|
||||
}
|
||||
|
||||
return skin;
|
||||
}
|
||||
|
||||
protected override bool _LoadSkin()
|
||||
{
|
||||
CSkin skin = null;
|
||||
for (int i = 0; i < 3; i++)
|
||||
for (var i = 0; i < 3; i++)
|
||||
{
|
||||
skin = _GetSkinToLoad(i);
|
||||
if (skin == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (skin.Load())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
skin.Unload();
|
||||
CLog.Error("Failed to load skin " + skin + "! Removing...", true);
|
||||
_Skins.Remove(skin.Name);
|
||||
}
|
||||
|
||||
if (skin == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
CurrentSkin = skin;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -19,12 +19,12 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml.Serialization;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Draw;
|
||||
using VocaluxeLib.Xml;
|
||||
using System.Linq;
|
||||
using VocaluxeLib.Log;
|
||||
using VocaluxeLib.Xml;
|
||||
|
||||
namespace Vocaluxe.Base.ThemeSystem
|
||||
{
|
||||
@@ -40,14 +40,15 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
|
||||
protected struct SRequiredElements
|
||||
{
|
||||
[XmlIgnore] public List<string> Textures, Videos, Colors;
|
||||
[XmlIgnore]
|
||||
public List<string> Textures, Videos, Colors;
|
||||
[XmlElement("Textures")]
|
||||
public string TexturesStr
|
||||
{
|
||||
get { return string.Join("\r\n", Textures); }
|
||||
set
|
||||
{
|
||||
string[] entries = value.Split(new string[] {"\r\n", "\n"}, StringSplitOptions.RemoveEmptyEntries);
|
||||
var entries = value.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
Textures = entries.Select(s => s.Trim()).Where(s => !string.IsNullOrEmpty(s)).ToList();
|
||||
}
|
||||
}
|
||||
@@ -57,7 +58,7 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
get { return string.Join("\r\n", Videos); }
|
||||
set
|
||||
{
|
||||
string[] entries = value.Split(new string[] {"\r\n", "\n"}, StringSplitOptions.RemoveEmptyEntries);
|
||||
var entries = value.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
Videos = entries.Select(s => s.Trim()).Where(s => !string.IsNullOrEmpty(s)).ToList();
|
||||
}
|
||||
}
|
||||
@@ -67,7 +68,7 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
get { return string.Join("\r\n", Colors); }
|
||||
set
|
||||
{
|
||||
string[] entries = value.Split(new string[] {"\r\n", "\n"}, StringSplitOptions.RemoveEmptyEntries);
|
||||
var entries = value.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.RemoveEmptyEntries);
|
||||
Colors = entries.Select(s => s.Trim()).Where(s => !string.IsNullOrEmpty(s)).ToList();
|
||||
}
|
||||
}
|
||||
@@ -92,7 +93,7 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
|
||||
public static bool InitRequiredElements()
|
||||
{
|
||||
string path = Path.Combine(CSettings.ProgramFolder, CSettings.FileNameRequiredSkinElements);
|
||||
var path = Path.Combine(CSettings.ProgramFolder, CSettings.FileNameRequiredSkinElements);
|
||||
var xml = new CXmlDeserializer();
|
||||
try
|
||||
{
|
||||
@@ -103,19 +104,26 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
CLog.Error("Error reading required elements: " + e);
|
||||
return false;
|
||||
}
|
||||
for (int i = 1; i <= CSettings.MaxNumPlayer; i++)
|
||||
|
||||
for (var i = 1; i <= CSettings.MaxNumPlayer; i++)
|
||||
{
|
||||
string name = "Player" + i;
|
||||
var name = "Player" + i;
|
||||
if (!_Required.Colors.Contains(name))
|
||||
{
|
||||
_Required.Colors.Add(name);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void Close()
|
||||
{
|
||||
if (_Required.Textures == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Required.Textures.Clear();
|
||||
_Required.Videos.Clear();
|
||||
_Required.Colors.Clear();
|
||||
@@ -141,7 +149,7 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
_Data = xml.Deserialize<SSkin>(Path.Combine(_Folder, _FileName));
|
||||
if (_Data.SkinSystemVersion != _SkinSystemVersion)
|
||||
{
|
||||
string errorMsg = _Data.SkinSystemVersion < _SkinSystemVersion ? "the file ist outdated!" : "the file is for newer program versions!";
|
||||
var errorMsg = _Data.SkinSystemVersion < _SkinSystemVersion ? "the file ist outdated!" : "the file is for newer program versions!";
|
||||
errorMsg += " Current Version is " + _SkinSystemVersion;
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
@@ -158,30 +166,35 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
public virtual bool Load()
|
||||
{
|
||||
if (_IsLoaded)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Debug.Assert(_Textures.Count == 0 && _Videos.Count == 0);
|
||||
|
||||
// load skins/textures
|
||||
foreach (KeyValuePair<string, string> kvp in _Data.Skins)
|
||||
foreach (var kvp in _Data.Skins)
|
||||
{
|
||||
CTextureRef texture = CDraw.AddTexture(Path.Combine(_Folder, kvp.Value));
|
||||
var texture = CDraw.AddTexture(Path.Combine(_Folder, kvp.Value));
|
||||
if (texture == null)
|
||||
{
|
||||
CLog.Error("Error on loading texture \"" + kvp.Key + "\": " + kvp.Value, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
_Textures.Add(kvp.Key, texture);
|
||||
}
|
||||
|
||||
// load videos
|
||||
foreach (KeyValuePair<string, string> kvp in _Data.Videos)
|
||||
foreach (var kvp in _Data.Videos)
|
||||
{
|
||||
CVideoSkinElement sk = new CVideoSkinElement {FileName = kvp.Value};
|
||||
var sk = new CVideoSkinElement { FileName = kvp.Value };
|
||||
if (!File.Exists(Path.Combine(_Folder, sk.FileName)))
|
||||
{
|
||||
CLog.Error("Video \"" + kvp.Key + "\": (" + sk.FileName + ") not found!");
|
||||
continue;
|
||||
}
|
||||
|
||||
_Videos.Add(kvp.Key, sk);
|
||||
}
|
||||
|
||||
@@ -191,11 +204,15 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
foreach (CTextureRef tex in _Textures.Values)
|
||||
foreach (var tex in _Textures.Values)
|
||||
{
|
||||
tex.Dispose();
|
||||
}
|
||||
|
||||
foreach (CVideoSkinElement vsk in _Videos.Values)
|
||||
foreach (var vsk in _Videos.Values)
|
||||
{
|
||||
CVideo.Close(ref vsk.VideoStream);
|
||||
}
|
||||
|
||||
_Textures.Clear();
|
||||
_Videos.Clear();
|
||||
@@ -218,8 +235,10 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
sk.VideoStream = CVideo.Load(Path.Combine(_Folder, sk.FileName));
|
||||
CVideo.SetLoop(sk.VideoStream, loop);
|
||||
}
|
||||
|
||||
return sk.VideoStream;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
get { return _Skins.Keys.ToArray(); }
|
||||
}
|
||||
|
||||
public readonly int PartyModeID;
|
||||
public readonly int PartyModeId;
|
||||
|
||||
protected readonly string _Folder;
|
||||
private readonly string _FileName;
|
||||
@@ -53,11 +53,11 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
|
||||
private bool _IsLoaded;
|
||||
|
||||
protected CTheme(string filePath, int partyModeID)
|
||||
protected CTheme(string filePath, int partyModeId)
|
||||
{
|
||||
_Folder = Path.GetDirectoryName(filePath);
|
||||
_FileName = Path.GetFileName(filePath);
|
||||
PartyModeID = partyModeID;
|
||||
PartyModeId = partyModeId;
|
||||
CurrentSkin = null;
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
_Data = xml.Deserialize<STheme>(Path.Combine(_Folder, _FileName));
|
||||
if (_Data.ThemeSystemVersion != _ThemeSystemVersion)
|
||||
{
|
||||
string errorMsg = _Data.ThemeSystemVersion < _ThemeSystemVersion ? "the file ist outdated!" : "the file is for newer program versions!";
|
||||
var errorMsg = _Data.ThemeSystemVersion < _ThemeSystemVersion ? "the file ist outdated!" : "the file is for newer program versions!";
|
||||
errorMsg += " Current Version is " + _ThemeSystemVersion;
|
||||
throw new Exception(errorMsg);
|
||||
}
|
||||
@@ -85,20 +85,21 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
return false;
|
||||
}
|
||||
|
||||
string path = Path.Combine(_Folder, Name);
|
||||
IEnumerable<string> files = CHelper.ListFiles(path, "*.xml");
|
||||
var path = Path.Combine(_Folder, Name);
|
||||
var files = CHelper.ListFiles(path, "*.xml");
|
||||
|
||||
// Load skins, succeed if at least 1 skin was loaded
|
||||
bool ok = false;
|
||||
foreach (string file in files)
|
||||
var ok = false;
|
||||
foreach (var file in files)
|
||||
{
|
||||
CSkin skin = _GetNewSkin(path, file);
|
||||
var skin = _GetNewSkin(path, file);
|
||||
if (skin.Init())
|
||||
{
|
||||
_Skins.Add(skin.Name, skin);
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
@@ -109,11 +110,16 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
public bool Load()
|
||||
{
|
||||
if (_IsLoaded)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!_LoadSkin())
|
||||
{
|
||||
return false;
|
||||
bool ok = _Load();
|
||||
}
|
||||
|
||||
var ok = _Load();
|
||||
|
||||
_IsLoaded = ok;
|
||||
return ok;
|
||||
@@ -126,6 +132,7 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
CurrentSkin.Unload();
|
||||
CurrentSkin = null;
|
||||
}
|
||||
|
||||
_IsLoaded = false;
|
||||
}
|
||||
|
||||
@@ -141,8 +148,9 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
CurrentSkin.Unload();
|
||||
CurrentSkin = null;
|
||||
}
|
||||
bool ok = _LoadSkin();
|
||||
|
||||
var ok = _LoadSkin();
|
||||
Debug.Assert(ok);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,13 +15,12 @@
|
||||
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Draw;
|
||||
using System.Diagnostics;
|
||||
using VocaluxeLib.Log;
|
||||
|
||||
namespace Vocaluxe.Base.ThemeSystem
|
||||
@@ -31,7 +30,7 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
private static readonly List<CTheme> _Themes = new List<CTheme>();
|
||||
public static string[] ThemeNames
|
||||
{
|
||||
get { return _Themes.Where(th=>th is CBaseTheme).Select(th => th.Name).Distinct().ToArray(); }
|
||||
get { return _Themes.Where(th => th is CBaseTheme).Select(th => th.Name).Distinct().ToArray(); }
|
||||
}
|
||||
|
||||
public static string[] SkinNames
|
||||
@@ -58,8 +57,11 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
|
||||
public static void Unload()
|
||||
{
|
||||
foreach (CTheme theme in _Themes)
|
||||
foreach (var theme in _Themes)
|
||||
{
|
||||
theme.Unload();
|
||||
}
|
||||
|
||||
CurrentThemes.Clear();
|
||||
}
|
||||
|
||||
@@ -70,54 +72,68 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
/// </summary>
|
||||
public static void Load()
|
||||
{
|
||||
CTheme theme = _Themes.FirstOrDefault(th => th is CBaseTheme && th.Name == CConfig.Config.Theme.Theme) ?? _Themes.FirstOrDefault(th => th is CBaseTheme);
|
||||
var theme = _Themes.FirstOrDefault(th => th is CBaseTheme && th.Name == CConfig.Config.Theme.Theme) ?? _Themes.FirstOrDefault(th => th is CBaseTheme);
|
||||
while (theme != null)
|
||||
{
|
||||
if (theme.Load())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
theme.Unload();
|
||||
CLog.Error("Failed to load theme {ThemeName}! Removing...", CLog.Params(theme.Name, theme), true);
|
||||
_Themes.Remove(theme);
|
||||
theme = _Themes.FirstOrDefault(th => th is CBaseTheme);
|
||||
}
|
||||
|
||||
CurrentThemes.Add(-1, theme);
|
||||
if (theme == null)
|
||||
{
|
||||
CLog.Fatal("No themes found! Cannot continue!");
|
||||
}
|
||||
else
|
||||
{
|
||||
CConfig.Config.Theme.Theme = theme.Name;
|
||||
CConfig.Config.Theme.Skin = theme.CurrentSkin.Name;
|
||||
int[] ids = _Themes.Select(th => th.PartyModeID).Distinct().ToArray();
|
||||
foreach (int id in ids.Where(id => id >= 0))
|
||||
var ids = _Themes.Select(th => th.PartyModeId).Distinct().ToArray();
|
||||
foreach (var id in ids.Where(id => id >= 0))
|
||||
{
|
||||
LoadPartymodeTheme(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool LoadPartymodeTheme(int partyModeID)
|
||||
public static bool LoadPartymodeTheme(int partyModeId)
|
||||
{
|
||||
Debug.Assert(partyModeID >= 0);
|
||||
CTheme theme = _Themes.FirstOrDefault(th => th.PartyModeID == partyModeID && th.Name == CConfig.Config.Theme.Theme);
|
||||
Debug.Assert(partyModeId >= 0);
|
||||
var theme = _Themes.FirstOrDefault(th => th.PartyModeId == partyModeId && th.Name == CConfig.Config.Theme.Theme);
|
||||
if (theme != null)
|
||||
{
|
||||
if (theme.Load())
|
||||
{
|
||||
CurrentThemes.Add(partyModeID, theme);
|
||||
CurrentThemes.Add(partyModeId, theme);
|
||||
return true;
|
||||
}
|
||||
|
||||
theme.Unload();
|
||||
CLog.Error("Failed to load theme " + theme + " for partymode! Removing...", true);
|
||||
_Themes.Remove(theme);
|
||||
}
|
||||
theme = _Themes.First(th => th.PartyModeID == partyModeID && th.Name == CSettings.DefaultName);
|
||||
|
||||
theme = _Themes.First(th => th.PartyModeId == partyModeId && th.Name == CSettings.DefaultName);
|
||||
if (theme.Load())
|
||||
{
|
||||
CurrentThemes.Add(partyModeID, theme);
|
||||
CurrentThemes.Add(partyModeId, theme);
|
||||
return true;
|
||||
}
|
||||
|
||||
CLog.Error("Failed to load default theme for partymode! Unloading partymode!", true);
|
||||
foreach (CPartyTheme th in _Themes.Where(th => th.PartyModeID == partyModeID))
|
||||
foreach (CPartyTheme th in _Themes.Where(th => th.PartyModeId == partyModeId))
|
||||
{
|
||||
th.Unload();
|
||||
_Themes.RemoveAll(th => th.PartyModeID == partyModeID);
|
||||
}
|
||||
|
||||
_Themes.RemoveAll(th => th.PartyModeId == partyModeId);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -129,31 +145,42 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
|
||||
public static void ReloadSkin()
|
||||
{
|
||||
foreach (CTheme theme in CurrentThemes.Values)
|
||||
foreach (var theme in CurrentThemes.Values)
|
||||
{
|
||||
theme.ReloadSkin();
|
||||
}
|
||||
}
|
||||
|
||||
public static bool ReadThemesFromFolder(string path, int partyModeID)
|
||||
public static bool ReadThemesFromFolder(string path, int partyModeId)
|
||||
{
|
||||
IEnumerable<string> files = CHelper.ListFiles(path, "*.xml", false, true);
|
||||
var files = CHelper.ListFiles(path, "*.xml", false, true);
|
||||
|
||||
List<CTheme> newThemes = new List<CTheme>();
|
||||
foreach (string file in files)
|
||||
var newThemes = new List<CTheme>();
|
||||
foreach (var file in files)
|
||||
{
|
||||
CTheme theme;
|
||||
if (partyModeID < 0)
|
||||
if (partyModeId < 0)
|
||||
{
|
||||
theme = new CBaseTheme(file);
|
||||
}
|
||||
else
|
||||
theme = new CPartyTheme(file, partyModeID);
|
||||
{
|
||||
theme = new CPartyTheme(file, partyModeId);
|
||||
}
|
||||
|
||||
if (theme.Init())
|
||||
{
|
||||
newThemes.Add(theme);
|
||||
}
|
||||
}
|
||||
|
||||
if (newThemes.Count == 0)
|
||||
{
|
||||
CLog.Error("No valid themes found in " + path);
|
||||
return false;
|
||||
}
|
||||
if (partyModeID >= 0 && newThemes.Count(th => th.Name == CSettings.DefaultName) == 0)
|
||||
|
||||
if (partyModeId >= 0 && newThemes.Count(th => th.Name == CSettings.DefaultName) == 0)
|
||||
{
|
||||
CLog.Error("Partymode misses default theme in " + path);
|
||||
return false;
|
||||
@@ -163,33 +190,42 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
return true;
|
||||
}
|
||||
|
||||
public static string GetThemeScreensPath(int partyModeID)
|
||||
public static string GetThemeScreensPath(int partyModeId)
|
||||
{
|
||||
CTheme theme;
|
||||
return CurrentThemes.TryGetValue(partyModeID, out theme) ? theme.GetScreenPath() : null;
|
||||
return CurrentThemes.TryGetValue(partyModeId, out theme) ? theme.GetScreenPath() : null;
|
||||
}
|
||||
|
||||
private static void _LogMissingElement(int partyModeID, string elType, string elName)
|
||||
private static void _LogMissingElement(int partyModeId, string elType, string elName)
|
||||
{
|
||||
CLog.Error("Skin " + CurrentThemes[partyModeID].CurrentSkin + " is missing the " + elType + " \"" + elName + "\"! Expect visual problems!");
|
||||
CLog.Error("Skin " + CurrentThemes[partyModeId].CurrentSkin + " is missing the " + elType + " \"" + elName + "\"! Expect visual problems!");
|
||||
}
|
||||
|
||||
public static CTextureRef GetSkinTexture(string textureName, int partyModeID)
|
||||
public static CTextureRef GetSkinTexture(string textureName, int partyModeId)
|
||||
{
|
||||
if (String.IsNullOrEmpty(textureName))
|
||||
if (string.IsNullOrEmpty(textureName))
|
||||
{
|
||||
return null;
|
||||
CTextureRef texture = CurrentThemes[partyModeID].CurrentSkin.GetTexture(textureName);
|
||||
}
|
||||
|
||||
var texture = CurrentThemes[partyModeId].CurrentSkin.GetTexture(textureName);
|
||||
if (texture == null)
|
||||
_LogMissingElement(partyModeID, "texture", textureName);
|
||||
{
|
||||
_LogMissingElement(partyModeId, "texture", textureName);
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static CVideoStream GetSkinVideo(string videoName, int partyModeID, bool loop = true)
|
||||
public static CVideoStream GetSkinVideo(string videoName, int partyModeId, bool loop = true)
|
||||
{
|
||||
Debug.Assert(!String.IsNullOrEmpty(videoName));
|
||||
CVideoStream video = CurrentThemes[partyModeID].CurrentSkin.GetVideo(videoName, loop);
|
||||
Debug.Assert(!string.IsNullOrEmpty(videoName));
|
||||
var video = CurrentThemes[partyModeId].CurrentSkin.GetVideo(videoName, loop);
|
||||
if (video == null)
|
||||
_LogMissingElement(partyModeID, "video", videoName);
|
||||
{
|
||||
_LogMissingElement(partyModeId, "video", videoName);
|
||||
}
|
||||
|
||||
return video;
|
||||
}
|
||||
|
||||
@@ -198,14 +234,15 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
return ((CBaseTheme)CurrentThemes[-1]).CursorTheme;
|
||||
}
|
||||
|
||||
public static bool GetColor(string colorName, int partyModeID, out SColorF color)
|
||||
public static bool GetColor(string colorName, int partyModeId, out SColorF color)
|
||||
{
|
||||
Debug.Assert(!String.IsNullOrEmpty(colorName));
|
||||
if (!CurrentThemes[partyModeID].CurrentSkin.GetColor(colorName, out color))
|
||||
Debug.Assert(!string.IsNullOrEmpty(colorName));
|
||||
if (!CurrentThemes[partyModeId].CurrentSkin.GetColor(colorName, out color))
|
||||
{
|
||||
_LogMissingElement(partyModeID, "color", colorName);
|
||||
_LogMissingElement(partyModeId, "color", colorName);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -213,7 +250,10 @@ namespace Vocaluxe.Base.ThemeSystem
|
||||
{
|
||||
SColorF color;
|
||||
if (!GetColor("Player" + playerNr, -1, out color))
|
||||
{
|
||||
CLog.Error("Invalid color requested: Color for player " + playerNr + ". Expect visual problems!", true);
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
+34
-18
@@ -17,7 +17,6 @@
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Diagnostics;
|
||||
using System.Xml.Serialization;
|
||||
using Vocaluxe.Base.Fonts;
|
||||
using VocaluxeLib;
|
||||
@@ -36,7 +35,8 @@ namespace Vocaluxe.Base
|
||||
|
||||
struct SThemeCursor
|
||||
{
|
||||
[XmlElement("Skin")] public string SkinName;
|
||||
[XmlElement("Skin")]
|
||||
public string SkinName;
|
||||
|
||||
public float W;
|
||||
public float H;
|
||||
@@ -48,13 +48,15 @@ namespace Vocaluxe.Base
|
||||
{
|
||||
public int ThemeSystemVersion;
|
||||
public SInfo Info;
|
||||
[XmlArray, DefaultValue(null)] public SFontFamily[] Fonts;
|
||||
[XmlArray, DefaultValue(null)]
|
||||
public SFontFamily[] Fonts;
|
||||
public SThemeCursor? Cursor;
|
||||
}
|
||||
|
||||
struct SDefaultFonts
|
||||
{
|
||||
[XmlArray] public SFontFamily[] Fonts;
|
||||
[XmlArray]
|
||||
public SFontFamily[] Fonts;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -64,10 +66,13 @@ namespace Vocaluxe.Base
|
||||
struct SFontFamily
|
||||
{
|
||||
public string Name;
|
||||
[XmlIgnore] public int PartyModeID;
|
||||
[XmlIgnore] public string ThemeName;
|
||||
[XmlIgnore]
|
||||
public int PartyModeId;
|
||||
[XmlIgnore]
|
||||
public string ThemeName;
|
||||
|
||||
[XmlNormalized] public float Outline; //0..1, 0=not outline 1=100% outline
|
||||
[XmlNormalized]
|
||||
public float Outline; //0..1, 0=not outline 1=100% outline
|
||||
public SColorF OutlineColor;
|
||||
|
||||
public string Folder;
|
||||
@@ -77,10 +82,14 @@ namespace Vocaluxe.Base
|
||||
public string FileItalic;
|
||||
public string FileBoldItalic;
|
||||
|
||||
[XmlIgnore] public CFontStyle Normal;
|
||||
[XmlIgnore] public CFontStyle Italic;
|
||||
[XmlIgnore] public CFontStyle Bold;
|
||||
[XmlIgnore] public CFontStyle BoldItalic;
|
||||
[XmlIgnore]
|
||||
public CFontStyle Normal;
|
||||
[XmlIgnore]
|
||||
public CFontStyle Italic;
|
||||
[XmlIgnore]
|
||||
public CFontStyle Bold;
|
||||
[XmlIgnore]
|
||||
public CFontStyle BoldItalic;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
@@ -102,13 +111,15 @@ namespace Vocaluxe.Base
|
||||
|
||||
struct SPlaylistInfo
|
||||
{
|
||||
[XmlElement("PlaylistName")] public string Name;
|
||||
[XmlElement("PlaylistName")]
|
||||
public string Name;
|
||||
}
|
||||
|
||||
struct SPlaylist
|
||||
{
|
||||
public SPlaylistInfo Info;
|
||||
[XmlArray] public SPlaylistSong[] Songs;
|
||||
[XmlArray]
|
||||
public SPlaylistSong[] Songs;
|
||||
}
|
||||
|
||||
#region Partymode
|
||||
@@ -119,17 +130,22 @@ namespace Vocaluxe.Base
|
||||
public string Author;
|
||||
public string Folder;
|
||||
public string PartyModeFile;
|
||||
[XmlAltName("PartyModeVersionMajor")] public int VersionMajor;
|
||||
[XmlAltName("PartyModeVersionMinor")] public int VersionMinor;
|
||||
[XmlAltName("PartyModeVersionMajor")]
|
||||
public int VersionMajor;
|
||||
[XmlAltName("PartyModeVersionMinor")]
|
||||
public int VersionMinor;
|
||||
public string TargetAudience;
|
||||
[XmlIgnore] public IPartyModeInfo ExtInfo;
|
||||
[XmlIgnore]
|
||||
public IPartyModeInfo ExtInfo;
|
||||
}
|
||||
|
||||
struct SPartyMode
|
||||
{
|
||||
public int PartyModeSystemVersion;
|
||||
[XmlArray("PartyScreens"), XmlArrayItem("ScreenFile")] public List<string> ScreenFiles;
|
||||
[XmlIgnore] public IPartyMode PartyMode;
|
||||
[XmlArray("PartyScreens"), XmlArrayItem("ScreenFile")]
|
||||
public List<string> ScreenFiles;
|
||||
[XmlIgnore]
|
||||
public IPartyMode PartyMode;
|
||||
public SPartyModeInfos Info;
|
||||
}
|
||||
#endregion Partymode
|
||||
|
||||
@@ -36,9 +36,12 @@ namespace Vocaluxe
|
||||
|
||||
public static void AddEnvironmentPath(string path)
|
||||
{
|
||||
string newPath = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
|
||||
var newPath = Environment.GetEnvironmentVariable("PATH") ?? string.Empty;
|
||||
if (newPath.Length > 0)
|
||||
{
|
||||
newPath += ";";
|
||||
}
|
||||
|
||||
newPath += path;
|
||||
|
||||
Environment.SetEnvironmentVariable("PATH", newPath);
|
||||
|
||||
+59
-40
@@ -15,7 +15,6 @@
|
||||
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Security;
|
||||
@@ -32,32 +31,44 @@ namespace Vocaluxe
|
||||
{
|
||||
private static bool _CheckUninstallKey(string name, string key)
|
||||
{
|
||||
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(key))
|
||||
using (var rk = Registry.LocalMachine.OpenSubKey(key))
|
||||
{
|
||||
if (rk == null)
|
||||
throw new SecurityException();
|
||||
foreach (string skName in rk.GetSubKeyNames())
|
||||
{
|
||||
using (RegistryKey sk = rk.OpenSubKey(skName))
|
||||
throw new SecurityException();
|
||||
}
|
||||
|
||||
foreach (var skName in rk.GetSubKeyNames())
|
||||
{
|
||||
using (var sk = rk.OpenSubKey(skName))
|
||||
{
|
||||
if (sk == null || sk.GetValue("DisplayName") == null)
|
||||
{
|
||||
continue;
|
||||
string displayName = sk.GetValue("DisplayName").ToString().ToLower();
|
||||
}
|
||||
|
||||
var displayName = sk.GetValue("DisplayName").ToString().ToLower();
|
||||
if (displayName.Equals(name) || displayName.StartsWith(name) || name.StartsWith(displayName))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static bool _KeyExists(string key)
|
||||
{
|
||||
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(key))
|
||||
using (var rk = Registry.LocalMachine.OpenSubKey(key))
|
||||
{
|
||||
if (rk != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -86,47 +97,55 @@ namespace Vocaluxe
|
||||
const string baseKey = @"SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\";
|
||||
const string wow6432BaseKey = @"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\";
|
||||
|
||||
#if ARCH_X64
|
||||
#if ARCH_X64
|
||||
string[] arches = { "x64" };
|
||||
#elif ARCH_X86
|
||||
#elif ARCH_X86
|
||||
string[] arches = { "x86" };
|
||||
#else
|
||||
#else
|
||||
string[] arches = { "x86", "x64" };
|
||||
#endif
|
||||
#endif
|
||||
|
||||
foreach (string arch in arches)
|
||||
{
|
||||
using (RegistryKey rk = Registry.LocalMachine.OpenSubKey(baseKey + arch) ??
|
||||
Registry.LocalMachine.OpenSubKey(wow6432BaseKey + arch))
|
||||
foreach (var arch in arches)
|
||||
{
|
||||
if (rk == null)
|
||||
continue;
|
||||
using (var rk = Registry.LocalMachine.OpenSubKey(baseKey + arch) ??
|
||||
Registry.LocalMachine.OpenSubKey(wow6432BaseKey + arch))
|
||||
{
|
||||
if (rk == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
object installed = rk.GetValue("Installed");
|
||||
if (installed == null)
|
||||
continue;
|
||||
var installed = rk.GetValue("Installed");
|
||||
if (installed == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int installedValue;
|
||||
if (int.TryParse(installed.ToString(), out installedValue) && installedValue == 1)
|
||||
return true;
|
||||
int installedValue;
|
||||
if (int.TryParse(installed.ToString(), out installedValue) && installedValue == 1)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static void _EnsureDataFolderExists()
|
||||
{
|
||||
if (!Directory.Exists(CSettings.DataFolder)) {
|
||||
if (!Directory.Exists(CSettings.DataFolder))
|
||||
{
|
||||
Directory.CreateDirectory(CSettings.DataFolder);
|
||||
// copy default profiles to DataFolder instead of adding ProgramFolder to CConfig.ProfileFolders
|
||||
// because we want to be able to edit them, but might not have permission to write to ProgramFolder
|
||||
string profilePath = Path.Combine(CSettings.DataFolder, CSettings.FolderNameProfiles);
|
||||
var profilePath = Path.Combine(CSettings.DataFolder, CSettings.FolderNameProfiles);
|
||||
Directory.CreateDirectory(profilePath);
|
||||
DirectoryInfo defaultProfileDir = new DirectoryInfo(Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameProfiles));
|
||||
FileInfo[] files = defaultProfileDir.GetFiles();
|
||||
foreach (FileInfo file in files) {
|
||||
string newPath = Path.Combine(profilePath, file.Name);
|
||||
var defaultProfileDir = new DirectoryInfo(Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameProfiles));
|
||||
var files = defaultProfileDir.GetFiles();
|
||||
foreach (var file in files)
|
||||
{
|
||||
var newPath = Path.Combine(profilePath, file.Name);
|
||||
file.CopyTo(newPath, false);
|
||||
}
|
||||
}
|
||||
@@ -143,13 +162,13 @@ namespace Vocaluxe
|
||||
}
|
||||
|
||||
if (!_IsVC2015To2022Installed())
|
||||
{
|
||||
CLog.Fatal(
|
||||
"VC++ 2015-2022 Redistributables are missing. Please install them first.\r\n" +
|
||||
"Download x64: https://aka.ms/vc14/vc_redist.x64.exe\r\n" +
|
||||
"Download x86: https://aka.ms/vc14/vc_redist.x86.exe");
|
||||
return false;
|
||||
}
|
||||
{
|
||||
CLog.Fatal(
|
||||
"VC++ 2015-2022 Redistributables are missing. Please install them first.\r\n" +
|
||||
"Download x64: https://aka.ms/vc14/vc_redist.x64.exe\r\n" +
|
||||
"Download x86: https://aka.ms/vc14/vc_redist.x86.exe");
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif //TODO: check for dependencies on linux?
|
||||
return true;
|
||||
@@ -161,7 +180,7 @@ namespace Vocaluxe
|
||||
string path = "x86";
|
||||
#endif
|
||||
#if ARCH_X64
|
||||
string path = "x64";
|
||||
var path = "x64";
|
||||
#endif
|
||||
path = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + Path.DirectorySeparatorChar + path;
|
||||
COSFunctions.AddEnvironmentPath(path);
|
||||
@@ -170,4 +189,4 @@ namespace Vocaluxe
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -30,7 +30,7 @@ namespace Vocaluxe
|
||||
|
||||
public CSplashScreen()
|
||||
{
|
||||
string path = Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameGraphics, CSettings.FileNameLogo);
|
||||
var path = Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameGraphics, CSettings.FileNameLogo);
|
||||
if (File.Exists(path))
|
||||
{
|
||||
try
|
||||
@@ -44,7 +44,9 @@ namespace Vocaluxe
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CLog.Error("Can't find " + path);
|
||||
}
|
||||
|
||||
path = Path.Combine(CSettings.ProgramFolder, CSettings.FileNameIcon);
|
||||
if (File.Exists(path))
|
||||
@@ -59,7 +61,9 @@ namespace Vocaluxe
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CLog.Error("Can't find " + path);
|
||||
}
|
||||
|
||||
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
|
||||
BackColor = Color.Transparent;
|
||||
@@ -82,14 +86,16 @@ namespace Vocaluxe
|
||||
set { base.BackColor = value; }
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e) {}
|
||||
protected override void OnPaint(PaintEventArgs e) { }
|
||||
|
||||
protected override void OnPaintBackground(PaintEventArgs e)
|
||||
{
|
||||
if (_Logo == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Graphics g = e.Graphics;
|
||||
var g = e.Graphics;
|
||||
g.DrawImage(_Logo, new Rectangle(0, 0, Width, Height));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,16 +23,17 @@ namespace Vocaluxe.GameModes
|
||||
abstract class CGameMode : IGameMode
|
||||
{
|
||||
private CSong _LastSong;
|
||||
private int _LastSongID = -1;
|
||||
private int _LastSongId = -1;
|
||||
|
||||
public CSong GetSong(int songID)
|
||||
public CSong GetSong(int songId)
|
||||
{
|
||||
if (songID != _LastSongID)
|
||||
if (songId != _LastSongId)
|
||||
{
|
||||
CSong song = CSongs.GetSong(songID);
|
||||
var song = CSongs.GetSong(songId);
|
||||
_LastSong = _PrepareSong(song);
|
||||
_LastSongID = songID;
|
||||
_LastSongId = songId;
|
||||
}
|
||||
|
||||
return _LastSong;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,21 +29,27 @@ namespace Vocaluxe.GameModes
|
||||
public static void Init()
|
||||
{
|
||||
_GameModes = new Dictionary<EGameMode, IGameMode>
|
||||
{
|
||||
{EGameMode.TR_GAMEMODE_NORMAL, new CGameModeNormal()},
|
||||
{EGameMode.TR_GAMEMODE_DUET, new CGameModeDuet()},
|
||||
{EGameMode.TR_GAMEMODE_SHORTSONG, new CGameModeShort()},
|
||||
{EGameMode.TR_GAMEMODE_MEDLEY, new CGameModeMedley()}
|
||||
};
|
||||
{
|
||||
{ EGameMode.TR_GAMEMODE_NORMAL, new CGameModeNormal() },
|
||||
{ EGameMode.TR_GAMEMODE_DUET, new CGameModeDuet() },
|
||||
{ EGameMode.TR_GAMEMODE_SHORTSONG, new CGameModeShort() },
|
||||
{ EGameMode.TR_GAMEMODE_MEDLEY, new CGameModeMedley() }
|
||||
};
|
||||
}
|
||||
|
||||
public static IGameMode Get(EGameMode gameMode)
|
||||
{
|
||||
if (_GameModes == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
IGameMode result;
|
||||
if (!_GameModes.TryGetValue(gameMode, out result))
|
||||
{
|
||||
result = _GameModes[EGameMode.TR_GAMEMODE_NORMAL];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -52,7 +58,7 @@ namespace Vocaluxe.GameModes
|
||||
{
|
||||
protected override CSong _PrepareSong(CSong song)
|
||||
{
|
||||
return (song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_NORMAL)) ? song : null;
|
||||
return song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_NORMAL) ? song : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +66,7 @@ namespace Vocaluxe.GameModes
|
||||
{
|
||||
protected override CSong _PrepareSong(CSong song)
|
||||
{
|
||||
return (song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_DUET)) ? song : null;
|
||||
return song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_DUET) ? song : null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,8 +75,11 @@ namespace Vocaluxe.GameModes
|
||||
protected override CSong _PrepareSong(CSong song)
|
||||
{
|
||||
if (!song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_SHORTSONG))
|
||||
{
|
||||
return null;
|
||||
var newSong = new CSong(song) {Finish = CGame.GetTimeFromBeats(song.ShortEnd.EndBeat, song.BPM) + CSettings.DefaultMedleyFadeOutTime + song.Gap};
|
||||
}
|
||||
|
||||
var newSong = new CSong(song) { End = CGame.GetTimeFromBeats(song.ShortEnd.EndBeat, song.Bpm) + CSettings.DefaultMedleyFadeOutTime + song.Gap };
|
||||
// set lines to short mode
|
||||
newSong.Notes.SetMedley(0, song.ShortEnd.EndBeat);
|
||||
|
||||
@@ -83,12 +92,17 @@ namespace Vocaluxe.GameModes
|
||||
protected override CSong _PrepareSong(CSong song)
|
||||
{
|
||||
if (!song.IsGameModeAvailable(EGameMode.TR_GAMEMODE_MEDLEY))
|
||||
{
|
||||
return null;
|
||||
var newSong = new CSong(song) {Start = CGame.GetTimeFromBeats(song.Medley.StartBeat, song.BPM) - song.Medley.FadeInTime + song.Gap};
|
||||
if (newSong.Start < 0f)
|
||||
newSong.Start = 0f;
|
||||
}
|
||||
|
||||
newSong.Finish = CGame.GetTimeFromBeats(song.Medley.EndBeat, song.BPM) + song.Medley.FadeOutTime + song.Gap;
|
||||
var newSong = new CSong(song) { Start = CGame.GetTimeFromBeats(song.Medley.StartBeat, song.Bpm) - song.Medley.FadeInTime + song.Gap };
|
||||
if (newSong.Start < 0f)
|
||||
{
|
||||
newSong.Start = 0f;
|
||||
}
|
||||
|
||||
newSong.End = CGame.GetTimeFromBeats(song.Medley.EndBeat, song.Bpm) + song.Medley.FadeOutTime + song.Gap;
|
||||
|
||||
// set lines to medley mode
|
||||
newSong.Notes.SetMedley(song.Medley.StartBeat, song.Medley.EndBeat);
|
||||
|
||||
@@ -21,6 +21,6 @@ namespace Vocaluxe.GameModes
|
||||
{
|
||||
interface IGameMode
|
||||
{
|
||||
CSong GetSong(int songID);
|
||||
CSong GetSong(int songId);
|
||||
}
|
||||
}
|
||||
@@ -16,15 +16,14 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Vocaluxe.Base;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Draw;
|
||||
using VocaluxeLib.Log;
|
||||
using Microsoft.Data.Sqlite;
|
||||
|
||||
namespace Vocaluxe.Lib.Database
|
||||
{
|
||||
@@ -32,20 +31,28 @@ namespace Vocaluxe.Lib.Database
|
||||
{
|
||||
private SqliteTransaction _TransactionCover;
|
||||
|
||||
public CCoverDB(string filePath) : base(filePath) {}
|
||||
public CCoverDB(string filePath) : base(filePath) { }
|
||||
|
||||
public override bool Init()
|
||||
{
|
||||
lock (_Mutex)
|
||||
{
|
||||
if (!base.Init())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_Version < 0)
|
||||
{
|
||||
return _CreateCoverDB();
|
||||
}
|
||||
|
||||
if (_Version < CSettings.DatabaseCoverVersion)
|
||||
{
|
||||
throw new NotImplementedException("Upgrading of cover DB not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -63,7 +70,10 @@ namespace Vocaluxe.Lib.Database
|
||||
public bool GetCover(string coverPath, ref CTextureRef tex, int maxSize)
|
||||
{
|
||||
if (_Connection == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!File.Exists(coverPath))
|
||||
{
|
||||
CLog.Error("Can't find File: " + coverPath);
|
||||
@@ -74,28 +84,34 @@ namespace Vocaluxe.Lib.Database
|
||||
{
|
||||
//Double check here because we may have just closed our connection
|
||||
if (_Connection == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
using (var command = new SqliteCommand())
|
||||
{
|
||||
command.Connection = _Connection;
|
||||
// If we have an open transaction on this connection, all commands must use it.
|
||||
if (_TransactionCover != null)
|
||||
{
|
||||
command.Transaction = _TransactionCover;
|
||||
}
|
||||
|
||||
command.CommandText = "SELECT id, width, height FROM Cover WHERE [Path] = @path";
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@path", coverPath);
|
||||
|
||||
SqliteDataReader reader = command.ExecuteReader();
|
||||
var reader = command.ExecuteReader();
|
||||
|
||||
if (reader != null && reader.HasRows)
|
||||
{
|
||||
reader.Read();
|
||||
int id = reader.GetInt32(0);
|
||||
int w = reader.GetInt32(1);
|
||||
int h = reader.GetInt32(2);
|
||||
var id = reader.GetInt32(0);
|
||||
var w = reader.GetInt32(1);
|
||||
var h = reader.GetInt32(2);
|
||||
reader.Close();
|
||||
|
||||
command.CommandText = "SELECT Data FROM CoverData WHERE CoverID = @id";
|
||||
command.CommandText = "SELECT Data FROM CoverData WHERE CoverId = @id";
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@id", id);
|
||||
reader = command.ExecuteReader();
|
||||
@@ -103,33 +119,39 @@ namespace Vocaluxe.Lib.Database
|
||||
if (reader.HasRows)
|
||||
{
|
||||
reader.Read();
|
||||
byte[] data2 = _GetBytes(reader);
|
||||
var data2 = _GetBytes(reader);
|
||||
reader.Dispose();
|
||||
tex = CDraw.EnqueueTexture(w, h, data2);
|
||||
return true;
|
||||
}
|
||||
|
||||
command.CommandText = "DELETE FROM Cover WHERE id = @id";
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@id", id);
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
if (reader != null)
|
||||
{
|
||||
reader.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// At this point we do not have a mathing entry in the CoverDB (either no Data found and deleted or nothing at all)
|
||||
// We break out of the lock to do the bitmap loading and resizing here to allow multithreaded loading
|
||||
|
||||
Bitmap origin = CHelper.LoadBitmap(coverPath);
|
||||
var origin = CHelper.LoadBitmap(coverPath);
|
||||
if (origin == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Size size = origin.GetSize();
|
||||
var size = origin.GetSize();
|
||||
if (size.Width > maxSize || size.Height > maxSize)
|
||||
{
|
||||
size = CHelper.FitInBounds(new SRectF(0, 0, maxSize, maxSize, 0), (float)size.Width / size.Height, EAspect.LetterBox).SizeI;
|
||||
Bitmap tmp = origin.Resize(size);
|
||||
var tmp = origin.Resize(size);
|
||||
origin.Dispose();
|
||||
origin = tmp;
|
||||
}
|
||||
@@ -139,7 +161,7 @@ namespace Vocaluxe.Lib.Database
|
||||
try
|
||||
{
|
||||
data = new byte[size.Width * size.Height * 4];
|
||||
BitmapData bmpData = origin.LockBits(origin.GetRect(), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||||
var bmpData = origin.LockBits(origin.GetRect(), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||||
Marshal.Copy(bmpData.Scan0, data, 0, data.Length);
|
||||
origin.UnlockBits(bmpData);
|
||||
}
|
||||
@@ -154,9 +176,15 @@ namespace Vocaluxe.Lib.Database
|
||||
{
|
||||
//Double check here because we may have just closed our connection
|
||||
if (_Connection == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_TransactionCover == null)
|
||||
{
|
||||
_TransactionCover = _Connection.BeginTransaction();
|
||||
}
|
||||
|
||||
using (var command = new SqliteCommand())
|
||||
{
|
||||
command.Connection = _Connection;
|
||||
@@ -171,14 +199,14 @@ namespace Vocaluxe.Lib.Database
|
||||
command.CommandText = "SELECT id FROM Cover WHERE [Path] = @path";
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@path", coverPath);
|
||||
SqliteDataReader reader = command.ExecuteReader();
|
||||
var reader = command.ExecuteReader();
|
||||
|
||||
if (reader != null)
|
||||
{
|
||||
reader.Read();
|
||||
int id = reader.GetInt32(0);
|
||||
var id = reader.GetInt32(0);
|
||||
reader.Dispose();
|
||||
command.CommandText = "INSERT INTO CoverData (CoverID, Data) VALUES (@id, @data)";
|
||||
command.CommandText = "INSERT INTO CoverData (CoverId, Data) VALUES (@id, @data)";
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@id", id);
|
||||
command.Parameters.AddWithValue("@data", data);
|
||||
@@ -187,6 +215,7 @@ namespace Vocaluxe.Lib.Database
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -204,7 +233,10 @@ namespace Vocaluxe.Lib.Database
|
||||
private void _CommitCovers()
|
||||
{
|
||||
if (_TransactionCover == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_TransactionCover.Commit();
|
||||
_TransactionCover.Dispose();
|
||||
_TransactionCover = null;
|
||||
@@ -230,7 +262,7 @@ namespace Vocaluxe.Lib.Database
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
command.CommandText = "CREATE TABLE IF NOT EXISTS CoverData ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
|
||||
"CoverID INTEGER NOT NULL, Data BLOB NOT NULL);";
|
||||
"CoverId INTEGER NOT NULL, Data BLOB NOT NULL);";
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
@@ -239,6 +271,7 @@ namespace Vocaluxe.Lib.Database
|
||||
CLog.Error("Error creating Cover DB " + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,10 @@ namespace Vocaluxe.Lib.Database
|
||||
lock (_Mutex)
|
||||
{
|
||||
if (_Connection != null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_Connection = new SqliteConnection("Data Source=" + _FilePath);
|
||||
try
|
||||
{
|
||||
@@ -62,17 +65,24 @@ namespace Vocaluxe.Lib.Database
|
||||
{
|
||||
reader = command.ExecuteReader();
|
||||
}
|
||||
catch (Exception) {}
|
||||
catch (Exception) { }
|
||||
|
||||
if (reader == null || !reader.Read() || reader.FieldCount == 0)
|
||||
{
|
||||
_Version = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
_Version = reader.GetInt32(0);
|
||||
}
|
||||
|
||||
if (reader != null)
|
||||
{
|
||||
reader.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -115,6 +125,7 @@ namespace Vocaluxe.Lib.Database
|
||||
stream.Write(buffer, 0, bytesRead);
|
||||
fieldOffset += bytesRead;
|
||||
}
|
||||
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,11 +20,10 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Community.CsharpSqlite;
|
||||
using Microsoft.Data.Sqlite;
|
||||
using Vocaluxe.Base;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Log;
|
||||
using VocaluxeLib.Songs;
|
||||
using Microsoft.Data.Sqlite;
|
||||
|
||||
namespace Vocaluxe.Lib.Database
|
||||
{
|
||||
@@ -38,11 +37,11 @@ namespace Vocaluxe.Lib.Database
|
||||
public string Str2;
|
||||
}
|
||||
|
||||
public CHighscoreDB(string filePath) : base(filePath) {}
|
||||
public CHighscoreDB(string filePath) : base(filePath) { }
|
||||
|
||||
public override bool Init()
|
||||
{
|
||||
string oldDBFilePath = Path.Combine(CSettings.DataFolder, CSettings.FileNameOldHighscoreDB);
|
||||
var oldDBFilePath = Path.Combine(CSettings.DataFolder, CSettings.FileNameOldHighscoreDB);
|
||||
if (File.Exists(oldDBFilePath))
|
||||
{
|
||||
if (File.Exists(_FilePath))
|
||||
@@ -52,11 +51,13 @@ namespace Vocaluxe.Lib.Database
|
||||
CLog.Fatal("Cannot init Highscore DB: Error opening old database: {DBFile}" + CLog.Params(oldDBFilePath));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_CreateOrConvert(_FilePath))
|
||||
{
|
||||
CLog.Fatal("Cannot init Highscore DB: Error opening database: {DBFile}", CLog.Params(_FilePath));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_ImportData(oldDBFilePath))
|
||||
{
|
||||
CLog.Fatal("Cannot init Highscore DB: Error importing data");
|
||||
@@ -72,6 +73,7 @@ namespace Vocaluxe.Lib.Database
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
File.Delete(oldDBFilePath);
|
||||
}
|
||||
else if (!_CreateOrConvert(_FilePath))
|
||||
@@ -79,6 +81,7 @@ namespace Vocaluxe.Lib.Database
|
||||
CLog.Fatal("Cannot init Highscore DB: Error opening database: {DBFile}", CLog.Params(_FilePath));
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -87,11 +90,11 @@ namespace Vocaluxe.Lib.Database
|
||||
//Do nothing
|
||||
}
|
||||
|
||||
public bool GetDataBaseSongInfos(string artist, string title, out int numPlayed, out DateTime dateAdded, out int highscoreID)
|
||||
public bool GetDataBaseSongInfos(string artist, string title, out int numPlayed, out DateTime dateAdded, out int highscoreId)
|
||||
{
|
||||
string sArtist;
|
||||
string sTitle;
|
||||
int songID;
|
||||
int songId;
|
||||
using (var connection = new SqliteConnection())
|
||||
{
|
||||
connection.ConnectionString = "Data Source=" + _FilePath;
|
||||
@@ -100,19 +103,20 @@ namespace Vocaluxe.Lib.Database
|
||||
{
|
||||
connection.Open();
|
||||
}
|
||||
catch (Exception) {}
|
||||
catch (Exception) { }
|
||||
|
||||
using (var command = new SqliteCommand())
|
||||
{
|
||||
command.Connection = connection;
|
||||
songID = _GetDataBaseSongID(artist, title, 0, command);
|
||||
highscoreID = songID;
|
||||
songId = _GetDataBaseSongId(artist, title, 0, command);
|
||||
highscoreId = songId;
|
||||
}
|
||||
}
|
||||
return _GetDataBaseSongInfos(songID, out sArtist, out sTitle, out numPlayed, out dateAdded, _FilePath);
|
||||
|
||||
return _GetDataBaseSongInfos(songId, out sArtist, out sTitle, out numPlayed, out dateAdded, _FilePath);
|
||||
}
|
||||
|
||||
public void IncreaseSongCounter(int dataBaseSongID)
|
||||
public void IncreaseSongCounter(int dataBaseSongId)
|
||||
{
|
||||
using (var connection = new SqliteConnection())
|
||||
{
|
||||
@@ -122,18 +126,18 @@ namespace Vocaluxe.Lib.Database
|
||||
{
|
||||
connection.Open();
|
||||
}
|
||||
catch (Exception) {}
|
||||
catch (Exception) { }
|
||||
|
||||
using (var command = new SqliteCommand())
|
||||
{
|
||||
command.Connection = connection;
|
||||
_IncreaseSongCounter(dataBaseSongID, command);
|
||||
_IncreaseSongCounter(dataBaseSongId, command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int AddScore(string playerName, int score, int lineNr, long date, int medley, int duet, int shortSong, int difficulty,
|
||||
string artist, string title, int numPlayed, string filePath)
|
||||
string artist, string title, int numPlayed, string filePath)
|
||||
{
|
||||
using (var connection = new SqliteConnection())
|
||||
{
|
||||
@@ -151,8 +155,8 @@ namespace Vocaluxe.Lib.Database
|
||||
using (var command = new SqliteCommand())
|
||||
{
|
||||
command.Connection = connection;
|
||||
int dataBaseSongID = _GetDataBaseSongID(artist, title, numPlayed, command);
|
||||
int result = _AddScore(playerName, score, lineNr, date, medley, duet, shortSong, difficulty, dataBaseSongID, command);
|
||||
var dataBaseSongId = _GetDataBaseSongId(artist, title, numPlayed, command);
|
||||
var result = _AddScore(playerName, score, lineNr, date, medley, duet, shortSong, difficulty, dataBaseSongId, command);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -173,9 +177,9 @@ namespace Vocaluxe.Lib.Database
|
||||
return -1;
|
||||
}
|
||||
|
||||
int medley = 0;
|
||||
int duet = 0;
|
||||
int shortSong = 0;
|
||||
var medley = 0;
|
||||
var duet = 0;
|
||||
var shortSong = 0;
|
||||
switch (player.GameMode)
|
||||
{
|
||||
case EGameMode.TR_GAMEMODE_MEDLEY:
|
||||
@@ -192,25 +196,25 @@ namespace Vocaluxe.Lib.Database
|
||||
using (var command = new SqliteCommand())
|
||||
{
|
||||
command.Connection = connection;
|
||||
int dataBaseSongID = CSongs.GetSong(player.SongID).DataBaseSongID;
|
||||
return _AddScore(CProfiles.GetPlayerName(player.ProfileID), (int)Math.Round(player.Points), player.VoiceNr, player.DateTicks, medley,
|
||||
duet, shortSong, (int)CProfiles.GetDifficulty(player.ProfileID), dataBaseSongID, command);
|
||||
var dataBaseSongId = CSongs.GetSong(player.SongId).DataBaseSongId;
|
||||
return _AddScore(CProfiles.GetPlayerName(player.ProfileId), (int)Math.Round(player.Points), player.VoiceNr, player.DateTicks, medley,
|
||||
duet, shortSong, (int)CProfiles.GetDifficulty(player.ProfileId), dataBaseSongId, command);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int _AddScore(string playerName, int score, int lineNr, long date, int medley, int duet, int shortSong, int difficulty,
|
||||
int dataBaseSongID, SqliteCommand command)
|
||||
int dataBaseSongId, SqliteCommand command)
|
||||
{
|
||||
int lastInsertID = -1;
|
||||
var lastInsertId = -1;
|
||||
|
||||
if (dataBaseSongID >= 0)
|
||||
if (dataBaseSongId >= 0)
|
||||
{
|
||||
command.CommandText = "SELECT id FROM Scores WHERE SongID = @SongID AND PlayerName = @PlayerName AND Score = @Score AND " +
|
||||
command.CommandText = "SELECT id FROM Scores WHERE SongId = @SongId AND PlayerName = @PlayerName AND Score = @Score AND " +
|
||||
"LineNr = @LineNr AND Date = @Date AND Medley = @Medley AND Duet = @Duet AND ShortSong = @ShortSong AND Difficulty = @Difficulty";
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@SongID", dataBaseSongID);
|
||||
command.Parameters.AddWithValue("@PlayerName", playerName ?? String.Empty);
|
||||
command.Parameters.AddWithValue("@SongId", dataBaseSongId);
|
||||
command.Parameters.AddWithValue("@PlayerName", playerName ?? string.Empty);
|
||||
command.Parameters.AddWithValue("@Score", score);
|
||||
command.Parameters.AddWithValue("@LineNr", lineNr);
|
||||
command.Parameters.AddWithValue("@Date", date);
|
||||
@@ -224,22 +228,26 @@ namespace Vocaluxe.Lib.Database
|
||||
{
|
||||
reader = command.ExecuteReader();
|
||||
}
|
||||
catch (Exception) {}
|
||||
catch (Exception) { }
|
||||
|
||||
if (reader != null && reader.HasRows)
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
return reader.GetInt32(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (reader != null)
|
||||
{
|
||||
reader.Dispose();
|
||||
}
|
||||
|
||||
command.CommandText = "INSERT INTO Scores (SongID, PlayerName, Score, LineNr, Date, Medley, Duet, ShortSong, Difficulty) " +
|
||||
"VALUES (@SongID, @PlayerName, @Score, @LineNr, @Date, @Medley, @Duet, @ShortSong, @Difficulty)";
|
||||
command.CommandText = "INSERT INTO Scores (SongId, PlayerName, Score, LineNr, Date, Medley, Duet, ShortSong, Difficulty) " +
|
||||
"VALUES (@SongId, @PlayerName, @Score, @LineNr, @Date, @Medley, @Duet, @ShortSong, @Difficulty)";
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@SongID", dataBaseSongID);
|
||||
command.Parameters.AddWithValue("@PlayerName", playerName ?? String.Empty);
|
||||
command.Parameters.AddWithValue("@SongId", dataBaseSongId);
|
||||
command.Parameters.AddWithValue("@PlayerName", playerName ?? string.Empty);
|
||||
command.Parameters.AddWithValue("@Score", score);
|
||||
command.Parameters.AddWithValue("@LineNr", lineNr);
|
||||
command.Parameters.AddWithValue("@Date", date);
|
||||
@@ -257,15 +265,18 @@ namespace Vocaluxe.Lib.Database
|
||||
if (reader != null && reader.HasRows)
|
||||
{
|
||||
while (reader.Read())
|
||||
lastInsertID = reader.GetInt32(0);
|
||||
{
|
||||
lastInsertId = reader.GetInt32(0);
|
||||
}
|
||||
|
||||
reader.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
return lastInsertID;
|
||||
return lastInsertId;
|
||||
}
|
||||
|
||||
public List<SDBScoreEntry> LoadScore(int songID, EGameMode gameMode, EHighscoreStyle style)
|
||||
public List<SDBScoreEntry> LoadScore(int songId, EGameMode gameMode, EHighscoreStyle style)
|
||||
{
|
||||
var scores = new List<SDBScoreEntry>();
|
||||
using (var connection = new SqliteConnection())
|
||||
@@ -284,9 +295,9 @@ namespace Vocaluxe.Lib.Database
|
||||
using (var command = new SqliteCommand())
|
||||
{
|
||||
command.Connection = connection;
|
||||
int medley = 0;
|
||||
int duet = 0;
|
||||
int shortSong = 0;
|
||||
var medley = 0;
|
||||
var duet = 0;
|
||||
var shortSong = 0;
|
||||
switch (gameMode)
|
||||
{
|
||||
case EGameMode.TR_GAMEMODE_MEDLEY:
|
||||
@@ -300,129 +311,137 @@ namespace Vocaluxe.Lib.Database
|
||||
break;
|
||||
}
|
||||
|
||||
int dataBaseSongID = _GetDataBaseSongID(songID, command);
|
||||
if (dataBaseSongID < 0)
|
||||
var dataBaseSongId = _GetDataBaseSongId(songId, command);
|
||||
if (dataBaseSongId < 0)
|
||||
{
|
||||
return scores;
|
||||
}
|
||||
|
||||
switch (style)
|
||||
{
|
||||
case EHighscoreStyle.TR_CONFIG_HIGHSCORE_LIST_BEST:
|
||||
command.CommandText = "SELECT os.PlayerName, os.Score, os.Date, os.Difficulty, os.LineNr, os.id " +
|
||||
"FROM Scores os " +
|
||||
"INNER JOIN ( " +
|
||||
"SELECT sc.PlayerName, sc.Score, sc.Difficulty, sc.LineNr, MIN(sc.Date) AS Date " +
|
||||
"FROM Scores sc " +
|
||||
"INNER JOIN ( " +
|
||||
"SELECT Playername, MAX(Score) AS Score, Difficulty, LineNr " +
|
||||
"FROM Scores " +
|
||||
"WHERE [SongID] = @SongID AND [Medley] = @Medley AND [Duet] = @Duet AND [ShortSong] = @ShortSong " +
|
||||
"GROUP BY PlayerName, Difficulty, LineNr " +
|
||||
") AS mc " +
|
||||
"ON sc.PlayerName = mc.PlayerName AND sc.Difficulty = mc.Difficulty AND sc.LineNr = mc.LineNr AND sc.Score = mc.Score " +
|
||||
"WHERE [SongID] = @SongID AND [Medley] = @Medley AND [Duet] = @Duet AND [ShortSong] = @ShortSong " +
|
||||
"GROUP BY sc.PlayerName, sc.Difficulty, sc.LineNr, sc.Score " +
|
||||
") AS iq " +
|
||||
"ON os.PlayerName = iq.PlayerName AND os.Difficulty = iq.Difficulty AND os.LineNr = iq.LineNr AND os.Score = iq.Score AND os.Date = iq.Date " +
|
||||
"WHERE [SongID] = @SongID AND [Medley] = @Medley AND [Duet] = @Duet AND [ShortSong] = @ShortSong " +
|
||||
"GROUP BY os.PlayerName, os.Difficulty, os.LineNr, os.Score " +
|
||||
"ORDER BY os.Score DESC, os.Date ASC";
|
||||
"FROM Scores os " +
|
||||
"INNER JOIN ( " +
|
||||
"SELECT sc.PlayerName, sc.Score, sc.Difficulty, sc.LineNr, MIN(sc.Date) AS Date " +
|
||||
"FROM Scores sc " +
|
||||
"INNER JOIN ( " +
|
||||
"SELECT Playername, MAX(Score) AS Score, Difficulty, LineNr " +
|
||||
"FROM Scores " +
|
||||
"WHERE [SongId] = @SongId AND [Medley] = @Medley AND [Duet] = @Duet AND [ShortSong] = @ShortSong " +
|
||||
"GROUP BY PlayerName, Difficulty, LineNr " +
|
||||
") AS mc " +
|
||||
"ON sc.PlayerName = mc.PlayerName AND sc.Difficulty = mc.Difficulty AND sc.LineNr = mc.LineNr AND sc.Score = mc.Score " +
|
||||
"WHERE [SongId] = @SongId AND [Medley] = @Medley AND [Duet] = @Duet AND [ShortSong] = @ShortSong " +
|
||||
"GROUP BY sc.PlayerName, sc.Difficulty, sc.LineNr, sc.Score " +
|
||||
") AS iq " +
|
||||
"ON os.PlayerName = iq.PlayerName AND os.Difficulty = iq.Difficulty AND os.LineNr = iq.LineNr AND os.Score = iq.Score AND os.Date = iq.Date " +
|
||||
"WHERE [SongId] = @SongId AND [Medley] = @Medley AND [Duet] = @Duet AND [ShortSong] = @ShortSong " +
|
||||
"GROUP BY os.PlayerName, os.Difficulty, os.LineNr, os.Score " +
|
||||
"ORDER BY os.Score DESC, os.Date ASC";
|
||||
break;
|
||||
case EHighscoreStyle.TR_CONFIG_HIGHSCORE_LIST_ALL:
|
||||
command.CommandText = "SELECT PlayerName, Score, Date, Difficulty, LineNr, id " +
|
||||
"FROM Scores " +
|
||||
"WHERE [SongID] = @SongID AND [Medley] = @Medley AND [Duet] = @Duet AND [ShortSong] = @ShortSong " +
|
||||
"ORDER BY [Score] DESC, [Date] ASC";
|
||||
"FROM Scores " +
|
||||
"WHERE [SongId] = @SongId AND [Medley] = @Medley AND [Duet] = @Duet AND [ShortSong] = @ShortSong " +
|
||||
"ORDER BY [Score] DESC, [Date] ASC";
|
||||
break;
|
||||
}
|
||||
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@SongID", dataBaseSongID);
|
||||
command.Parameters.AddWithValue("@SongId", dataBaseSongId);
|
||||
command.Parameters.AddWithValue("@Medley", medley);
|
||||
command.Parameters.AddWithValue("@Duet", duet);
|
||||
command.Parameters.AddWithValue("@ShortSong", shortSong);
|
||||
|
||||
SqliteDataReader reader = command.ExecuteReader();
|
||||
var reader = command.ExecuteReader();
|
||||
if (reader != null && reader.HasRows)
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var score = new SDBScoreEntry
|
||||
{
|
||||
Name = reader.GetString(0),
|
||||
Score = reader.GetInt32(1),
|
||||
Date = new DateTime(reader.GetInt64(2)).ToString("dd/MM/yyyy"),
|
||||
Difficulty = (EGameDifficulty)reader.GetInt32(3),
|
||||
VoiceNr = reader.GetInt32(4),
|
||||
ID = reader.GetInt32(5)
|
||||
};
|
||||
{
|
||||
Name = reader.GetString(0),
|
||||
Score = reader.GetInt32(1),
|
||||
Date = new DateTime(reader.GetInt64(2)).ToString("dd/MM/yyyy"),
|
||||
Difficulty = (EGameDifficulty)reader.GetInt32(3),
|
||||
VoiceNr = reader.GetInt32(4),
|
||||
Id = reader.GetInt32(5)
|
||||
};
|
||||
|
||||
scores.Add(score);
|
||||
}
|
||||
|
||||
reader.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return scores;
|
||||
}
|
||||
|
||||
private void _IncreaseSongCounter(int dataBaseSongID, SqliteCommand command)
|
||||
private void _IncreaseSongCounter(int dataBaseSongId, SqliteCommand command)
|
||||
{
|
||||
command.CommandText = "UPDATE Songs SET NumPlayed = NumPlayed + 1 WHERE [id] = @id";
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@id", dataBaseSongID);
|
||||
command.Parameters.AddWithValue("@id", dataBaseSongId);
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
private int _GetDataBaseSongID(int songID, SqliteCommand command)
|
||||
private int _GetDataBaseSongId(int songId, SqliteCommand command)
|
||||
{
|
||||
CSong song = CSongs.GetSong(songID);
|
||||
var song = CSongs.GetSong(songId);
|
||||
|
||||
if (song == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _GetDataBaseSongID(song.Artist, song.Title, 0, command);
|
||||
return _GetDataBaseSongId(song.Artist, song.Title, 0, command);
|
||||
}
|
||||
|
||||
private int _GetDataBaseSongID(string artist, string title, int defNumPlayed, SqliteCommand command)
|
||||
private int _GetDataBaseSongId(string artist, string title, int defNumPlayed, SqliteCommand command)
|
||||
{
|
||||
command.CommandText = "SELECT id FROM Songs WHERE [Title] = @title AND [Artist] = @artist";
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@title", title ?? String.Empty);
|
||||
command.Parameters.AddWithValue("@artist", artist ?? String.Empty);
|
||||
command.Parameters.AddWithValue("@title", title ?? string.Empty);
|
||||
command.Parameters.AddWithValue("@artist", artist ?? string.Empty);
|
||||
|
||||
SqliteDataReader reader = command.ExecuteReader();
|
||||
var reader = command.ExecuteReader();
|
||||
|
||||
if (reader != null && reader.HasRows)
|
||||
{
|
||||
reader.Read();
|
||||
int id = reader.GetInt32(0);
|
||||
var id = reader.GetInt32(0);
|
||||
reader.Dispose();
|
||||
return id;
|
||||
}
|
||||
|
||||
if (reader != null)
|
||||
{
|
||||
reader.Close();
|
||||
}
|
||||
|
||||
command.CommandText = "INSERT INTO Songs (Title, Artist, NumPlayed, DateAdded) " +
|
||||
"VALUES (@title, @artist, @numplayed, @dateadded)";
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@title", title ?? String.Empty);
|
||||
command.Parameters.AddWithValue("@artist", artist ?? String.Empty);
|
||||
command.Parameters.AddWithValue("@title", title ?? string.Empty);
|
||||
command.Parameters.AddWithValue("@artist", artist ?? string.Empty);
|
||||
command.Parameters.AddWithValue("@numplayed", defNumPlayed);
|
||||
command.Parameters.AddWithValue("@dateadded", DateTime.Now.Ticks);
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
command.CommandText = "SELECT id FROM Songs WHERE [Title] = @title AND [Artist] = @artist";
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@title", title ?? String.Empty);
|
||||
command.Parameters.AddWithValue("@artist", artist ?? String.Empty);
|
||||
command.Parameters.AddWithValue("@title", title ?? string.Empty);
|
||||
command.Parameters.AddWithValue("@artist", artist ?? string.Empty);
|
||||
|
||||
reader = command.ExecuteReader();
|
||||
|
||||
if (reader != null)
|
||||
{
|
||||
reader.Read();
|
||||
int id = reader.GetInt32(0);
|
||||
var id = reader.GetInt32(0);
|
||||
reader.Dispose();
|
||||
return id;
|
||||
}
|
||||
@@ -430,10 +449,10 @@ namespace Vocaluxe.Lib.Database
|
||||
return -1;
|
||||
}
|
||||
|
||||
private bool _GetDataBaseSongInfos(int songID, out string artist, out string title, out int numPlayed, out DateTime dateAdded, string filePath)
|
||||
private bool _GetDataBaseSongInfos(int songId, out string artist, out string title, out int numPlayed, out DateTime dateAdded, string filePath)
|
||||
{
|
||||
artist = String.Empty;
|
||||
title = String.Empty;
|
||||
artist = string.Empty;
|
||||
title = string.Empty;
|
||||
numPlayed = 0;
|
||||
dateAdded = DateTime.Today;
|
||||
|
||||
@@ -455,7 +474,7 @@ namespace Vocaluxe.Lib.Database
|
||||
command.Connection = connection;
|
||||
command.CommandText = "SELECT Artist, Title, NumPlayed, DateAdded FROM Songs WHERE [id] = @id";
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@id", songID);
|
||||
command.Parameters.AddWithValue("@id", songId);
|
||||
|
||||
SqliteDataReader reader;
|
||||
try
|
||||
@@ -472,22 +491,33 @@ namespace Vocaluxe.Lib.Database
|
||||
reader.Read();
|
||||
|
||||
if (!reader.IsDBNull(0))
|
||||
{
|
||||
artist = reader.GetString(0);
|
||||
}
|
||||
|
||||
if (!reader.IsDBNull(1))
|
||||
title = reader.GetString(1);
|
||||
{
|
||||
title = reader.GetString(1);
|
||||
}
|
||||
|
||||
if (!reader.IsDBNull(2))
|
||||
{
|
||||
numPlayed = reader.GetInt32(2);
|
||||
}
|
||||
|
||||
if (!reader.IsDBNull(3))
|
||||
{
|
||||
dateAdded = new DateTime(reader.GetInt64(3));
|
||||
}
|
||||
|
||||
reader.Dispose();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (reader != null)
|
||||
{
|
||||
reader.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -525,7 +555,7 @@ namespace Vocaluxe.Lib.Database
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
command.CommandText = "CREATE TABLE IF NOT EXISTS Scores ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
|
||||
"SongID INTEGER NOT NULL, PlayerName TEXT NOT NULL, Score INTEGER NOT NULL, LineNr INTEGER NOT NULL, Date BIGINT NOT NULL, " +
|
||||
"SongId INTEGER NOT NULL, PlayerName TEXT NOT NULL, Score INTEGER NOT NULL, LineNr INTEGER NOT NULL, Date BIGINT NOT NULL, " +
|
||||
"Medley INTEGER NOT NULL, Duet INTEGER NOT NULL, ShortSong INTEGER NOT NULL, Difficulty INTEGER NOT NULL);";
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
@@ -561,7 +591,7 @@ namespace Vocaluxe.Lib.Database
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
command.CommandText = "CREATE TABLE IF NOT EXISTS Scores ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
|
||||
"SongID INTEGER NOT NULL, PlayerName TEXT NOT NULL, Score INTEGER NOT NULL, LineNr INTEGER NOT NULL, Date BIGINT NOT NULL, " +
|
||||
"SongId INTEGER NOT NULL, PlayerName TEXT NOT NULL, Score INTEGER NOT NULL, LineNr INTEGER NOT NULL, Date BIGINT NOT NULL, " +
|
||||
"Medley INTEGER NOT NULL, Duet INTEGER NOT NULL, Difficulty INTEGER NOT NULL);";
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
@@ -575,7 +605,7 @@ namespace Vocaluxe.Lib.Database
|
||||
/// <returns></returns>
|
||||
private bool _CreateOrConvert(string filePath)
|
||||
{
|
||||
bool result = true;
|
||||
var result = true;
|
||||
using (var connection = new SqliteConnection())
|
||||
{
|
||||
connection.ConnectionString = "Data Source=" + filePath;
|
||||
@@ -593,10 +623,10 @@ namespace Vocaluxe.Lib.Database
|
||||
{
|
||||
command.Connection = connection;
|
||||
command.CommandText = "PRAGMA user_version";
|
||||
SqliteDataReader reader = command.ExecuteReader();
|
||||
var reader = command.ExecuteReader();
|
||||
reader.Read();
|
||||
|
||||
int version = reader.GetInt32(0);
|
||||
var version = reader.GetInt32(0);
|
||||
|
||||
reader.Dispose();
|
||||
|
||||
@@ -604,7 +634,7 @@ namespace Vocaluxe.Lib.Database
|
||||
command.CommandText = "SELECT name FROM sqlite_master WHERE type='table' AND name='US_Scores';";
|
||||
reader = command.ExecuteReader();
|
||||
reader.Read();
|
||||
bool scoresTableExists = reader.HasRows;
|
||||
var scoresTableExists = reader.HasRows;
|
||||
|
||||
reader.Dispose();
|
||||
|
||||
@@ -615,7 +645,7 @@ namespace Vocaluxe.Lib.Database
|
||||
{
|
||||
reader = command.ExecuteReader();
|
||||
}
|
||||
catch (Exception) {}
|
||||
catch (Exception) { }
|
||||
|
||||
if (reader == null || reader.FieldCount == 0)
|
||||
{
|
||||
@@ -637,12 +667,14 @@ namespace Vocaluxe.Lib.Database
|
||||
result &= _UpdateDatabase(2, connection);
|
||||
}
|
||||
else
|
||||
{
|
||||
_CreateHighscoreDB(filePath);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
reader.Read();
|
||||
int currentVersion = reader.GetInt32(0);
|
||||
var currentVersion = reader.GetInt32(0);
|
||||
if (currentVersion < CSettings.DatabaseHighscoreVersion)
|
||||
{
|
||||
// update database
|
||||
@@ -651,7 +683,9 @@ namespace Vocaluxe.Lib.Database
|
||||
}
|
||||
|
||||
if (reader != null)
|
||||
{
|
||||
reader.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -683,35 +717,36 @@ namespace Vocaluxe.Lib.Database
|
||||
command.Connection = connection;
|
||||
//The USDX database has no column for LineNr, Medley and Duet so just fill 0 in there
|
||||
command.CommandText =
|
||||
"INSERT INTO Scores (SongID, PlayerName, Score, LineNr, Date, Medley, Duet, Difficulty) SELECT SongID, Player, Score, '0', Date, '0', '0', Difficulty from US_Scores";
|
||||
"INSERT INTO Scores (SongId, PlayerName, Score, LineNr, Date, Medley, Duet, Difficulty) SELECT SongId, Player, Score, '0', Date, '0', '0', Difficulty from US_Scores";
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
command.CommandText = "INSERT INTO Songs SELECT ID, Artist, Title, TimesPlayed from US_Songs";
|
||||
command.CommandText = "INSERT INTO Songs SELECT Id, Artist, Title, TimesPlayed from US_Songs";
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
var scores = new List<SData>();
|
||||
var songs = new List<SData>();
|
||||
|
||||
command.CommandText = "SELECT id, PlayerName, Date FROM Scores";
|
||||
SqliteDataReader reader = command.ExecuteReader();
|
||||
var reader = command.ExecuteReader();
|
||||
|
||||
if (reader != null && reader.HasRows)
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var data = new SData {Id = reader.GetInt32(0), Str1 = reader.GetString(1)};
|
||||
var data = new SData { Id = reader.GetInt32(0), Str1 = reader.GetString(1) };
|
||||
Int64 ticks = 0;
|
||||
|
||||
try
|
||||
{
|
||||
ticks = reader.GetInt64(2);
|
||||
}
|
||||
catch {}
|
||||
catch { }
|
||||
|
||||
data.Ticks = _UnixTimeToTicks((int)ticks);
|
||||
|
||||
scores.Add(data);
|
||||
}
|
||||
|
||||
reader.Close();
|
||||
}
|
||||
|
||||
@@ -723,37 +758,40 @@ namespace Vocaluxe.Lib.Database
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
var data = new SData {Id = reader.GetInt32(0), Str1 = reader.GetString(1), Str2 = reader.GetString(2)};
|
||||
var data = new SData { Id = reader.GetInt32(0), Str1 = reader.GetString(1), Str2 = reader.GetString(2) };
|
||||
songs.Add(data);
|
||||
}
|
||||
}
|
||||
|
||||
if (reader != null)
|
||||
{
|
||||
reader.Dispose();
|
||||
}
|
||||
|
||||
SqliteTransaction transaction = connection.BeginTransaction();
|
||||
var transaction = connection.BeginTransaction();
|
||||
command.Transaction = transaction;
|
||||
// update Title and Artist strings
|
||||
foreach (SData data in songs)
|
||||
foreach (var data in songs)
|
||||
{
|
||||
command.CommandText = "UPDATE Songs SET [Artist] = @artist, [Title] = @title WHERE [ID] = @id";
|
||||
command.CommandText = "UPDATE Songs SET [Artist] = @artist, [Title] = @title WHERE [Id] = @id";
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@title", data.Str2 ?? String.Empty);
|
||||
command.Parameters.AddWithValue("@artist", data.Str1 ?? String.Empty);
|
||||
command.Parameters.AddWithValue("@title", data.Str2 ?? string.Empty);
|
||||
command.Parameters.AddWithValue("@artist", data.Str1 ?? string.Empty);
|
||||
command.Parameters.AddWithValue("@id", data.Id);
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// update player names
|
||||
foreach (SData data in scores)
|
||||
foreach (var data in scores)
|
||||
{
|
||||
command.CommandText = "UPDATE Scores SET [PlayerName] = @player, [Date] = @date WHERE [id] = @id";
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@player", data.Str1 ?? String.Empty);
|
||||
command.Parameters.AddWithValue("@player", data.Str1 ?? string.Empty);
|
||||
command.Parameters.AddWithValue("@date", data.Ticks);
|
||||
command.Parameters.AddWithValue("@id", data.Id);
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
|
||||
//Delete old tables after conversion
|
||||
@@ -808,18 +846,21 @@ namespace Vocaluxe.Lib.Database
|
||||
{
|
||||
command.Connection = connection;
|
||||
command.CommandText = "PRAGMA table_info(US_Scores);";
|
||||
bool dateExists = false;
|
||||
using (SqliteDataReader reader = command.ExecuteReader())
|
||||
var dateExists = false;
|
||||
using (var reader = command.ExecuteReader())
|
||||
{
|
||||
//Check for column Date
|
||||
while (reader.Read())
|
||||
{
|
||||
for (int i = 0; i < reader.FieldCount; i++)
|
||||
for (var i = 0; i < reader.FieldCount; i++)
|
||||
{
|
||||
if (reader.GetName(i) == "name")
|
||||
{
|
||||
if (reader.GetString(i) == "Date")
|
||||
{
|
||||
dateExists = true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -828,11 +869,11 @@ namespace Vocaluxe.Lib.Database
|
||||
|
||||
//This is a USDX 1.01 DB
|
||||
command.CommandText = !dateExists
|
||||
? "INSERT INTO Scores (SongID, PlayerName, Score, LineNr, Date, Medley, Duet, Difficulty) SELECT SongID, Player, Score, '0', '0', '0', '0', Difficulty from US_Scores"
|
||||
: "INSERT INTO Scores (SongID, PlayerName, Score, LineNr, Date, Medley, Duet, Difficulty) SELECT SongID, Player, Score, '0', Date, '0', '0', Difficulty from US_Scores";
|
||||
? "INSERT INTO Scores (SongId, PlayerName, Score, LineNr, Date, Medley, Duet, Difficulty) SELECT SongId, Player, Score, '0', '0', '0', '0', Difficulty from US_Scores"
|
||||
: "INSERT INTO Scores (SongId, PlayerName, Score, LineNr, Date, Medley, Duet, Difficulty) SELECT SongId, Player, Score, '0', Date, '0', '0', Difficulty from US_Scores";
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
command.CommandText = "INSERT INTO Songs SELECT ID, Artist, Title, TimesPlayed from US_Songs";
|
||||
command.CommandText = "INSERT INTO Songs SELECT Id, Artist, Title, TimesPlayed from US_Songs";
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
// convert from CP1252 to UTF8
|
||||
@@ -840,28 +881,32 @@ namespace Vocaluxe.Lib.Database
|
||||
var songs = new List<SData>();
|
||||
|
||||
Sqlite3.sqlite3 oldDB;
|
||||
int res = Sqlite3.sqlite3_open(filePath, out oldDB);
|
||||
var res = Sqlite3.sqlite3_open(filePath, out oldDB);
|
||||
|
||||
if (res != Sqlite3.SQLITE_OK)
|
||||
{
|
||||
CLog.Error("Error opening Database: " + filePath + " (" + Sqlite3.sqlite3_errmsg(oldDB) + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
var stmt = new Sqlite3.Vdbe();
|
||||
res = Sqlite3.sqlite3_prepare_v2(oldDB, "SELECT id, Artist, Title FROM Songs", -1, ref stmt, 0);
|
||||
|
||||
if (res != Sqlite3.SQLITE_OK)
|
||||
{
|
||||
CLog.Error("Error query Database: " + filePath + " (" + Sqlite3.sqlite3_errmsg(oldDB) + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Sqlite3.sqlite3_step(Stmt);
|
||||
Encoding utf8 = Encoding.UTF8;
|
||||
Encoding cp1252 = Encoding.GetEncoding(1252);
|
||||
var utf8 = Encoding.UTF8;
|
||||
var cp1252 = Encoding.GetEncoding(1252);
|
||||
|
||||
while (Sqlite3.sqlite3_step(stmt) == Sqlite3.SQLITE_ROW)
|
||||
{
|
||||
var data = new SData {Id = Sqlite3.sqlite3_column_int(stmt, 0)};
|
||||
var data = new SData { Id = Sqlite3.sqlite3_column_int(stmt, 0) };
|
||||
|
||||
byte[] bytes = Sqlite3.sqlite3_column_rawbytes(stmt, 1);
|
||||
var bytes = Sqlite3.sqlite3_column_rawbytes(stmt, 1);
|
||||
data.Str1 = bytes != null ? utf8.GetString(Encoding.Convert(cp1252, utf8, bytes)) : "Someone";
|
||||
|
||||
bytes = Sqlite3.sqlite3_column_rawbytes(stmt, 2);
|
||||
@@ -869,6 +914,7 @@ namespace Vocaluxe.Lib.Database
|
||||
|
||||
songs.Add(data);
|
||||
}
|
||||
|
||||
Sqlite3.sqlite3_finalize(stmt);
|
||||
}
|
||||
|
||||
@@ -877,54 +923,66 @@ namespace Vocaluxe.Lib.Database
|
||||
// ReSharper disable ConvertIfStatementToConditionalTernaryExpression
|
||||
if (!dateExists)
|
||||
// ReSharper restore ConvertIfStatementToConditionalTernaryExpression
|
||||
{
|
||||
res = Sqlite3.sqlite3_prepare_v2(oldDB, "SELECT id, PlayerName FROM Scores", -1, ref stmt, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
res = Sqlite3.sqlite3_prepare_v2(oldDB, "SELECT id, PlayerName, Date FROM Scores", -1, ref stmt, 0);
|
||||
}
|
||||
|
||||
if (res != Sqlite3.SQLITE_OK)
|
||||
{
|
||||
CLog.Error("Error query Database: " + filePath + " (" + Sqlite3.sqlite3_errmsg(oldDB) + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Sqlite3.sqlite3_step(Stmt);
|
||||
Encoding utf8 = Encoding.UTF8;
|
||||
Encoding cp1252 = Encoding.GetEncoding(1252);
|
||||
var utf8 = Encoding.UTF8;
|
||||
var cp1252 = Encoding.GetEncoding(1252);
|
||||
|
||||
while (Sqlite3.sqlite3_step(stmt) == Sqlite3.SQLITE_ROW)
|
||||
{
|
||||
var data = new SData {Id = Sqlite3.sqlite3_column_int(stmt, 0)};
|
||||
var data = new SData { Id = Sqlite3.sqlite3_column_int(stmt, 0) };
|
||||
|
||||
byte[] bytes = Sqlite3.sqlite3_column_rawbytes(stmt, 1);
|
||||
var bytes = Sqlite3.sqlite3_column_rawbytes(stmt, 1);
|
||||
data.Str1 = bytes != null ? utf8.GetString(Encoding.Convert(cp1252, utf8, bytes)) : "Someone";
|
||||
|
||||
if (dateExists)
|
||||
{
|
||||
data.Ticks = _UnixTimeToTicks(Sqlite3.sqlite3_column_int(stmt, 2));
|
||||
}
|
||||
|
||||
scores.Add(data);
|
||||
}
|
||||
|
||||
Sqlite3.sqlite3_finalize(stmt);
|
||||
}
|
||||
}
|
||||
|
||||
Sqlite3.sqlite3_close(oldDB);
|
||||
|
||||
SqliteTransaction transaction = connection.BeginTransaction();
|
||||
var transaction = connection.BeginTransaction();
|
||||
command.Transaction = transaction;
|
||||
|
||||
// update Title and Artist strings
|
||||
foreach (SData data in songs)
|
||||
foreach (var data in songs)
|
||||
{
|
||||
command.CommandText = "UPDATE Songs SET [Artist] = @artist, [Title] = @title WHERE [ID] = @id";
|
||||
command.CommandText = "UPDATE Songs SET [Artist] = @artist, [Title] = @title WHERE [Id] = @id";
|
||||
command.Parameters.Clear();
|
||||
command.Parameters.AddWithValue("@title", data.Str2 ?? String.Empty);
|
||||
command.Parameters.AddWithValue("@artist", data.Str1 ?? String.Empty);
|
||||
command.Parameters.AddWithValue("@title", data.Str2 ?? string.Empty);
|
||||
command.Parameters.AddWithValue("@artist", data.Str1 ?? string.Empty);
|
||||
command.Parameters.AddWithValue("@id", data.Id);
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
// update player names
|
||||
foreach (SData data in scores)
|
||||
foreach (var data in scores)
|
||||
{
|
||||
if (!dateExists)
|
||||
{
|
||||
command.CommandText = "UPDATE Scores SET [PlayerName] = @player WHERE [id] = @id";
|
||||
}
|
||||
else
|
||||
{
|
||||
command.CommandText = "UPDATE Scores SET [PlayerName] = @player, [Date] = @date WHERE [id] = @id";
|
||||
@@ -932,11 +990,15 @@ namespace Vocaluxe.Lib.Database
|
||||
|
||||
command.Parameters.Clear();
|
||||
if (dateExists)
|
||||
{
|
||||
command.Parameters.AddWithValue("@date", data.Ticks);
|
||||
command.Parameters.AddWithValue("@player", data.Str1 ?? String.Empty);
|
||||
}
|
||||
|
||||
command.Parameters.AddWithValue("@player", data.Str1 ?? string.Empty);
|
||||
command.Parameters.AddWithValue("@id", data.Id);
|
||||
command.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
transaction.Commit();
|
||||
|
||||
//Delete old tables after conversion
|
||||
@@ -953,12 +1015,16 @@ namespace Vocaluxe.Lib.Database
|
||||
|
||||
private bool _UpdateDatabase(int currentVersion, SqliteConnection connection)
|
||||
{
|
||||
bool updated = true;
|
||||
var updated = true;
|
||||
|
||||
if (currentVersion < 2)
|
||||
{
|
||||
updated &= _ConvertV1toV2(connection);
|
||||
}
|
||||
else if (currentVersion < 3)
|
||||
{
|
||||
updated &= _ConvertV2toV3(connection);
|
||||
}
|
||||
|
||||
return updated;
|
||||
}
|
||||
@@ -998,7 +1064,7 @@ namespace Vocaluxe.Lib.Database
|
||||
command.ExecuteNonQuery();
|
||||
|
||||
//Read NumPlayed from Scores and save to Songs
|
||||
command.CommandText = "SELECT SongID, Date FROM Scores ORDER BY Date ASC";
|
||||
command.CommandText = "SELECT SongId, Date FROM Scores ORDER BY Date ASC";
|
||||
|
||||
SqliteDataReader reader;
|
||||
try
|
||||
@@ -1011,25 +1077,29 @@ namespace Vocaluxe.Lib.Database
|
||||
}
|
||||
|
||||
long lastDateAdded = -1;
|
||||
int lastID = -1;
|
||||
DateTime dt = new DateTime(1, 1, 1, 0, 0, 5);
|
||||
long sec = dt.Ticks;
|
||||
List<int> ids = new List<int>();
|
||||
var lastId = -1;
|
||||
var dt = new DateTime(1, 1, 1, 0, 0, 5);
|
||||
var sec = dt.Ticks;
|
||||
var ids = new List<int>();
|
||||
while (reader.Read())
|
||||
{
|
||||
int id = reader.GetInt32(0);
|
||||
long dateAdded = reader.GetInt64(1);
|
||||
if (id != lastID || dateAdded > lastDateAdded + sec)
|
||||
var id = reader.GetInt32(0);
|
||||
var dateAdded = reader.GetInt64(1);
|
||||
if (id != lastId || dateAdded > lastDateAdded + sec)
|
||||
{
|
||||
ids.Add(id);
|
||||
lastID = id;
|
||||
lastId = id;
|
||||
lastDateAdded = dateAdded;
|
||||
}
|
||||
}
|
||||
|
||||
reader.Dispose();
|
||||
|
||||
foreach (int id in ids)
|
||||
foreach (var id in ids)
|
||||
{
|
||||
_IncreaseSongCounter(id, command);
|
||||
}
|
||||
|
||||
command.Dispose();
|
||||
|
||||
return true;
|
||||
@@ -1056,11 +1126,14 @@ namespace Vocaluxe.Lib.Database
|
||||
using (var cmdSource = new SqliteCommand())
|
||||
{
|
||||
cmdSource.Connection = connSource;
|
||||
|
||||
#region import table scores
|
||||
cmdSource.CommandText = "SELECT SongID, PlayerName, Score, LineNr, Date, Medley, Duet, ShortSong, Difficulty FROM Scores";
|
||||
SqliteDataReader source = cmdSource.ExecuteReader();
|
||||
cmdSource.CommandText = "SELECT SongId, PlayerName, Score, LineNr, Date, Medley, Duet, ShortSong, Difficulty FROM Scores";
|
||||
var source = cmdSource.ExecuteReader();
|
||||
if (source == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (source.FieldCount == 0)
|
||||
{
|
||||
@@ -1070,21 +1143,23 @@ namespace Vocaluxe.Lib.Database
|
||||
|
||||
while (source.Read())
|
||||
{
|
||||
int songid = source.GetInt32(0);
|
||||
string player = source.GetString(1);
|
||||
int score = source.GetInt32(2);
|
||||
int linenr = source.GetInt32(3);
|
||||
long date = source.GetInt64(4);
|
||||
int medley = source.GetInt32(5);
|
||||
int duet = source.GetInt32(6);
|
||||
int shortsong = source.GetInt32(7);
|
||||
int diff = source.GetInt32(8);
|
||||
var songid = source.GetInt32(0);
|
||||
var player = source.GetString(1);
|
||||
var score = source.GetInt32(2);
|
||||
var linenr = source.GetInt32(3);
|
||||
var date = source.GetInt64(4);
|
||||
var medley = source.GetInt32(5);
|
||||
var duet = source.GetInt32(6);
|
||||
var shortsong = source.GetInt32(7);
|
||||
var diff = source.GetInt32(8);
|
||||
|
||||
string artist, title;
|
||||
DateTime dateadded;
|
||||
int numplayed;
|
||||
if (_GetDataBaseSongInfos(songid, out artist, out title, out numplayed, out dateadded, sourceDBPath))
|
||||
{
|
||||
AddScore(player, score, linenr, date, medley, duet, shortsong, diff, artist, title, numplayed, _FilePath);
|
||||
}
|
||||
}
|
||||
#endregion import table scores
|
||||
|
||||
|
||||
+137
-39
@@ -15,8 +15,6 @@
|
||||
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
using SlimDX;
|
||||
using SlimDX.Direct3D9;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
@@ -24,6 +22,8 @@ using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Windows.Forms;
|
||||
using SlimDX;
|
||||
using SlimDX.Direct3D9;
|
||||
using SlimDX.Windows;
|
||||
using Vocaluxe.Base;
|
||||
using VocaluxeLib;
|
||||
@@ -39,7 +39,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
if (OnMessage == null || OnMessage(ref m))
|
||||
{
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,7 +65,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
base.Dispose();
|
||||
if (D3DTexture != null)
|
||||
{
|
||||
D3DTexture.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +152,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
|
||||
if (
|
||||
!_D3D.CheckDeviceMultisampleType(_D3D.Adapters.DefaultAdapter.Adapter, DeviceType.Hardware, _D3D.Adapters.DefaultAdapter.CurrentDisplayMode.Format, false, msType,
|
||||
out quality))
|
||||
out quality))
|
||||
{
|
||||
CLog.Error("[Direct3D] This AAMode is not supported by this device or driver, fallback to no AA");
|
||||
msType = MultisampleType.None;
|
||||
@@ -163,8 +167,8 @@ namespace Vocaluxe.Lib.Draw
|
||||
_PresentParameters.PresentationInterval = CConfig.Config.Graphics.VSync == EOffOn.TR_CONFIG_ON ? PresentInterval.Default : PresentInterval.Immediate;
|
||||
|
||||
//GMA 950 graphics devices can only process vertices in software mode
|
||||
Capabilities caps = _D3D.GetDeviceCaps(_D3D.Adapters.DefaultAdapter.Adapter, DeviceType.Hardware);
|
||||
CreateFlags flags = (caps.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0 ? CreateFlags.HardwareVertexProcessing : CreateFlags.SoftwareVertexProcessing;
|
||||
var caps = _D3D.GetDeviceCaps(_D3D.Adapters.DefaultAdapter.Adapter, DeviceType.Hardware);
|
||||
var flags = (caps.DeviceCaps & DeviceCaps.HWTransformAndLight) != 0 ? CreateFlags.HardwareVertexProcessing : CreateFlags.SoftwareVertexProcessing;
|
||||
|
||||
//Check if Pow2 textures are needed
|
||||
_NonPowerOf2TextureSupported = true;
|
||||
@@ -198,10 +202,14 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
// The window was minimized, so restore it to the last known size
|
||||
if (_Form.ClientSize.Width == 0 || _Form.ClientSize.Height == 0)
|
||||
{
|
||||
_Form.ClientSize = _SizeBeforeMinimize;
|
||||
}
|
||||
|
||||
if (_H == _Form.ClientSize.Height && _W == _Form.ClientSize.Width && CConfig.Config.Graphics.ScreenAlignment == _CurrentAlignment)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_CurrentAlignment = CConfig.Config.Graphics.ScreenAlignment;
|
||||
_H = _Form.ClientSize.Height;
|
||||
@@ -252,21 +260,26 @@ namespace Vocaluxe.Lib.Draw
|
||||
public override bool Init()
|
||||
{
|
||||
if (!base.Init())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_Device.Disposed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_InitDevice();
|
||||
|
||||
//This creates a new white texture and adds it to the texture pool
|
||||
//This texture is used for the DrawRect method
|
||||
using (var blankMap = new Bitmap(1, 1))
|
||||
using (Graphics g = Graphics.FromImage(blankMap))
|
||||
using (var g = Graphics.FromImage(blankMap))
|
||||
{
|
||||
g.Clear(Color.White);
|
||||
_BlankTexture = AddTexture(blankMap);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -274,44 +287,88 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
_AdjustNewBorders();
|
||||
|
||||
_VertexBuffer = new VertexBuffer(_Device, CSettings.VertexBufferElements * (4 * Marshal.SizeOf(typeof(STexturedColoredVertex))), Usage.WriteOnly | Usage.Dynamic,
|
||||
VertexFormat.Position | VertexFormat.Texture1 | VertexFormat.Diffuse, Pool.Default);
|
||||
_VertexBuffer = new VertexBuffer(_Device, CSettings.VertexBufferElements * 4 * Marshal.SizeOf(typeof(STexturedColoredVertex)), Usage.WriteOnly | Usage.Dynamic,
|
||||
VertexFormat.Position | VertexFormat.Texture1 | VertexFormat.Diffuse, Pool.Default);
|
||||
|
||||
if (_Device.SetStreamSource(0, _VertexBuffer, 0, Marshal.SizeOf(typeof(STexturedColoredVertex))).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set stream source");
|
||||
}
|
||||
|
||||
_Device.VertexDeclaration = STexturedColoredVertex.GetDeclaration(_Device);
|
||||
|
||||
if (_Device.SetRenderState(RenderState.CullMode, Cull.None).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set cull mode");
|
||||
}
|
||||
|
||||
if (_Device.SetRenderState(RenderState.AlphaBlendEnable, true).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to enable alpha blending");
|
||||
}
|
||||
|
||||
if (_Device.SetRenderState(RenderState.Lighting, false).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to disable lighting");
|
||||
}
|
||||
|
||||
if (_Device.SetRenderState(RenderState.DestinationBlend, Blend.InverseSourceAlpha).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set destination blend");
|
||||
}
|
||||
|
||||
if (_Device.SetRenderState(RenderState.SourceBlend, Blend.SourceAlpha).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set source blend");
|
||||
}
|
||||
|
||||
if (_PresentParameters.Multisample != MultisampleType.None)
|
||||
{
|
||||
if (_Device.SetRenderState(RenderState.MultisampleAntialias, true).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set antialiasing");
|
||||
}
|
||||
}
|
||||
|
||||
if (_Device.SetSamplerState(0, SamplerState.MinFilter, TextureFilter.Linear).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set min filter");
|
||||
}
|
||||
|
||||
if (_Device.SetSamplerState(0, SamplerState.MagFilter, TextureFilter.Linear).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set mag filter");
|
||||
}
|
||||
|
||||
if (_Device.SetSamplerState(0, SamplerState.MipFilter, TextureFilter.Linear).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set mip filter");
|
||||
}
|
||||
|
||||
if (_Device.SetSamplerState(0, SamplerState.AddressU, TextureAddress.Clamp).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set clamping on u");
|
||||
}
|
||||
|
||||
if (_Device.SetSamplerState(0, SamplerState.AddressV, TextureAddress.Clamp).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set claming on v");
|
||||
}
|
||||
|
||||
if (_Device.SetTextureStageState(0, TextureStage.AlphaArg1, TextureArgument.Texture).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set alpha argument 1");
|
||||
}
|
||||
|
||||
if (_Device.SetTextureStageState(0, TextureStage.AlphaArg2, TextureArgument.Diffuse).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set alpha argument 2");
|
||||
}
|
||||
|
||||
if (_Device.SetTextureStageState(0, TextureStage.AlphaOperation, TextureOperation.Modulate).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set alpha operation");
|
||||
}
|
||||
|
||||
var indices = new Int16[6];
|
||||
indices[0] = 0;
|
||||
@@ -323,7 +380,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
|
||||
_IndexBuffer = new IndexBuffer(_Device, 6 * sizeof(Int16), Usage.WriteOnly, Pool.Managed, true);
|
||||
|
||||
DataStream stream = _IndexBuffer.Lock(0, 0, LockFlags.Discard);
|
||||
var stream = _IndexBuffer.Lock(0, 0, LockFlags.Discard);
|
||||
stream.WriteRange(indices);
|
||||
_IndexBuffer.Unlock();
|
||||
_Device.Indices = _IndexBuffer;
|
||||
@@ -332,14 +389,19 @@ namespace Vocaluxe.Lib.Draw
|
||||
protected override void _OnBeforeDraw()
|
||||
{
|
||||
if (_Device.BeginScene().IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to begin scene");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void _OnAfterDraw()
|
||||
{
|
||||
_RenderVertexBuffer();
|
||||
if (_Device.EndScene().IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to end scene");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
//Now push the frame to the Viewport
|
||||
@@ -357,6 +419,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
_InitDevice();
|
||||
}
|
||||
}
|
||||
|
||||
Application.DoEvents();
|
||||
}
|
||||
|
||||
@@ -370,23 +433,30 @@ namespace Vocaluxe.Lib.Draw
|
||||
_VertexBuffer.Dispose();
|
||||
_IndexBuffer.Dispose();
|
||||
if (_Device.Reset(_PresentParameters).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to reset the device");
|
||||
}
|
||||
}
|
||||
|
||||
protected override void _AdjustNewBorders()
|
||||
{
|
||||
const float dx = (float)CSettings.RenderW / 2;
|
||||
const float dy = (float)CSettings.RenderH / 2;
|
||||
Matrix translate = Matrix.Translation(new Vector3(-dx, dy, 0));
|
||||
Matrix projection = Matrix.OrthoOffCenterLH(
|
||||
-dx - _BorderLeft, (CSettings.RenderW * CConfig.Config.Graphics.NumScreens) - dx + _BorderRight,
|
||||
var translate = Matrix.Translation(new Vector3(-dx, dy, 0));
|
||||
var projection = Matrix.OrthoOffCenterLH(
|
||||
-dx - _BorderLeft, CSettings.RenderW * CConfig.Config.Graphics.NumScreens - dx + _BorderRight,
|
||||
-dy - _BorderBottom, dy + _BorderTop,
|
||||
CSettings.ZNear, CSettings.ZFar);
|
||||
|
||||
if (_Device.SetTransform(TransformState.Projection, projection).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set orthogonal matrix");
|
||||
}
|
||||
|
||||
if (_Device.SetTransform(TransformState.World, translate).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set translation matrix");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -437,7 +507,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
dc.Wy2 -= 0.5f;
|
||||
|
||||
color.A *= CGraphics.GlobalAlpha;
|
||||
int c = color.AsColor().ToArgb();
|
||||
var c = color.AsColor().ToArgb();
|
||||
int c2;
|
||||
if (isReflection)
|
||||
{
|
||||
@@ -445,7 +515,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
c2 = color.AsColor().ToArgb();
|
||||
}
|
||||
else
|
||||
{
|
||||
c2 = c;
|
||||
}
|
||||
|
||||
var vert = new STexturedColoredVertex[4];
|
||||
vert[0] = new STexturedColoredVertex(new Vector3(dc.Wx1, -dc.Wy1, dc.Wz), new Vector2(dc.Tx1, dc.Ty1), c);
|
||||
@@ -465,7 +537,10 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
//The vertexbuffer is full, so we need to flush it before we can continue
|
||||
if (_Vertices.Count >= CSettings.VertexBufferElements)
|
||||
{
|
||||
_RenderVertexBuffer();
|
||||
}
|
||||
|
||||
_Vertices.Enqueue(vertices[0]);
|
||||
_Vertices.Enqueue(vertices[1]);
|
||||
_Vertices.Enqueue(vertices[2]);
|
||||
@@ -480,25 +555,37 @@ namespace Vocaluxe.Lib.Draw
|
||||
private void _RenderVertexBuffer()
|
||||
{
|
||||
if (_Vertices.Count <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//The vertex buffer locks are slow actions, its better to lock once per frame and write all vertices to the buffer at once
|
||||
DataStream stream = _VertexBuffer.Lock(0, _Vertices.Count * Marshal.SizeOf(typeof(STexturedColoredVertex)), LockFlags.Discard);
|
||||
var stream = _VertexBuffer.Lock(0, _Vertices.Count * Marshal.SizeOf(typeof(STexturedColoredVertex)), LockFlags.Discard);
|
||||
stream.WriteRange(_Vertices.ToArray());
|
||||
_VertexBuffer.Unlock();
|
||||
stream.Dispose();
|
||||
|
||||
for (int i = 0; i < _Vertices.Count; i += 4)
|
||||
for (var i = 0; i < _Vertices.Count; i += 4)
|
||||
{
|
||||
//Apply rotation
|
||||
if (_Device.SetTransform(TransformState.World, _VerticesRotationMatrices.Dequeue()).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set world transformation");
|
||||
}
|
||||
|
||||
//Apply texture
|
||||
if (_Device.SetTexture(0, _VerticesTextures.Dequeue()).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to set texture");
|
||||
}
|
||||
|
||||
//Draw 2 triangles from vertexbuffer
|
||||
if (_Device.DrawIndexedPrimitives(PrimitiveType.TriangleList, i, 0, 4, 0, 2).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to draw quad");
|
||||
}
|
||||
}
|
||||
|
||||
//Clear the queues for the next frame
|
||||
_Vertices.Clear();
|
||||
_VerticesTextures.Clear();
|
||||
@@ -512,7 +599,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
protected override void _ClearScreen()
|
||||
{
|
||||
if (_Device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.Black, 1.0f, 0).IsFailure)
|
||||
{
|
||||
CLog.Error("Failed to clear the backbuffer");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -521,9 +610,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
/// </summary>
|
||||
public CTextureRef CopyScreen()
|
||||
{
|
||||
CD3DTexture tex = _CreateTexture(new Size(_W, _H));
|
||||
Surface backbufferSurface = _Device.GetBackBuffer(0, 0);
|
||||
Surface textureSurface = tex.D3DTexture.GetSurfaceLevel(0);
|
||||
var tex = _CreateTexture(new Size(_W, _H));
|
||||
var backbufferSurface = _Device.GetBackBuffer(0, 0);
|
||||
var textureSurface = tex.D3DTexture.GetSurfaceLevel(0);
|
||||
Surface.FromSurface(textureSurface, backbufferSurface, Filter.Default, 0, new Rectangle(0, 0, _W, _H), new Rectangle(0, 0, _W, _H));
|
||||
backbufferSurface.Dispose();
|
||||
|
||||
@@ -544,8 +633,8 @@ namespace Vocaluxe.Lib.Draw
|
||||
}
|
||||
else
|
||||
{
|
||||
Surface backbufferSurface = _Device.GetBackBuffer(0, 0);
|
||||
Surface textureSurface = texture.D3DTexture.GetSurfaceLevel(0);
|
||||
var backbufferSurface = _Device.GetBackBuffer(0, 0);
|
||||
var textureSurface = texture.D3DTexture.GetSurfaceLevel(0);
|
||||
Surface.FromSurface(textureSurface, backbufferSurface, Filter.Default, 0);
|
||||
backbufferSurface.Dispose();
|
||||
}
|
||||
@@ -556,10 +645,10 @@ namespace Vocaluxe.Lib.Draw
|
||||
/// </summary>
|
||||
public void MakeScreenShot()
|
||||
{
|
||||
string file = CHelper.GetUniqueFileName(Path.Combine(CSettings.DataFolder, CSettings.FolderNameScreenshots), "Screenshot.png");
|
||||
var file = CHelper.GetUniqueFileName(Path.Combine(CSettings.DataFolder, CSettings.FolderNameScreenshots), "Screenshot.png");
|
||||
|
||||
//create a surface of the frame
|
||||
using (Surface surface = _Device.GetBackBuffer(0, 0))
|
||||
using (var surface = _Device.GetBackBuffer(0, 0))
|
||||
{
|
||||
var screen = new Bitmap(Surface.ToStream(surface, ImageFileFormat.Png));
|
||||
screen.Save(file, ImageFormat.Png);
|
||||
@@ -592,49 +681,56 @@ namespace Vocaluxe.Lib.Draw
|
||||
protected override CD3DTexture _CreateTexture(Size dataSize)
|
||||
{
|
||||
if (dataSize.Width < 0)
|
||||
{
|
||||
return new CD3DTexture(null, dataSize);
|
||||
}
|
||||
|
||||
return new CD3DTexture(_Device, dataSize, _CheckForNextPowerOf2(dataSize.Width), _CheckForNextPowerOf2(dataSize.Height));
|
||||
}
|
||||
|
||||
protected override void _WriteDataToTexture(CD3DTexture texture, byte[] data)
|
||||
{
|
||||
//Lock the texture and fill it with the data
|
||||
DataRectangle rect = texture.D3DTexture.LockRectangle(0, LockFlags.Discard);
|
||||
int rowWidth = 4 * texture.DataSize.Width;
|
||||
var rect = texture.D3DTexture.LockRectangle(0, LockFlags.Discard);
|
||||
var rowWidth = 4 * texture.DataSize.Width;
|
||||
if (rowWidth == rect.Pitch)
|
||||
{
|
||||
rect.Data.Write(data, 0, data.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i + rowWidth <= data.Length; i += rowWidth)
|
||||
for (var i = 0; i + rowWidth <= data.Length; i += rowWidth)
|
||||
{
|
||||
rect.Data.Write(data, i, rowWidth);
|
||||
//Go to next row
|
||||
rect.Data.Position = rect.Data.Position - rowWidth + rect.Pitch;
|
||||
}
|
||||
}
|
||||
|
||||
texture.D3DTexture.UnlockRectangle(0);
|
||||
}
|
||||
|
||||
private static Matrix _CalculateRotationMatrix(float rot, float rx1, float rx2, float ry1, float ry2)
|
||||
{
|
||||
Matrix originTranslation = Matrix.Translation(new Vector3(-(float)CSettings.RenderW / 2, (float)CSettings.RenderH / 2, 0));
|
||||
var originTranslation = Matrix.Translation(new Vector3(-(float)CSettings.RenderW / 2, (float)CSettings.RenderH / 2, 0));
|
||||
if (Math.Abs(rot) > float.Epsilon)
|
||||
{
|
||||
float rotation = rot * (float)Math.PI / 180;
|
||||
float centerX = (rx1 + rx2) / 2f;
|
||||
float centerY = -(ry1 + ry2) / 2f;
|
||||
var rotation = rot * (float)Math.PI / 180;
|
||||
var centerX = (rx1 + rx2) / 2f;
|
||||
var centerY = -(ry1 + ry2) / 2f;
|
||||
|
||||
Matrix translationA = Matrix.Translation(-centerX, -centerY, 0);
|
||||
Matrix rotationMat = Matrix.RotationZ(-rotation);
|
||||
Matrix translationB = Matrix.Translation(centerX, centerY, 0);
|
||||
var translationA = Matrix.Translation(-centerX, -centerY, 0);
|
||||
var rotationMat = Matrix.RotationZ(-rotation);
|
||||
var translationB = Matrix.Translation(centerX, centerY, 0);
|
||||
|
||||
//Multiplicate the matrices to get the real world matrix,
|
||||
//First shift the texture into the center
|
||||
//Rotate it and shift it back to the origin position
|
||||
//Apply the originTranslation after
|
||||
Matrix result = translationA * rotationMat * translationB * originTranslation;
|
||||
var result = translationA * rotationMat * translationB * originTranslation;
|
||||
return result;
|
||||
}
|
||||
|
||||
return originTranslation;
|
||||
}
|
||||
|
||||
@@ -642,12 +738,12 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
private static VertexDeclaration _Declaration;
|
||||
private static readonly VertexElement[] _Elements =
|
||||
{
|
||||
new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
|
||||
new VertexElement(0, sizeof(float) * 3, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),
|
||||
new VertexElement(0, sizeof(float) * 3 + sizeof(float) * 2, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0),
|
||||
VertexElement.VertexDeclarationEnd
|
||||
};
|
||||
{
|
||||
new VertexElement(0, 0, DeclarationType.Float3, DeclarationMethod.Default, DeclarationUsage.Position, 0),
|
||||
new VertexElement(0, sizeof(float) * 3, DeclarationType.Float2, DeclarationMethod.Default, DeclarationUsage.TextureCoordinate, 0),
|
||||
new VertexElement(0, sizeof(float) * 3 + sizeof(float) * 2, DeclarationType.Color, DeclarationMethod.Default, DeclarationUsage.Color, 0),
|
||||
VertexElement.VertexDeclarationEnd
|
||||
};
|
||||
|
||||
// ReSharper disable NotAccessedField.Local
|
||||
private Vector3 _Position;
|
||||
@@ -665,7 +761,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
public static VertexDeclaration GetDeclaration(Device device)
|
||||
{
|
||||
if (_Declaration == null || _Declaration.Disposed)
|
||||
{
|
||||
_Declaration = new VertexDeclaration(device, _Elements);
|
||||
}
|
||||
|
||||
return _Declaration;
|
||||
}
|
||||
|
||||
@@ -16,12 +16,12 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using Vocaluxe.Base;
|
||||
using Vocaluxe.Base.Server;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Draw;
|
||||
using System.Diagnostics;
|
||||
using Vocaluxe.Base.Server;
|
||||
|
||||
namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
@@ -70,9 +70,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
_Y = 0;
|
||||
//The windows width is too big
|
||||
int old = _W;
|
||||
var old = _W;
|
||||
_W = (int)Math.Round(_H * CSettings.GetRenderAspect());
|
||||
int diff = old - _W;
|
||||
var diff = old - _W;
|
||||
switch (_CurrentAlignment)
|
||||
{
|
||||
case EGeneralAlignment.Start:
|
||||
@@ -90,9 +90,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
_X = 0;
|
||||
//The windows height is too big
|
||||
int old = _H;
|
||||
var old = _H;
|
||||
_H = (int)Math.Round(_W / CSettings.GetRenderAspect());
|
||||
int diff = old - _H;
|
||||
var diff = old - _H;
|
||||
switch (_CurrentAlignment)
|
||||
{
|
||||
case EGeneralAlignment.Start:
|
||||
@@ -146,13 +146,19 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
drawCoords = new SDrawCoords();
|
||||
if (Math.Abs(rect.W) < 1 || Math.Abs(rect.H) < 1 || Math.Abs(bounds.H) < 1 || Math.Abs(bounds.W) < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bounds.X >= rect.Right || bounds.Right <= rect.X)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (bounds.Y >= rect.Bottom || bounds.Bottom <= rect.Y)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
drawCoords.Tx1 = Math.Max(0, (bounds.X - rect.X) / rect.W * texture.WidthRatio);
|
||||
drawCoords.Wx1 = Math.Max(rect.X, bounds.X);
|
||||
@@ -166,7 +172,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
|
||||
if (mirrored)
|
||||
{
|
||||
float tmp = drawCoords.Ty1;
|
||||
var tmp = drawCoords.Ty1;
|
||||
drawCoords.Ty1 = drawCoords.Ty2;
|
||||
drawCoords.Ty2 = tmp;
|
||||
}
|
||||
@@ -191,9 +197,14 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
drawCoords = new SDrawCoords();
|
||||
if (Math.Abs(rect.W) < 1 || Math.Abs(rect.H) < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (begin >= 1 || begin >= end)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Debug.Assert(begin.IsInRange(0, 1) && end.IsInRange(0, 1));
|
||||
|
||||
@@ -209,7 +220,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
|
||||
if (mirrored)
|
||||
{
|
||||
float tmp = drawCoords.Ty1;
|
||||
var tmp = drawCoords.Ty1;
|
||||
drawCoords.Ty1 = drawCoords.Ty2;
|
||||
drawCoords.Ty2 = tmp;
|
||||
}
|
||||
@@ -223,26 +234,38 @@ namespace Vocaluxe.Lib.Draw
|
||||
public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, bool mirrored = false, bool allMonitors = true)
|
||||
{
|
||||
if (Math.Abs(color.A) < 0.01)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SDrawCoords dc;
|
||||
TTextureType texture;
|
||||
if (!_GetTexture(textureRef, out texture))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (allMonitors)
|
||||
{
|
||||
for (int i = 0; i < CConfig.Config.Graphics.NumScreens; i++)
|
||||
for (var i = 0; i < CConfig.Config.Graphics.NumScreens; i++)
|
||||
{
|
||||
SRectF newrect = rect;
|
||||
var newrect = rect;
|
||||
newrect.X += CSettings.RenderW * i;
|
||||
if (!_CalcDrawCoords(texture, newrect, out dc, mirrored))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_DrawTexture(texture, dc, color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_CalcDrawCoords(texture, rect, out dc, mirrored))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_DrawTexture(texture, dc, color);
|
||||
}
|
||||
}
|
||||
@@ -258,29 +281,40 @@ namespace Vocaluxe.Lib.Draw
|
||||
public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false, bool allMonitors = true)
|
||||
{
|
||||
if (Math.Abs(color.A) < 0.01)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SDrawCoords dc;
|
||||
TTextureType texture;
|
||||
if (!_GetTexture(textureRef, out texture))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (allMonitors)
|
||||
{
|
||||
for (int i = 0; i < CConfig.Config.Graphics.NumScreens; i++)
|
||||
for (var i = 0; i < CConfig.Config.Graphics.NumScreens; i++)
|
||||
{
|
||||
SRectF newrect = rect;
|
||||
SRectF newbounds = bounds;
|
||||
var newrect = rect;
|
||||
var newbounds = bounds;
|
||||
newrect.X += CSettings.RenderW * i;
|
||||
newbounds.X += CSettings.RenderW * i;
|
||||
if (!_CalcDrawCoords(texture, newrect, newbounds, out dc, mirrored))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_DrawTexture(texture, dc, color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_CalcDrawCoords(texture, rect, bounds, out dc, mirrored))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_DrawTexture(texture, dc, color);
|
||||
}
|
||||
}
|
||||
@@ -296,27 +330,38 @@ namespace Vocaluxe.Lib.Draw
|
||||
public void DrawTexture(CTextureRef textureRef, SRectF rect, SColorF color, float begin, float end, bool allMonitors = true)
|
||||
{
|
||||
if (Math.Abs(color.A) < 0.01)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SDrawCoords dc;
|
||||
TTextureType texture;
|
||||
if (!_GetTexture(textureRef, out texture))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (allMonitors)
|
||||
{
|
||||
for (int i = 0; i < CConfig.Config.Graphics.NumScreens; i++)
|
||||
for (var i = 0; i < CConfig.Config.Graphics.NumScreens; i++)
|
||||
{
|
||||
SRectF newrect = rect;
|
||||
var newrect = rect;
|
||||
newrect.X += CSettings.RenderW * i;
|
||||
if (!_CalcDrawCoords(texture, newrect, out dc, false, begin, end))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_DrawTexture(texture, dc, color);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_CalcDrawCoords(texture, rect, out dc, false, begin, end))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_DrawTexture(texture, dc, color);
|
||||
}
|
||||
}
|
||||
@@ -335,11 +380,16 @@ namespace Vocaluxe.Lib.Draw
|
||||
Debug.Assert(height >= 0);
|
||||
|
||||
if (Math.Abs(color.A) < 0.01 || height < 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
SDrawCoords dc;
|
||||
TTextureType texture;
|
||||
if (!_GetTexture(textureRef, out texture))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int loops;
|
||||
if (allMonitors)
|
||||
@@ -351,23 +401,29 @@ namespace Vocaluxe.Lib.Draw
|
||||
loops = 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < loops; i++)
|
||||
for (var i = 0; i < loops; i++)
|
||||
{
|
||||
SRectF newrect = rect;
|
||||
SRectF newbounds = bounds;
|
||||
var newrect = rect;
|
||||
var newbounds = bounds;
|
||||
newrect.X += CSettings.RenderW * i;
|
||||
newbounds.X += CSettings.RenderW * i;
|
||||
if (!_CalcDrawCoords(texture, newrect, newbounds, out dc, true))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (height > newrect.H)
|
||||
{
|
||||
height = newrect.H;
|
||||
}
|
||||
|
||||
dc.Wy1 += newrect.H + space; // Move from start of rect to end of rect with spacing
|
||||
dc.Wy2 += space + height; // Move from end of rect
|
||||
dc.Ty2 += (newrect.H - height) / newrect.H; // Adjust so not all of the start of the texture is drawn (mirrored--> Ty1>Ty2)
|
||||
if (dc.Ty2 < dc.Ty1) // Make sure we actually draw something
|
||||
{
|
||||
_DrawTexture(texture, dc, color, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,9 +440,13 @@ namespace Vocaluxe.Lib.Draw
|
||||
|
||||
_Fullscreen = false;
|
||||
if (CConfig.Config.Graphics.FullScreen == EOffOn.TR_CONFIG_ON)
|
||||
{
|
||||
_EnterFullScreen();
|
||||
}
|
||||
else
|
||||
{
|
||||
_DoResize(); //Resize window if aspect ratio is incorrect
|
||||
}
|
||||
|
||||
while (_Run)
|
||||
{
|
||||
@@ -399,15 +459,22 @@ namespace Vocaluxe.Lib.Draw
|
||||
//Clear the previous Frame
|
||||
_ClearScreen();
|
||||
if (!CGraphics.Draw())
|
||||
{
|
||||
_Run = false;
|
||||
}
|
||||
|
||||
_OnAfterDraw();
|
||||
|
||||
if (!CGraphics.UpdateGameLogic(_Keys, _Mouse))
|
||||
{
|
||||
_Run = false;
|
||||
}
|
||||
|
||||
//Apply fullscreen mode
|
||||
if ((CConfig.Config.Graphics.FullScreen == EOffOn.TR_CONFIG_ON) != _Fullscreen)
|
||||
if (CConfig.Config.Graphics.FullScreen == EOffOn.TR_CONFIG_ON != _Fullscreen)
|
||||
{
|
||||
_ToggleFullScreen();
|
||||
}
|
||||
|
||||
//Apply border changes
|
||||
if (_BorderLeft != CConfig.Config.Graphics.BorderLeft || _BorderRight != CConfig.Config.Graphics.BorderRight || _BorderTop != CConfig.Config.Graphics.BorderTop ||
|
||||
@@ -422,18 +489,23 @@ namespace Vocaluxe.Lib.Draw
|
||||
}
|
||||
|
||||
if (_CurrentAlignment != CConfig.Config.Graphics.ScreenAlignment)
|
||||
{
|
||||
_DoResize();
|
||||
}
|
||||
|
||||
if (CConfig.Config.Graphics.VSync == EOffOn.TR_CONFIG_OFF)
|
||||
{
|
||||
if (CTime.IsRunning())
|
||||
{
|
||||
int delay = (int)Math.Floor(CConfig.CalcCycleTime() - CTime.GetMilliseconds());
|
||||
var delay = (int)Math.Floor(CConfig.CalcCycleTime() - CTime.GetMilliseconds());
|
||||
|
||||
if (delay >= 1 && delay < 500)
|
||||
{
|
||||
Thread.Sleep(delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Calculate the FPS Rate and restart the timer after a frame
|
||||
CTime.CalculateFPS();
|
||||
CTime.Restart();
|
||||
@@ -443,9 +515,13 @@ namespace Vocaluxe.Lib.Draw
|
||||
private void _ToggleFullScreen()
|
||||
{
|
||||
if (!_Fullscreen)
|
||||
{
|
||||
_EnterFullScreen();
|
||||
}
|
||||
else
|
||||
{
|
||||
_LeaveFullScreen();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,14 +52,14 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
_Form.Close();
|
||||
}
|
||||
catch {}
|
||||
catch { }
|
||||
}
|
||||
|
||||
protected void _CenterToScreen()
|
||||
{
|
||||
Screen screen = Screen.FromControl(_Form);
|
||||
var screen = Screen.FromControl(_Form);
|
||||
_Form.Location = new Point((screen.WorkingArea.Width - _Form.Width) / 2,
|
||||
(screen.WorkingArea.Height - _Form.Height) / 2);
|
||||
(screen.WorkingArea.Height - _Form.Height) / 2);
|
||||
}
|
||||
|
||||
private static bool _OnMessageAvoidScreenOff(ref Message m)
|
||||
@@ -76,8 +76,10 @@ namespace Vocaluxe.Lib.Draw
|
||||
case 0xF170: // SC_MONITORPOWER
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -92,7 +94,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
|
||||
_Form.FormBorderStyle = FormBorderStyle.None;
|
||||
|
||||
Screen screen = Screen.FromControl(_Form);
|
||||
var screen = Screen.FromControl(_Form);
|
||||
_Form.DesktopBounds = new Rectangle(screen.Bounds.Location, new Size(screen.Bounds.Width, screen.Bounds.Height));
|
||||
|
||||
if (_Form.WindowState == FormWindowState.Maximized)
|
||||
@@ -102,7 +104,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
_Form.WindowState = FormWindowState.Maximized;
|
||||
}
|
||||
else
|
||||
{
|
||||
_DoResize();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void _LeaveFullScreen()
|
||||
@@ -154,9 +158,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
protected void _OnMouseLeave(object sender, EventArgs e)
|
||||
{
|
||||
_Mouse.Visible = false;
|
||||
#if !WIN && !DEBUG
|
||||
#if !WIN && !DEBUG
|
||||
_Form.Cursor = Cursors.Default;
|
||||
#endif
|
||||
#endif
|
||||
Cursor.Show();
|
||||
}
|
||||
|
||||
@@ -164,9 +168,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
Cursor.Hide();
|
||||
_Mouse.Visible = true;
|
||||
#if !WIN && !DEBUG //don't want to be stuck without a cursor when debugging
|
||||
#if !WIN && !DEBUG //don't want to be stuck without a cursor when debugging
|
||||
_Form.Cursor = new Cursor("Linux/blank.cur"); //Cursor.Hide() doesn't work in Mono
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -191,13 +195,15 @@ namespace Vocaluxe.Lib.Draw
|
||||
_Keys.KeyUp(e);
|
||||
}
|
||||
#endregion keyboard event handlers
|
||||
|
||||
#endregion
|
||||
|
||||
public override bool Init()
|
||||
{
|
||||
if (!base.Init())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_Form.Icon = new Icon(Path.Combine(CSettings.ProgramFolder, CSettings.FileNameIcon));
|
||||
_Form.Text = CSettings.GetFullVersionText();
|
||||
((IFormHook)_Form).OnMessage = _OnMessageAvoidScreenOff;
|
||||
|
||||
@@ -87,11 +87,11 @@ namespace Vocaluxe.Lib.Draw
|
||||
|
||||
private void _DrawBuffer()
|
||||
{
|
||||
Graphics frontBuffer = Graphics.FromHwnd(Handle);
|
||||
int h = ClientSize.Height;
|
||||
int w = ClientSize.Width;
|
||||
int y = 0;
|
||||
int x = 0;
|
||||
var frontBuffer = Graphics.FromHwnd(Handle);
|
||||
var h = ClientSize.Height;
|
||||
var w = ClientSize.Width;
|
||||
var y = 0;
|
||||
var x = 0;
|
||||
|
||||
if (ClientSize.Width / (float)ClientSize.Height > CSettings.GetRenderAspect())
|
||||
{
|
||||
@@ -111,9 +111,13 @@ namespace Vocaluxe.Lib.Draw
|
||||
private void _ToggleFullScreen()
|
||||
{
|
||||
if (!_Fullscreen)
|
||||
{
|
||||
_Maximize(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
_Restore(this);
|
||||
}
|
||||
}
|
||||
|
||||
private void _Maximize(Form targetForm)
|
||||
@@ -146,7 +150,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
|
||||
private void _OnResizeEvent(object sender, EventArgs e)
|
||||
{
|
||||
Graphics frontBuffer = Graphics.FromHwnd(Handle);
|
||||
var frontBuffer = Graphics.FromHwnd(Handle);
|
||||
frontBuffer.Clear(Color.Black);
|
||||
}
|
||||
|
||||
@@ -172,6 +176,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
base.WndProc(ref m);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
base.WndProc(ref m);
|
||||
@@ -220,11 +225,13 @@ namespace Vocaluxe.Lib.Draw
|
||||
public void MainLoop()
|
||||
{
|
||||
_Run = true;
|
||||
int delay = 0;
|
||||
var delay = 0;
|
||||
Show();
|
||||
|
||||
if (CConfig.Config.Graphics.FullScreen == EOffOn.TR_CONFIG_ON)
|
||||
{
|
||||
_Maximize(this);
|
||||
}
|
||||
|
||||
while (_Run)
|
||||
{
|
||||
@@ -237,19 +244,26 @@ namespace Vocaluxe.Lib.Draw
|
||||
_Run = CGraphics.UpdateGameLogic(_Keys, _Mouse);
|
||||
_FlipBuffer();
|
||||
|
||||
if ((CConfig.Config.Graphics.FullScreen == EOffOn.TR_CONFIG_ON) != _Fullscreen)
|
||||
if (CConfig.Config.Graphics.FullScreen == EOffOn.TR_CONFIG_ON != _Fullscreen)
|
||||
{
|
||||
_ToggleFullScreen();
|
||||
}
|
||||
|
||||
if (CTime.IsRunning())
|
||||
{
|
||||
delay = (int)Math.Floor(CConfig.CalcCycleTime() - CTime.GetMilliseconds());
|
||||
}
|
||||
|
||||
if (delay >= 1)
|
||||
{
|
||||
Thread.Sleep(delay);
|
||||
}
|
||||
|
||||
CTime.CalculateFPS();
|
||||
CTime.Restart();
|
||||
}
|
||||
}
|
||||
|
||||
Close();
|
||||
}
|
||||
|
||||
@@ -260,6 +274,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
base.Close();
|
||||
}
|
||||
catch { }
|
||||
|
||||
Dispose();
|
||||
}
|
||||
|
||||
@@ -282,10 +297,10 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
var bmp = new Bitmap(_Backbuffer);
|
||||
_Bitmaps.Add(bmp);
|
||||
CTextureRef texture = _GetNewTexture(bmp.GetSize());
|
||||
var texture = _GetNewTexture(bmp.GetSize());
|
||||
|
||||
// Add to Texture List
|
||||
_Textures[texture.ID] = texture;
|
||||
_Textures[texture.Id] = texture;
|
||||
|
||||
return texture;
|
||||
}
|
||||
@@ -298,12 +313,14 @@ namespace Vocaluxe.Lib.Draw
|
||||
texture = CopyScreen();
|
||||
}
|
||||
else
|
||||
_Bitmaps[texture.ID] = new Bitmap(_Backbuffer);
|
||||
{
|
||||
_Bitmaps[texture.Id] = new Bitmap(_Backbuffer);
|
||||
}
|
||||
}
|
||||
|
||||
public void MakeScreenShot()
|
||||
{
|
||||
string file = CHelper.GetUniqueFileName(Path.Combine(CSettings.DataFolder, CSettings.FolderNameScreenshots), "Screenshot.png");
|
||||
var file = CHelper.GetUniqueFileName(Path.Combine(CSettings.DataFolder, CSettings.FolderNameScreenshots), "Screenshot.png");
|
||||
|
||||
_Backbuffer.Save(file, ImageFormat.Png);
|
||||
}
|
||||
@@ -316,10 +333,10 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
var bmp2 = new Bitmap(bmp);
|
||||
_Bitmaps.Add(bmp2);
|
||||
CTextureRef texture = _GetNewTexture(bmp.GetSize());
|
||||
var texture = _GetNewTexture(bmp.GetSize());
|
||||
|
||||
// Add to Texture List
|
||||
_Textures[texture.ID] = texture;
|
||||
_Textures[texture.Id] = texture;
|
||||
|
||||
return texture;
|
||||
}
|
||||
@@ -335,12 +352,16 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
CTextureRef texture;
|
||||
if (_TextureCache.TryGetValue(texturePath, out texture))
|
||||
{
|
||||
return texture;
|
||||
}
|
||||
|
||||
using (var bmp = new Bitmap(texturePath))
|
||||
{
|
||||
texture = AddTexture(bmp);
|
||||
_TextureCache.Add(texturePath, texture);
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
@@ -349,13 +370,16 @@ namespace Vocaluxe.Lib.Draw
|
||||
|
||||
private bool _TextureExists(CTextureRef texture)
|
||||
{
|
||||
return texture != null && _Textures.ContainsKey(texture.ID);
|
||||
return texture != null && _Textures.ContainsKey(texture.Id);
|
||||
}
|
||||
|
||||
public CTextureRef CopyTexture(CTextureRef textureRef)
|
||||
{
|
||||
if (_TextureExists(textureRef))
|
||||
return AddTexture(_Bitmaps[textureRef.ID]);
|
||||
{
|
||||
return AddTexture(_Bitmaps[textureRef.Id]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -363,10 +387,11 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
if (_TextureExists(texture))
|
||||
{
|
||||
_Bitmaps[texture.ID].Dispose();
|
||||
_Textures.Remove(texture.ID);
|
||||
_Bitmaps[texture.Id].Dispose();
|
||||
_Textures.Remove(texture.Id);
|
||||
texture.SetRemoved();
|
||||
}
|
||||
|
||||
texture = null;
|
||||
}
|
||||
|
||||
@@ -394,7 +419,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
using (var bmp = new Bitmap(w, h))
|
||||
{
|
||||
BitmapData bmpData = bmp.LockBits(bmp.GetRect(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
||||
var bmpData = bmp.LockBits(bmp.GetRect(), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
||||
Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
|
||||
bmp.UnlockBits(bmpData);
|
||||
return AddTexture(bmp);
|
||||
@@ -405,30 +430,37 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
if (_TextureExists(texture))
|
||||
{
|
||||
BitmapData bmpData = _Bitmaps[texture.ID].LockBits(new Rectangle(0, 0, _Bitmaps[texture.ID].Width, _Bitmaps[texture.ID].Height),
|
||||
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
||||
var bmpData = _Bitmaps[texture.Id].LockBits(new Rectangle(0, 0, _Bitmaps[texture.Id].Width, _Bitmaps[texture.Id].Height),
|
||||
ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
|
||||
Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
|
||||
_Bitmaps[texture.ID].UnlockBits(bmpData);
|
||||
_Bitmaps[texture.Id].UnlockBits(bmpData);
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateTexture(CTextureRef textureRef, Bitmap bmp)
|
||||
{
|
||||
if (_TextureExists(textureRef))
|
||||
_Bitmaps[textureRef.ID] = bmp;
|
||||
{
|
||||
_Bitmaps[textureRef.Id] = bmp;
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, bool mirrored = false, bool allMonitors = true)
|
||||
{
|
||||
if (texture != null)
|
||||
{
|
||||
DrawTexture(texture, rect, color, rect, mirrored);
|
||||
}
|
||||
}
|
||||
|
||||
public void DrawTexture(CTextureRef texture, SRectF rect, SColorF color, SRectF bounds, bool mirrored = false, bool allMonitors = true)
|
||||
{
|
||||
if (!_TextureExists(texture))
|
||||
{
|
||||
return;
|
||||
Bitmap coloredBitmap = _ColorizeBitmap(_Bitmaps[texture.ID], color);
|
||||
}
|
||||
|
||||
var coloredBitmap = _ColorizeBitmap(_Bitmaps[texture.Id], color);
|
||||
_G.DrawImage(coloredBitmap, new RectangleF(rect.X, rect.Y, rect.W, rect.H));
|
||||
coloredBitmap.Dispose();
|
||||
}
|
||||
@@ -446,7 +478,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
var newBitmap = new Bitmap(original.Width, original.Height);
|
||||
|
||||
using (Graphics g = Graphics.FromImage(newBitmap))
|
||||
using (var g = Graphics.FromImage(newBitmap))
|
||||
{
|
||||
var cm = new ColorMatrix { Matrix33 = color.A, Matrix00 = color.R, Matrix11 = color.G, Matrix22 = color.B, Matrix44 = 1 };
|
||||
|
||||
@@ -455,7 +487,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
ia.SetColorMatrix(cm);
|
||||
|
||||
g.DrawImage(original, new Rectangle(0, 0, original.Width, original.Height),
|
||||
0, 0, original.Width, original.Height, GraphicsUnit.Pixel, ia);
|
||||
0, 0, original.Width, original.Height, GraphicsUnit.Pixel, ia);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,19 +15,18 @@
|
||||
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
using System.Diagnostics;
|
||||
using System.Drawing.Imaging;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Windows.Forms;
|
||||
using OpenTK;
|
||||
using OpenTK.Graphics;
|
||||
using OpenTK.Graphics.OpenGL;
|
||||
using Vocaluxe.Base;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Draw;
|
||||
using BeginMode = OpenTK.Graphics.OpenGL.BeginMode;
|
||||
using BlendingFactorDest = OpenTK.Graphics.OpenGL.BlendingFactorDest;
|
||||
using BlendingFactorSrc = OpenTK.Graphics.OpenGL.BlendingFactorSrc;
|
||||
using ClearBufferMask = OpenTK.Graphics.OpenGL.ClearBufferMask;
|
||||
@@ -54,7 +53,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
protected override void WndProc(ref Message m)
|
||||
{
|
||||
if (OnMessage == null || OnMessage(ref m))
|
||||
{
|
||||
base.WndProc(ref m);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +68,10 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
Name = name;
|
||||
if (name == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GL.BindTexture(TextureTarget.Texture2D, Name);
|
||||
|
||||
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, texWidth, texHeight, 0, PixelFormat.Bgra, PixelType.UnsignedByte, IntPtr.Zero);
|
||||
@@ -89,7 +93,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
base.Dispose();
|
||||
if (Name != 0)
|
||||
{
|
||||
GL.DeleteTexture(Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,7 +112,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
//Check AA Mode
|
||||
CConfig.Config.Graphics.AAMode = (EAntiAliasingModes)_CheckAntiAliasingMode((int)CConfig.Config.Graphics.AAMode);
|
||||
|
||||
bool ok = false;
|
||||
var ok = false;
|
||||
try
|
||||
{
|
||||
#if WIN
|
||||
@@ -116,7 +122,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
#endif
|
||||
_Control = new GLControl(gm, 2, 1, GraphicsContextFlags.Default);
|
||||
if (_Control.GraphicsMode != null)
|
||||
{
|
||||
ok = true;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -124,7 +132,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
_Control = new GLControl();
|
||||
}
|
||||
|
||||
_Control.MakeCurrent();
|
||||
_Control.VSync = CConfig.Config.Graphics.VSync == EOffOn.TR_CONFIG_ON;
|
||||
@@ -149,10 +159,12 @@ namespace Vocaluxe.Lib.Draw
|
||||
|
||||
private static int _CheckAntiAliasingMode(int setValue)
|
||||
{
|
||||
int samples = 0;
|
||||
var samples = 0;
|
||||
|
||||
if (setValue > 32)
|
||||
{
|
||||
setValue = 32;
|
||||
}
|
||||
|
||||
while (samples <= setValue)
|
||||
{
|
||||
@@ -167,15 +179,25 @@ namespace Vocaluxe.Lib.Draw
|
||||
}
|
||||
|
||||
if (mode.Samples != samples)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (samples == 0)
|
||||
{
|
||||
samples = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
samples *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (samples == 2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return samples / 2;
|
||||
}
|
||||
|
||||
@@ -231,7 +253,9 @@ namespace Vocaluxe.Lib.Draw
|
||||
public override bool Init()
|
||||
{
|
||||
if (!base.Init())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Init Texturing
|
||||
GL.Enable(EnableCap.Texture2D);
|
||||
@@ -285,20 +309,21 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
GL.MatrixMode(MatrixMode.Projection);
|
||||
GL.LoadIdentity();
|
||||
GL.Ortho(-CConfig.Config.Graphics.BorderLeft, CConfig.Config.Graphics.BorderRight + CSettings.RenderW * CConfig.Config.Graphics.NumScreens, CConfig.Config.Graphics.BorderBottom + CSettings.RenderH,
|
||||
-CConfig.Config.Graphics.BorderTop, CSettings.ZNear, CSettings.ZFar);
|
||||
GL.Ortho(-CConfig.Config.Graphics.BorderLeft, CConfig.Config.Graphics.BorderRight + CSettings.RenderW * CConfig.Config.Graphics.NumScreens,
|
||||
CConfig.Config.Graphics.BorderBottom + CSettings.RenderH,
|
||||
-CConfig.Config.Graphics.BorderTop, CSettings.ZNear, CSettings.ZFar);
|
||||
}
|
||||
|
||||
public void MakeScreenShot()
|
||||
{
|
||||
string file = CHelper.GetUniqueFileName(Path.Combine(CSettings.DataFolder, CSettings.FolderNameScreenshots), "Screenshot.png");
|
||||
var file = CHelper.GetUniqueFileName(Path.Combine(CSettings.DataFolder, CSettings.FolderNameScreenshots), "Screenshot.png");
|
||||
|
||||
int width = GetScreenWidth();
|
||||
int height = GetScreenHeight();
|
||||
var width = GetScreenWidth();
|
||||
var height = GetScreenHeight();
|
||||
|
||||
using (var screen = new Bitmap(width, height))
|
||||
{
|
||||
BitmapData bmpData = screen.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
var bmpData = screen.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
|
||||
|
||||
GL.ReadPixels(0, 0, width, height, PixelFormat.Bgra, PixelType.UnsignedByte, bmpData.Scan0);
|
||||
screen.UnlockBits(bmpData);
|
||||
@@ -311,8 +336,8 @@ namespace Vocaluxe.Lib.Draw
|
||||
public CTextureRef CopyScreen()
|
||||
{
|
||||
//TODO: Check if _W,_H needs to be used or not
|
||||
Size size = new Size(GetScreenWidth(), GetScreenHeight());
|
||||
COGLTexture texture = _CreateTexture(size);
|
||||
var size = new Size(GetScreenWidth(), GetScreenHeight());
|
||||
var texture = _CreateTexture(size);
|
||||
|
||||
GL.BindTexture(TextureTarget.Texture2D, texture.Name);
|
||||
GL.CopyTexSubImage2D(TextureTarget.Texture2D, 0, 0, 0, 0, 0, size.Width, size.Height); //TODO: Use _X,_Y and _W,_H?
|
||||
@@ -340,12 +365,15 @@ namespace Vocaluxe.Lib.Draw
|
||||
|
||||
public void DrawRect(SColorF color, SRectF rect, bool allMonitors = true)
|
||||
{
|
||||
int loops = 1;
|
||||
var loops = 1;
|
||||
if (allMonitors)
|
||||
loops = CConfig.Config.Graphics.NumScreens;
|
||||
for (int i = 0; i < loops; i++)
|
||||
{
|
||||
SRectF newrect = rect;
|
||||
loops = CConfig.Config.Graphics.NumScreens;
|
||||
}
|
||||
|
||||
for (var i = 0; i < loops; i++)
|
||||
{
|
||||
var newrect = rect;
|
||||
newrect.X += CSettings.RenderW * i;
|
||||
|
||||
GL.Enable(EnableCap.Blend);
|
||||
@@ -360,6 +388,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
GL.Rotate(-newrect.Rotation, 0f, 0f, 1f);
|
||||
GL.Translate(-0.5f, -0.5f, 0);
|
||||
}
|
||||
|
||||
GL.Vertex3(newrect.X, newrect.Y, newrect.Z + CGraphics.ZOffset);
|
||||
GL.Vertex3(newrect.X, newrect.Y + newrect.H, newrect.Z + CGraphics.ZOffset);
|
||||
GL.Vertex3(newrect.X + newrect.W, newrect.Y + newrect.H, newrect.Z + CGraphics.ZOffset);
|
||||
@@ -373,24 +402,34 @@ namespace Vocaluxe.Lib.Draw
|
||||
public void DrawRectReflection(SColorF color, SRectF rect, float space, float height)
|
||||
{
|
||||
if (rect.H < height)
|
||||
{
|
||||
height = rect.H;
|
||||
}
|
||||
|
||||
float rx1 = rect.X;
|
||||
float rx2 = rect.X + rect.W;
|
||||
float ry1 = rect.Y + rect.H + space;
|
||||
float ry2 = rect.Y + rect.H + space + height;
|
||||
var rx1 = rect.X;
|
||||
var rx2 = rect.X + rect.W;
|
||||
var ry1 = rect.Y + rect.H + space;
|
||||
var ry2 = rect.Y + rect.H + space + height;
|
||||
|
||||
if (rx1 < rect.X)
|
||||
{
|
||||
rx1 = rect.X;
|
||||
}
|
||||
|
||||
if (rx2 > rect.X + rect.W)
|
||||
{
|
||||
rx2 = rect.X + rect.W;
|
||||
}
|
||||
|
||||
if (ry1 < rect.Y + space)
|
||||
{
|
||||
ry1 = rect.Y + space;
|
||||
}
|
||||
|
||||
if (ry2 > rect.Y + rect.H + space + height)
|
||||
{
|
||||
ry2 = rect.Y + rect.H + space + height;
|
||||
}
|
||||
|
||||
|
||||
GL.Enable(EnableCap.Blend);
|
||||
@@ -423,8 +462,11 @@ namespace Vocaluxe.Lib.Draw
|
||||
protected override COGLTexture _CreateTexture(Size dataSize)
|
||||
{
|
||||
if (dataSize.Width < 0)
|
||||
{
|
||||
return new COGLTexture(0, dataSize);
|
||||
COGLTexture texture = new COGLTexture(GL.GenTexture(), dataSize, _CheckForNextPowerOf2(dataSize.Width), _CheckForNextPowerOf2(dataSize.Height));
|
||||
}
|
||||
|
||||
var texture = new COGLTexture(GL.GenTexture(), dataSize, _CheckForNextPowerOf2(dataSize.Width), _CheckForNextPowerOf2(dataSize.Height));
|
||||
|
||||
return texture;
|
||||
}
|
||||
@@ -432,10 +474,13 @@ namespace Vocaluxe.Lib.Draw
|
||||
private void _ClearTexture(COGLTexture texture)
|
||||
{
|
||||
if (texture.DataSize.Equals(texture.Size))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
GL.BindFramebuffer(OpenTK.Graphics.OpenGL.FramebufferTarget.Framebuffer, _FBO);
|
||||
GL.FramebufferTexture2D(OpenTK.Graphics.OpenGL.FramebufferTarget.Framebuffer, OpenTK.Graphics.OpenGL.FramebufferAttachment.ColorAttachment0, TextureTarget.Texture2D,
|
||||
texture.Name, 0);
|
||||
texture.Name, 0);
|
||||
GL.ClearColor(Color.FromArgb(0));
|
||||
GL.Clear(ClearBufferMask.ColorBufferBit);
|
||||
GL.ClearColor(Color.Black);
|
||||
@@ -495,7 +540,10 @@ namespace Vocaluxe.Lib.Draw
|
||||
GL.Vertex3(dc.Wx1, dc.Wy1, dc.Wz);
|
||||
|
||||
if (isReflection)
|
||||
{
|
||||
GL.Color4(color.R, color.G, color.B, 0);
|
||||
}
|
||||
|
||||
GL.TexCoord2(dc.Tx1, dc.Ty2);
|
||||
GL.Vertex3(dc.Wx1, dc.Wy2, dc.Wz);
|
||||
|
||||
@@ -503,7 +551,10 @@ namespace Vocaluxe.Lib.Draw
|
||||
GL.Vertex3(dc.Wx2, dc.Wy2, dc.Wz);
|
||||
|
||||
if (isReflection)
|
||||
{
|
||||
GL.Color4(color.R, color.G, color.B, color.A * CGraphics.GlobalAlpha);
|
||||
}
|
||||
|
||||
GL.TexCoord2(dc.Tx2, dc.Ty1);
|
||||
GL.Vertex3(dc.Wx2, dc.Wy1, dc.Wz);
|
||||
|
||||
|
||||
@@ -74,13 +74,22 @@ namespace Vocaluxe.Lib.Draw
|
||||
private void _CalcRatios()
|
||||
{
|
||||
if (_DataSize.Width == Size.Width)
|
||||
{
|
||||
WidthRatio = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
WidthRatio = (float)_DataSize.Width / Size.Width;
|
||||
}
|
||||
|
||||
if (_DataSize.Height == Size.Height)
|
||||
{
|
||||
HeightRatio = 1f;
|
||||
}
|
||||
else
|
||||
{
|
||||
HeightRatio = (float)_DataSize.Height / Size.Height;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _IsDisposed;
|
||||
@@ -88,7 +97,10 @@ namespace Vocaluxe.Lib.Draw
|
||||
public virtual void Dispose()
|
||||
{
|
||||
if (_IsDisposed)
|
||||
{
|
||||
throw new ObjectDisposedException(GetType().Name);
|
||||
}
|
||||
|
||||
RefCount = 0;
|
||||
_IsDisposed = true;
|
||||
}
|
||||
|
||||
@@ -98,10 +98,10 @@ namespace Vocaluxe.Lib.Draw
|
||||
|
||||
protected bool _NonPowerOf2TextureSupported;
|
||||
|
||||
private int _NextID;
|
||||
private readonly Object _MutexID = new object();
|
||||
private int _NextId;
|
||||
private readonly Object _MutexId = new object();
|
||||
|
||||
// Maps texture IDs to textures. Multiple IDs can be mapped to one texture (-->texture.RefCount>1)
|
||||
// Maps texture Ids to textures. Multiple Ids can be mapped to one texture (-->texture.RefCount>1)
|
||||
private readonly Dictionary<int, TTextureType> _Textures = new Dictionary<int, TTextureType>();
|
||||
// Maps texturePaths to textures. Texture may have already been disposed (RefCount<=0)
|
||||
private readonly Dictionary<string, STextureCacheEntry> _TextureCache = new Dictionary<string, STextureCacheEntry>();
|
||||
@@ -109,11 +109,11 @@ namespace Vocaluxe.Lib.Draw
|
||||
private readonly Dictionary<string, Task<Size>> _BitmapsLoading = new Dictionary<string, Task<Size>>();
|
||||
private int _TextureCount;
|
||||
|
||||
private int _MainThreadID;
|
||||
private int _MainThreadId;
|
||||
|
||||
public virtual bool Init()
|
||||
{
|
||||
_MainThreadID = Thread.CurrentThread.ManagedThreadId;
|
||||
_MainThreadId = Thread.CurrentThread.ManagedThreadId;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -123,11 +123,14 @@ namespace Vocaluxe.Lib.Draw
|
||||
lock (_Textures)
|
||||
{
|
||||
//Dispose all textures
|
||||
foreach (TTextureType texture in _Textures.Values)
|
||||
foreach (var texture in _Textures.Values)
|
||||
{
|
||||
if (texture != null && --texture.RefCount <= 0)
|
||||
{
|
||||
texture.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
_Textures.Clear();
|
||||
_TextureCache.Clear();
|
||||
}
|
||||
@@ -138,7 +141,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
/// </summary>
|
||||
protected void _EnsureMainThread()
|
||||
{
|
||||
Debug.Assert(_MainThreadID == Thread.CurrentThread.ManagedThreadId);
|
||||
Debug.Assert(_MainThreadId == Thread.CurrentThread.ManagedThreadId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -149,9 +152,15 @@ namespace Vocaluxe.Lib.Draw
|
||||
protected int _CheckForNextPowerOf2(int n)
|
||||
{
|
||||
if (_NonPowerOf2TextureSupported)
|
||||
{
|
||||
return n;
|
||||
}
|
||||
|
||||
if (n < 0)
|
||||
{
|
||||
throw new ArgumentOutOfRangeException("n", "Must be positive.");
|
||||
}
|
||||
|
||||
return (int)Math.Pow(2, Math.Ceiling(Math.Log(n, 2)));
|
||||
}
|
||||
|
||||
@@ -185,8 +194,8 @@ namespace Vocaluxe.Lib.Draw
|
||||
/// <returns></returns>
|
||||
private static bool _RequiresResize(Size size)
|
||||
{
|
||||
int maxArea = _GetMaxTextureArea();
|
||||
int curArea = size.Width * size.Height;
|
||||
var maxArea = _GetMaxTextureArea();
|
||||
var curArea = size.Width * size.Height;
|
||||
return curArea > maxArea;
|
||||
}
|
||||
|
||||
@@ -197,13 +206,16 @@ namespace Vocaluxe.Lib.Draw
|
||||
private Size _GetNewTextureSize(Size size)
|
||||
{
|
||||
Debug.Assert(size.Width > 0 && size.Height > 0);
|
||||
int maxArea = _GetMaxTextureArea();
|
||||
int curArea = size.Width * size.Height;
|
||||
var maxArea = _GetMaxTextureArea();
|
||||
var curArea = size.Width * size.Height;
|
||||
if (curArea <= maxArea)
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
Debug.Assert(_RequiresResize(size));
|
||||
double factor = Math.Sqrt((double)maxArea / curArea);
|
||||
Size newSize = new Size((int)(size.Width * factor), (int)(size.Height * factor));
|
||||
var factor = Math.Sqrt((double)maxArea / curArea);
|
||||
var newSize = new Size((int)(size.Width * factor), (int)(size.Height * factor));
|
||||
if (!_NonPowerOf2TextureSupported)
|
||||
{
|
||||
if (size.Width < size.Height)
|
||||
@@ -211,16 +223,21 @@ namespace Vocaluxe.Lib.Draw
|
||||
newSize.Width = _CheckForNextPowerOf2(newSize.Width);
|
||||
newSize.Height = _CheckForNextPowerOf2(maxArea / newSize.Width);
|
||||
if (newSize.Width * newSize.Height > maxArea)
|
||||
{
|
||||
newSize.Height /= 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
newSize.Height = _CheckForNextPowerOf2(newSize.Height);
|
||||
newSize.Width = _CheckForNextPowerOf2(maxArea / newSize.Height);
|
||||
if (newSize.Width * newSize.Height > maxArea)
|
||||
{
|
||||
newSize.Width /= 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Assert(newSize.Width * newSize.Height <= maxArea);
|
||||
return newSize;
|
||||
}
|
||||
@@ -229,7 +246,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
|
||||
protected virtual void _WriteDataToTexture(TTextureType texture, IntPtr data)
|
||||
{
|
||||
byte[] dataArray = new byte[4 * texture.DataSize.Width * texture.DataSize.Height];
|
||||
var dataArray = new byte[4 * texture.DataSize.Width * texture.DataSize.Height];
|
||||
Marshal.Copy(data, dataArray, 0, dataArray.Length);
|
||||
_WriteDataToTexture(texture, dataArray);
|
||||
}
|
||||
@@ -250,7 +267,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
/// <returns></returns>
|
||||
private TTextureType _CreateAndFillTexture(Size dataSize, byte[] data)
|
||||
{
|
||||
TTextureType texture = _CreateTexture(dataSize);
|
||||
var texture = _CreateTexture(dataSize);
|
||||
_WriteDataToTexture(texture, data);
|
||||
return texture;
|
||||
}
|
||||
@@ -266,7 +283,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
Bitmap bmp2 = null;
|
||||
try
|
||||
{
|
||||
Size size = _GetNewTextureSize(bmp.GetSize());
|
||||
var size = _GetNewTextureSize(bmp.GetSize());
|
||||
if (!size.Equals(bmp.GetSize()))
|
||||
{
|
||||
bmp2 = bmp.Resize(size);
|
||||
@@ -274,18 +291,25 @@ namespace Vocaluxe.Lib.Draw
|
||||
}
|
||||
|
||||
//Fill the new Bitmap with the texture data
|
||||
BitmapData bmpData = bmp.LockBits(bmp.GetRect(), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||||
var bmpData = bmp.LockBits(bmp.GetRect(), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||||
if (texture == null)
|
||||
{
|
||||
texture = _CreateTexture(size);
|
||||
}
|
||||
else
|
||||
{
|
||||
texture.DataSize = size;
|
||||
}
|
||||
|
||||
_WriteDataToTexture(texture, bmpData.Scan0);
|
||||
bmp.UnlockBits(bmpData);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (bmp2 != null)
|
||||
{
|
||||
bmp2.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,14 +323,17 @@ namespace Vocaluxe.Lib.Draw
|
||||
/// <param name="texturePath"></param>
|
||||
private void _AddToCache(TTextureType texture, Size origSize, string texturePath)
|
||||
{
|
||||
if (String.IsNullOrEmpty(texturePath))
|
||||
if (string.IsNullOrEmpty(texturePath))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Assert(texture != null);
|
||||
lock (_Textures)
|
||||
{
|
||||
Debug.Assert(!_TextureCache.ContainsKey(texturePath));
|
||||
texture.TexturePath = texturePath;
|
||||
STextureCacheEntry cacheEntry = new STextureCacheEntry {OrigSize = origSize, Texture = texture};
|
||||
var cacheEntry = new STextureCacheEntry { OrigSize = origSize, Texture = texture };
|
||||
_TextureCache.Add(texturePath, cacheEntry);
|
||||
}
|
||||
}
|
||||
@@ -321,29 +348,36 @@ namespace Vocaluxe.Lib.Draw
|
||||
private CTextureRef _GetFromCache(string texturePath, out Task<Size> loader)
|
||||
{
|
||||
loader = null;
|
||||
if (String.IsNullOrEmpty(texturePath))
|
||||
if (string.IsNullOrEmpty(texturePath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
lock (_TextureCache)
|
||||
lock (_Textures)
|
||||
lock (_Textures)
|
||||
{
|
||||
STextureCacheEntry cacheEntry;
|
||||
if (_TextureCache.TryGetValue(texturePath, out cacheEntry))
|
||||
{
|
||||
STextureCacheEntry cacheEntry;
|
||||
if (_TextureCache.TryGetValue(texturePath, out cacheEntry))
|
||||
if (cacheEntry.Texture.RefCount <= 0)
|
||||
{
|
||||
if (cacheEntry.Texture.RefCount <= 0)
|
||||
_TextureCache.Remove(texturePath);
|
||||
else
|
||||
_TextureCache.Remove(texturePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cacheEntry.OrigSize.Width < 0)
|
||||
{
|
||||
if (cacheEntry.OrigSize.Width < 0)
|
||||
lock (_BitmapsLoading)
|
||||
{
|
||||
lock (_BitmapsLoading)
|
||||
{
|
||||
loader = _BitmapsLoading[texturePath];
|
||||
}
|
||||
loader = _BitmapsLoading[texturePath];
|
||||
}
|
||||
return _GetTextureReference(cacheEntry.OrigSize, cacheEntry.Texture);
|
||||
}
|
||||
|
||||
return _GetTextureReference(cacheEntry.OrigSize, cacheEntry.Texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -360,18 +394,23 @@ namespace Vocaluxe.Lib.Draw
|
||||
Debug.Assert(origSize.Width > 0 && origSize.Height > 0 || origSize.Width == -1 && origSize.Height == -1);
|
||||
Debug.Assert(texture != null);
|
||||
int id;
|
||||
lock (_MutexID)
|
||||
lock (_MutexId)
|
||||
{
|
||||
id = _NextID++;
|
||||
id = _NextId++;
|
||||
}
|
||||
CTextureRef textureRef = new CTextureRef(id, origSize);
|
||||
|
||||
var textureRef = new CTextureRef(id, origSize);
|
||||
lock (_Textures)
|
||||
{
|
||||
if (texture.RefCount == 0)
|
||||
{
|
||||
_TextureCount++;
|
||||
}
|
||||
|
||||
texture.RefCount++;
|
||||
_Textures.Add(id, texture);
|
||||
}
|
||||
|
||||
return textureRef;
|
||||
}
|
||||
|
||||
@@ -392,14 +431,23 @@ namespace Vocaluxe.Lib.Draw
|
||||
private static bool _IsTextureUsable(TTextureType texture, Size dataSize)
|
||||
{
|
||||
if (texture == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!texture.DataSize.Equals(dataSize))
|
||||
{
|
||||
if (texture.Size.Width < dataSize.Width || texture.Size.Height < dataSize.Height)
|
||||
{
|
||||
return false; // Texture memory to small
|
||||
}
|
||||
|
||||
if (texture.Size.Width * 0.9 > dataSize.Width || texture.Size.Height * 0.9 > dataSize.Height)
|
||||
{
|
||||
return false; // Texture memory to big
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -410,9 +458,10 @@ namespace Vocaluxe.Lib.Draw
|
||||
texture = null;
|
||||
return false;
|
||||
}
|
||||
|
||||
lock (_Textures)
|
||||
{
|
||||
return _Textures.TryGetValue(textureRef.ID, out texture) && (!checkDrawable || texture.IsLoaded);
|
||||
return _Textures.TryGetValue(textureRef.Id, out texture) && (!checkDrawable || texture.IsLoaded);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -428,7 +477,10 @@ namespace Vocaluxe.Lib.Draw
|
||||
if (texture != null && --texture.RefCount <= 0)
|
||||
{
|
||||
if (texture.TexturePath != null)
|
||||
{
|
||||
_TextureCache.Remove(texture.TexturePath);
|
||||
}
|
||||
|
||||
texture.Dispose();
|
||||
_TextureCount--;
|
||||
}
|
||||
@@ -442,63 +494,82 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
while (_TextureQueue.Count > 0)
|
||||
{
|
||||
STextureQueue q = _TextureQueue.Dequeue();
|
||||
var q = _TextureQueue.Dequeue();
|
||||
|
||||
if (q.Action == EQueueAction.Add)
|
||||
{
|
||||
TTextureType oldTexture = q.TextureOrRef as TTextureType;
|
||||
var oldTexture = q.TextureOrRef as TTextureType;
|
||||
Debug.Assert(oldTexture != null, "Queued type is wrong");
|
||||
Debug.Assert(!oldTexture.IsLoaded);
|
||||
if (oldTexture.RefCount <= 0)
|
||||
{
|
||||
Bitmap bmp = q.Data as Bitmap;
|
||||
var bmp = q.Data as Bitmap;
|
||||
if (bmp != null)
|
||||
{
|
||||
bmp.Dispose();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
TTextureType texture = null;
|
||||
// ReSharper disable CanBeReplacedWithTryCastAndCheckForNull
|
||||
if (q.Data is Bitmap)
|
||||
{
|
||||
Bitmap bmp = (Bitmap)q.Data;
|
||||
var bmp = (Bitmap)q.Data;
|
||||
_WriteBitmapToTexture(ref texture, bmp);
|
||||
bmp.Dispose();
|
||||
}
|
||||
else if (q.Data is byte[])
|
||||
{
|
||||
texture = _CreateAndFillTexture(q.DataSize, (byte[])q.Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("q.Data is of invalid type");
|
||||
}
|
||||
// ReSharper restore CanBeReplacedWithTryCastAndCheckForNull
|
||||
|
||||
_MergeTextures(oldTexture, texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
CTextureRef textureRef = q.TextureOrRef as CTextureRef;
|
||||
var textureRef = q.TextureOrRef as CTextureRef;
|
||||
Debug.Assert(textureRef != null, "Queued type is wrong");
|
||||
if (!_Textures.ContainsKey(textureRef.ID))
|
||||
if (!_Textures.ContainsKey(textureRef.Id))
|
||||
{
|
||||
Bitmap bmp = q.Data as Bitmap;
|
||||
var bmp = q.Data as Bitmap;
|
||||
if (bmp != null)
|
||||
{
|
||||
bmp.Dispose();
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (q.Action == EQueueAction.Update)
|
||||
{
|
||||
// ReSharper disable CanBeReplacedWithTryCastAndCheckForNull
|
||||
if (q.Data is Bitmap)
|
||||
{
|
||||
Bitmap bmp = (Bitmap)q.Data;
|
||||
var bmp = (Bitmap)q.Data;
|
||||
UpdateTexture(textureRef, bmp);
|
||||
bmp.Dispose();
|
||||
}
|
||||
else if (q.Data is byte[])
|
||||
{
|
||||
UpdateTexture(textureRef, q.DataSize, (byte[])q.Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("q.Data is of invalid type");
|
||||
}
|
||||
// ReSharper restore CanBeReplacedWithTryCastAndCheckForNull
|
||||
}
|
||||
else if (q.Action == EQueueAction.Delete)
|
||||
{
|
||||
RemoveTexture(ref textureRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -517,9 +588,12 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
newTexture.RefCount += oldTexture.RefCount;
|
||||
IEnumerable<int> oldKeys = _Textures.Where(pair => pair.Value == oldTexture).Select(pair => pair.Key).ToArray();
|
||||
foreach (int key in oldKeys)
|
||||
foreach (var key in oldKeys)
|
||||
{
|
||||
_Textures[key] = newTexture;
|
||||
if (!String.IsNullOrEmpty(oldTexture.TexturePath))
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(oldTexture.TexturePath))
|
||||
{
|
||||
newTexture.TexturePath = oldTexture.TexturePath;
|
||||
STextureCacheEntry cacheEntry;
|
||||
@@ -529,6 +603,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
_TextureCache[newTexture.TexturePath] = cacheEntry;
|
||||
}
|
||||
}
|
||||
|
||||
oldTexture.Dispose();
|
||||
}
|
||||
}
|
||||
@@ -548,9 +623,13 @@ namespace Vocaluxe.Lib.Draw
|
||||
if (_RequiresResize(bmp.GetSize()))
|
||||
{
|
||||
if (asyncResize)
|
||||
{
|
||||
Task.Factory.StartNew(() => _ResizeTextureAndEnqueue(texture, bmp, action));
|
||||
}
|
||||
else
|
||||
{
|
||||
_ResizeTextureAndEnqueue(texture, bmp, action);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -569,7 +648,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
/// <param name="action"></param>
|
||||
private void _ResizeTextureAndEnqueue(object texture, Bitmap bmp, EQueueAction action)
|
||||
{
|
||||
Bitmap bmp2 = bmp.Resize(_GetNewTextureSize(bmp.Size));
|
||||
var bmp2 = bmp.Resize(_GetNewTextureSize(bmp.Size));
|
||||
bmp.Dispose();
|
||||
lock (_TextureQueue)
|
||||
{
|
||||
@@ -586,7 +665,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
/// <returns></returns>
|
||||
private Size _LoadAndEnqueueBitmap(string filePath, CTextureRef textureRef, TTextureType texture)
|
||||
{
|
||||
Bitmap bmp = CHelper.LoadBitmap(filePath);
|
||||
var bmp = CHelper.LoadBitmap(filePath);
|
||||
if (bmp == null)
|
||||
{
|
||||
RemoveTexture(ref textureRef); // Done asynchonously in the function
|
||||
@@ -598,9 +677,11 @@ namespace Vocaluxe.Lib.Draw
|
||||
_BitmapsLoading.Remove(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
return new Size(-1, -1);
|
||||
}
|
||||
Size origSize = bmp.GetSize();
|
||||
|
||||
var origSize = bmp.GetSize();
|
||||
textureRef.OrigSize = origSize;
|
||||
// Update cache, use the same lock as in add/get cache methods
|
||||
lock (_Textures)
|
||||
@@ -611,11 +692,13 @@ namespace Vocaluxe.Lib.Draw
|
||||
cacheEntry.OrigSize = origSize;
|
||||
_TextureCache[filePath] = cacheEntry;
|
||||
}
|
||||
|
||||
lock (_BitmapsLoading)
|
||||
{
|
||||
_BitmapsLoading.Remove(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
_EnqueueTextureAddOrUpdate(texture, bmp, EQueueAction.Add, false);
|
||||
return origSize;
|
||||
}
|
||||
@@ -634,17 +717,24 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
textureRef = _GetFromCache(texturePath, out loader);
|
||||
}
|
||||
|
||||
if (textureRef != null)
|
||||
{
|
||||
if (loader != null)
|
||||
{
|
||||
textureRef.OrigSize = loader.Result;
|
||||
}
|
||||
|
||||
Debug.Assert(textureRef.OrigSize.Width > 0);
|
||||
return textureRef;
|
||||
}
|
||||
|
||||
Bitmap bmp = CHelper.LoadBitmap(texturePath);
|
||||
var bmp = CHelper.LoadBitmap(texturePath);
|
||||
if (bmp == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
textureRef = AddTexture(bmp, texturePath);
|
||||
@@ -653,6 +743,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
bmp.Dispose();
|
||||
}
|
||||
|
||||
return textureRef;
|
||||
}
|
||||
|
||||
@@ -672,10 +763,12 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
_EnsureMainThread();
|
||||
if (bmp.Height == 0 || bmp.Width == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
CTextureRef textureRef;
|
||||
Size origSize = bmp.GetSize();
|
||||
var origSize = bmp.GetSize();
|
||||
TTextureType texture = null;
|
||||
Task<Size> loader;
|
||||
// Make the Get/Add Cache methods atomic
|
||||
@@ -689,10 +782,16 @@ namespace Vocaluxe.Lib.Draw
|
||||
_AddToCache(texture, origSize, texturePath);
|
||||
}
|
||||
}
|
||||
|
||||
if (textureRef == null)
|
||||
{
|
||||
textureRef = _GetTextureReference(origSize, texture);
|
||||
}
|
||||
else if (loader != null)
|
||||
{
|
||||
textureRef.OrigSize = loader.Result;
|
||||
}
|
||||
|
||||
Debug.Assert(textureRef.OrigSize.Width > 0);
|
||||
return textureRef;
|
||||
}
|
||||
@@ -700,7 +799,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
public CTextureRef AddTexture(int w, int h, byte[] data)
|
||||
{
|
||||
_EnsureMainThread();
|
||||
TTextureType texture = _CreateAndFillTexture(new Size(w, h), data);
|
||||
var texture = _CreateAndFillTexture(new Size(w, h), data);
|
||||
return _GetTextureReference(w, h, texture);
|
||||
}
|
||||
|
||||
@@ -708,8 +807,8 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
lock (_TextureQueue)
|
||||
{
|
||||
TTextureType texture = _CreateTexture(new Size(-1, -1));
|
||||
CTextureRef textureRef = _GetTextureReference(w, h, texture);
|
||||
var texture = _CreateTexture(new Size(-1, -1));
|
||||
var textureRef = _GetTextureReference(w, h, texture);
|
||||
_TextureQueue.Enqueue(new STextureQueue(texture, EQueueAction.Add, new Size(w, h), data));
|
||||
return textureRef;
|
||||
}
|
||||
@@ -717,8 +816,8 @@ namespace Vocaluxe.Lib.Draw
|
||||
|
||||
public CTextureRef EnqueueTexture(Bitmap bmp)
|
||||
{
|
||||
TTextureType texture = _CreateTexture(new Size(-1, -1));
|
||||
CTextureRef textureRef = _GetTextureReference(bmp.GetSize(), texture);
|
||||
var texture = _CreateTexture(new Size(-1, -1));
|
||||
var textureRef = _GetTextureReference(bmp.GetSize(), texture);
|
||||
_EnqueueTextureAddOrUpdate(texture, bmp, EQueueAction.Add, true);
|
||||
|
||||
return textureRef;
|
||||
@@ -733,7 +832,10 @@ namespace Vocaluxe.Lib.Draw
|
||||
// All solved with atomic get/add cache and _WaitForTextureLoaded
|
||||
|
||||
if (!File.Exists(filePath))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
CTextureRef textureRef;
|
||||
TTextureType texture = null;
|
||||
Task<Size> loader;
|
||||
@@ -744,7 +846,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
if (textureRef == null)
|
||||
{
|
||||
Debug.Assert(loader == null);
|
||||
Size invalidSize = new Size(-1, -1);
|
||||
var invalidSize = new Size(-1, -1);
|
||||
texture = _CreateTexture(invalidSize);
|
||||
// This cache entry has to be updated once the real origSize is available
|
||||
_AddToCache(texture, invalidSize, filePath);
|
||||
@@ -762,9 +864,12 @@ namespace Vocaluxe.Lib.Draw
|
||||
if (texture == null)
|
||||
{
|
||||
// Found in cache
|
||||
CTextureRef tmp = textureRef; // Workaround for implicitly captured closure warning (false positive)
|
||||
var tmp = textureRef; // Workaround for implicitly captured closure warning (false positive)
|
||||
if (loader != null)
|
||||
{
|
||||
Task.Factory.StartNew(() => tmp.OrigSize = loader.Result);
|
||||
}
|
||||
|
||||
return textureRef;
|
||||
}
|
||||
|
||||
@@ -796,8 +901,11 @@ namespace Vocaluxe.Lib.Draw
|
||||
_EnsureMainThread();
|
||||
TTextureType texture;
|
||||
if (!_GetTexture(textureRef, out texture, false))
|
||||
{
|
||||
return;
|
||||
bool reuseTexture = _IsTextureUsable(texture, dataSize);
|
||||
}
|
||||
|
||||
var reuseTexture = _IsTextureUsable(texture, dataSize);
|
||||
if (reuseTexture && texture.RefCount == 1)
|
||||
{
|
||||
texture.DataSize = dataSize;
|
||||
@@ -808,7 +916,7 @@ namespace Vocaluxe.Lib.Draw
|
||||
_DisposeTexture(texture);
|
||||
texture = _CreateAndFillTexture(dataSize, data);
|
||||
texture.RefCount = 1;
|
||||
_Textures[textureRef.ID] = texture;
|
||||
_Textures[textureRef.Id] = texture;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -817,17 +925,22 @@ namespace Vocaluxe.Lib.Draw
|
||||
_EnsureMainThread();
|
||||
TTextureType texture;
|
||||
if (!_GetTexture(textureRef, out texture, false))
|
||||
{
|
||||
return;
|
||||
bool reuseTexture = _IsTextureUsable(texture, bmp.Size);
|
||||
}
|
||||
|
||||
var reuseTexture = _IsTextureUsable(texture, bmp.Size);
|
||||
if (reuseTexture && texture.RefCount == 1)
|
||||
{
|
||||
_WriteBitmapToTexture(ref texture, bmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
_DisposeTexture(texture);
|
||||
texture = null;
|
||||
_WriteBitmapToTexture(ref texture, bmp);
|
||||
texture.RefCount = 1;
|
||||
_Textures[textureRef.ID] = texture;
|
||||
_Textures[textureRef.Id] = texture;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -838,18 +951,25 @@ namespace Vocaluxe.Lib.Draw
|
||||
{
|
||||
TTextureType texture;
|
||||
if (!_GetTexture(textureRef, out texture, false))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// If bitmap is not yet loaded, wait for it
|
||||
if (!String.IsNullOrEmpty(texture.TexturePath))
|
||||
if (!string.IsNullOrEmpty(texture.TexturePath))
|
||||
{
|
||||
Task<Size> loader;
|
||||
lock (_BitmapsLoading)
|
||||
{
|
||||
_BitmapsLoading.TryGetValue(texture.TexturePath, out loader);
|
||||
}
|
||||
|
||||
if (loader != null)
|
||||
{
|
||||
textureRef.OrigSize = loader.Result;
|
||||
}
|
||||
}
|
||||
|
||||
Debug.Assert(textureRef.OrigSize.Width > 0);
|
||||
return _GetTextureReference(textureRef.OrigSize, texture);
|
||||
}
|
||||
@@ -862,29 +982,36 @@ namespace Vocaluxe.Lib.Draw
|
||||
public void RemoveTexture(ref CTextureRef textureRef)
|
||||
{
|
||||
if (textureRef == null)
|
||||
return;
|
||||
if (textureRef.ID > 0)
|
||||
{
|
||||
if (_MainThreadID != Thread.CurrentThread.ManagedThreadId)
|
||||
return;
|
||||
}
|
||||
|
||||
if (textureRef.Id > 0)
|
||||
{
|
||||
if (_MainThreadId != Thread.CurrentThread.ManagedThreadId)
|
||||
{
|
||||
lock (_TextureQueue)
|
||||
{
|
||||
_TextureQueue.Enqueue(new STextureQueue(textureRef, EQueueAction.Delete, null));
|
||||
}
|
||||
|
||||
textureRef = null;
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_Textures)
|
||||
{
|
||||
TTextureType t;
|
||||
if (_Textures.TryGetValue(textureRef.ID, out t))
|
||||
if (_Textures.TryGetValue(textureRef.Id, out t))
|
||||
{
|
||||
_DisposeTexture(t);
|
||||
_Textures.Remove(textureRef.ID);
|
||||
_Textures.Remove(textureRef.Id);
|
||||
}
|
||||
|
||||
textureRef.SetRemoved();
|
||||
}
|
||||
}
|
||||
|
||||
textureRef = null;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,7 +34,10 @@ namespace Vocaluxe.Lib.Input
|
||||
public virtual bool Init()
|
||||
{
|
||||
if (_Initialized)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_CurrentKeysPool = new List<SKeyEvent>();
|
||||
_CurrentMousePool = new List<SMouseEvent>();
|
||||
_Initialized = true;
|
||||
@@ -44,13 +47,22 @@ namespace Vocaluxe.Lib.Input
|
||||
public virtual void Close()
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_CurrentKeysPool = null;
|
||||
_CurrentMousePool = null;
|
||||
lock (_KeysPool)
|
||||
{
|
||||
_KeysPool.Clear();
|
||||
}
|
||||
|
||||
lock (_MousePool)
|
||||
{
|
||||
_MousePool.Clear();
|
||||
}
|
||||
|
||||
_Initialized = false;
|
||||
}
|
||||
|
||||
@@ -63,18 +75,27 @@ namespace Vocaluxe.Lib.Input
|
||||
public virtual void Update()
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_KeysPool)
|
||||
{
|
||||
foreach (SKeyEvent e in _KeysPool)
|
||||
foreach (var e in _KeysPool)
|
||||
{
|
||||
_CurrentKeysPool.Add(e);
|
||||
}
|
||||
|
||||
_KeysPool.Clear();
|
||||
}
|
||||
|
||||
lock (_MousePool)
|
||||
{
|
||||
foreach (SMouseEvent e in _MousePool)
|
||||
foreach (var e in _MousePool)
|
||||
{
|
||||
_CurrentMousePool.Add(e);
|
||||
}
|
||||
|
||||
_MousePool.Clear();
|
||||
}
|
||||
}
|
||||
@@ -82,26 +103,34 @@ namespace Vocaluxe.Lib.Input
|
||||
public virtual bool PollKeyEvent(ref SKeyEvent keyEvent)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_CurrentKeysPool.Count > 0)
|
||||
{
|
||||
keyEvent = _CurrentKeysPool[0];
|
||||
_CurrentKeysPool.RemoveAt(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual bool PollMouseEvent(ref SMouseEvent mouseEvent)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_CurrentMousePool.Count > 0)
|
||||
{
|
||||
mouseEvent = _CurrentMousePool[0];
|
||||
_CurrentMousePool.RemoveAt(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -110,7 +139,10 @@ namespace Vocaluxe.Lib.Input
|
||||
public void AddKeyEvent(SKeyEvent keyEvent)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_KeysPool)
|
||||
{
|
||||
_KeysPool.Add(keyEvent);
|
||||
@@ -120,7 +152,10 @@ namespace Vocaluxe.Lib.Input
|
||||
public void AddMouseEvent(SMouseEvent mouseEvent)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_MousePool)
|
||||
{
|
||||
_MousePool.Add(mouseEvent);
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Diagnostics;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Threading;
|
||||
using System.Windows.Forms;
|
||||
using OpenTK.Input;
|
||||
using Vocaluxe.Base;
|
||||
@@ -79,7 +79,9 @@ namespace Vocaluxe.Lib.Input
|
||||
public override bool Init()
|
||||
{
|
||||
if (!base.Init())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_rumbleTimer = new CRumbleTimer();
|
||||
_evTerminate = new AutoResetEvent(false);
|
||||
@@ -97,10 +99,14 @@ namespace Vocaluxe.Lib.Input
|
||||
public override void Connect()
|
||||
{
|
||||
if (_active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_evTerminate == null)
|
||||
{
|
||||
_evTerminate = new AutoResetEvent(false);
|
||||
}
|
||||
|
||||
if (_handlerThread == null)
|
||||
{
|
||||
@@ -126,12 +132,16 @@ namespace Vocaluxe.Lib.Input
|
||||
_active = false;
|
||||
|
||||
if (_evTerminate != null)
|
||||
{
|
||||
_evTerminate.Set();
|
||||
}
|
||||
|
||||
if (_handlerThread != null)
|
||||
{
|
||||
if (!_handlerThread.Join(ThreadJoinTimeoutMs))
|
||||
{
|
||||
Debug.WriteLine("CGamePad: Handler thread did not terminate within timeout.");
|
||||
}
|
||||
|
||||
_handlerThread = null;
|
||||
}
|
||||
@@ -139,7 +149,9 @@ namespace Vocaluxe.Lib.Input
|
||||
try
|
||||
{
|
||||
if (_GamePadIndex != -1)
|
||||
{
|
||||
GamePad.SetVibration(_GamePadIndex, 0.0f, 0.0f);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -167,7 +179,9 @@ namespace Vocaluxe.Lib.Input
|
||||
lock (_Sync)
|
||||
{
|
||||
if (_rumbleTimer != null)
|
||||
{
|
||||
_rumbleTimer.Set(duration);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,7 +194,9 @@ namespace Vocaluxe.Lib.Input
|
||||
Thread.Sleep(PollSleepMs);
|
||||
|
||||
if (!_EnsureConnected())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -202,13 +218,19 @@ namespace Vocaluxe.Lib.Input
|
||||
private bool _EnsureConnected()
|
||||
{
|
||||
if (Connected)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_DoConnect())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_evTerminate != null)
|
||||
{
|
||||
_evTerminate.WaitOne(ReconnectWaitMs);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -224,16 +246,22 @@ namespace Vocaluxe.Lib.Input
|
||||
stopRumble = _rumbleTimer != null && _rumbleTimer.ShouldStop;
|
||||
}
|
||||
|
||||
int currentIndex = _GamePadIndex;
|
||||
var currentIndex = _GamePadIndex;
|
||||
if (currentIndex == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (startRumble)
|
||||
{
|
||||
GamePad.SetVibration(currentIndex, 1.0f, 1.0f);
|
||||
}
|
||||
else if (stopRumble)
|
||||
{
|
||||
GamePad.SetVibration(currentIndex, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
GamePadState state = GamePad.GetState(currentIndex);
|
||||
var state = GamePad.GetState(currentIndex);
|
||||
|
||||
if (!GamePad.GetCapabilities(currentIndex).IsConnected)
|
||||
{
|
||||
@@ -261,7 +289,9 @@ namespace Vocaluxe.Lib.Input
|
||||
private static void _StopVibrationBestEffort(int gamePadIndex)
|
||||
{
|
||||
if (gamePadIndex == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
@@ -275,17 +305,17 @@ namespace Vocaluxe.Lib.Input
|
||||
|
||||
private void _HandleButtons(GamePadState buttonStates)
|
||||
{
|
||||
bool leftClickTriggered =
|
||||
(buttonStates.Buttons.LeftShoulder == OpenTK.Input.ButtonState.Pressed &&
|
||||
_oldButtonStates.Buttons.LeftShoulder == OpenTK.Input.ButtonState.Released);
|
||||
var leftClickTriggered =
|
||||
buttonStates.Buttons.LeftShoulder == OpenTK.Input.ButtonState.Pressed &&
|
||||
_oldButtonStates.Buttons.LeftShoulder == OpenTK.Input.ButtonState.Released;
|
||||
|
||||
bool rightClickTriggered =
|
||||
(buttonStates.Buttons.RightShoulder == OpenTK.Input.ButtonState.Pressed &&
|
||||
_oldButtonStates.Buttons.RightShoulder == OpenTK.Input.ButtonState.Released);
|
||||
var rightClickTriggered =
|
||||
buttonStates.Buttons.RightShoulder == OpenTK.Input.ButtonState.Pressed &&
|
||||
_oldButtonStates.Buttons.RightShoulder == OpenTK.Input.ButtonState.Released;
|
||||
|
||||
leftClickTriggered |=
|
||||
(buttonStates.Buttons.RightStick == OpenTK.Input.ButtonState.Pressed &&
|
||||
_oldButtonStates.Buttons.RightStick == OpenTK.Input.ButtonState.Released);
|
||||
buttonStates.Buttons.RightStick == OpenTK.Input.ButtonState.Pressed &&
|
||||
_oldButtonStates.Buttons.RightStick == OpenTK.Input.ButtonState.Released;
|
||||
|
||||
var keys = new List<Keys>();
|
||||
|
||||
@@ -380,7 +410,7 @@ namespace Vocaluxe.Lib.Input
|
||||
keys.Add(Keys.Back);
|
||||
}
|
||||
|
||||
foreach (Keys key in keys)
|
||||
foreach (var key in keys)
|
||||
{
|
||||
AddKeyEvent(new SKeyEvent(
|
||||
ESender.Gamepad,
|
||||
@@ -392,16 +422,20 @@ namespace Vocaluxe.Lib.Input
|
||||
key));
|
||||
}
|
||||
|
||||
float rightX = buttonStates.ThumbSticks.Right.X;
|
||||
float rightY = buttonStates.ThumbSticks.Right.Y;
|
||||
var rightX = buttonStates.ThumbSticks.Right.X;
|
||||
var rightY = buttonStates.ThumbSticks.Right.Y;
|
||||
|
||||
if (Math.Abs(rightX) < RightStickMouseDeadZone)
|
||||
{
|
||||
rightX = 0.0f;
|
||||
}
|
||||
|
||||
if (Math.Abs(rightY) < RightStickMouseDeadZone)
|
||||
{
|
||||
rightY = 0.0f;
|
||||
}
|
||||
|
||||
bool hasMouseDelta =
|
||||
var hasMouseDelta =
|
||||
Math.Abs(rightX) > MouseAxisEpsilon ||
|
||||
Math.Abs(rightY) > MouseAxisEpsilon;
|
||||
|
||||
@@ -414,7 +448,7 @@ namespace Vocaluxe.Lib.Input
|
||||
_mouseX = Math.Min(CSettings.RenderW, Math.Max(0.0f, _mouseX));
|
||||
_mouseY = Math.Min(CSettings.RenderH, Math.Max(0.0f, _mouseY));
|
||||
|
||||
bool mouseMoved =
|
||||
var mouseMoved =
|
||||
hasMouseDelta ||
|
||||
leftClickTriggered ||
|
||||
rightClickTriggered;
|
||||
@@ -478,7 +512,7 @@ namespace Vocaluxe.Lib.Input
|
||||
{
|
||||
_GamePadIndex = -1;
|
||||
|
||||
for (int i = 0; i < MaxGamePads; i++)
|
||||
for (var i = 0; i < MaxGamePads; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -495,7 +529,9 @@ namespace Vocaluxe.Lib.Input
|
||||
}
|
||||
|
||||
if (_GamePadIndex == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_oldButtonStates = new GamePadState();
|
||||
_ResetAllRepeatTimers();
|
||||
@@ -525,4 +561,4 @@ namespace Vocaluxe.Lib.Input
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Vocaluxe.Base;
|
||||
using VocaluxeLib.Log;
|
||||
|
||||
namespace Vocaluxe.Lib.Input
|
||||
@@ -26,16 +25,21 @@ namespace Vocaluxe.Lib.Input
|
||||
public struct SHIDDeviceInfo
|
||||
{
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
[MarshalAs(UnmanagedType.LPTStr)] public readonly String Path;
|
||||
[MarshalAs(UnmanagedType.LPTStr)]
|
||||
public readonly String Path;
|
||||
public readonly ushort VendorString;
|
||||
public readonly ushort ProductID;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public readonly String SerialNumber;
|
||||
public readonly ushort ProductId;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public readonly String SerialNumber;
|
||||
public readonly ushort ReleaseNumber;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public readonly String ManufacturerString;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public readonly String ProductString;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public readonly String ManufacturerString;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public readonly String ProductString;
|
||||
public readonly ushort UsagePage;
|
||||
public readonly ushort Usage;
|
||||
[MarshalAs(UnmanagedType.LPWStr)] public readonly int InterfaceNumber;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
public readonly int InterfaceNumber;
|
||||
internal IntPtr Next;
|
||||
// ReSharper restore MemberCanBePrivate.Global
|
||||
}
|
||||
@@ -101,13 +105,13 @@ namespace Vocaluxe.Lib.Input
|
||||
}
|
||||
|
||||
[DllImport(_HIDApiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_enumerate", CharSet = CharSet.Ansi)]
|
||||
private static extern IntPtr hid_enumerate(ushort vendorID, ushort productID);
|
||||
private static extern IntPtr hid_enumerate(ushort vendorId, ushort productId);
|
||||
|
||||
//HIDDeviceInfo
|
||||
public static IntPtr Enumerate(ushort vendorID, ushort productID)
|
||||
public static IntPtr Enumerate(ushort vendorId, ushort productId)
|
||||
{
|
||||
//HIDDeviceInfo
|
||||
return hid_enumerate(vendorID, productID);
|
||||
return hid_enumerate(vendorId, productId);
|
||||
}
|
||||
|
||||
[DllImport(_HIDApiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_free_enumeration", CharSet = CharSet.Unicode)]
|
||||
@@ -119,14 +123,14 @@ namespace Vocaluxe.Lib.Input
|
||||
}
|
||||
|
||||
[DllImport(_HIDApiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_open", CharSet = CharSet.Unicode)]
|
||||
private static extern IntPtr hid_open(ushort vendorID, ushort productID, IntPtr serialNumber);
|
||||
private static extern IntPtr hid_open(ushort vendorId, ushort productId, IntPtr serialNumber);
|
||||
|
||||
public static bool Open(ushort vendorID, ushort productID, out IntPtr handle)
|
||||
public static bool Open(ushort vendorId, ushort productId, out IntPtr handle)
|
||||
{
|
||||
handle = IntPtr.Zero;
|
||||
try
|
||||
{
|
||||
handle = hid_open(vendorID, productID, IntPtr.Zero);
|
||||
handle = hid_open(vendorId, productId, IntPtr.Zero);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -135,7 +139,9 @@ namespace Vocaluxe.Lib.Input
|
||||
}
|
||||
|
||||
if (handle != IntPtr.Zero)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -161,7 +167,7 @@ namespace Vocaluxe.Lib.Input
|
||||
|
||||
public static int ReadTimeout(IntPtr device, ref byte[] data, int length, int milliseconds)
|
||||
{
|
||||
IntPtr dataPtr = Marshal.AllocHGlobal(length);
|
||||
var dataPtr = Marshal.AllocHGlobal(length);
|
||||
int bytesRead;
|
||||
try
|
||||
{
|
||||
@@ -174,9 +180,13 @@ namespace Vocaluxe.Lib.Input
|
||||
}
|
||||
|
||||
if (bytesRead != -1)
|
||||
{
|
||||
Marshal.Copy(dataPtr, data, 0, bytesRead);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = null;
|
||||
}
|
||||
|
||||
Marshal.FreeHGlobal(dataPtr);
|
||||
|
||||
@@ -189,7 +199,7 @@ namespace Vocaluxe.Lib.Input
|
||||
public static int Read(IntPtr device, out byte[] data, int length)
|
||||
{
|
||||
data = new byte[length];
|
||||
IntPtr dataPtr = Marshal.AllocHGlobal(length);
|
||||
var dataPtr = Marshal.AllocHGlobal(length);
|
||||
|
||||
int result;
|
||||
try
|
||||
@@ -203,9 +213,13 @@ namespace Vocaluxe.Lib.Input
|
||||
}
|
||||
|
||||
if (result != -1)
|
||||
{
|
||||
Marshal.Copy(dataPtr, data, 0, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = null;
|
||||
}
|
||||
|
||||
Marshal.FreeHGlobal(dataPtr);
|
||||
return result;
|
||||
@@ -249,6 +263,7 @@ namespace Vocaluxe.Lib.Input
|
||||
CLog.Error("Error CHIDAPI.Close(): " + e);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -126,10 +126,12 @@ namespace Vocaluxe.Lib.Input
|
||||
public EGesture GetGesture(Point newPosition)
|
||||
{
|
||||
if (!_Locked)
|
||||
{
|
||||
return EGesture.None;
|
||||
}
|
||||
|
||||
int dx = newPosition.X - _Begin.X;
|
||||
int dy = newPosition.Y - _Begin.Y;
|
||||
var dx = newPosition.X - _Begin.X;
|
||||
var dy = newPosition.Y - _Begin.Y;
|
||||
|
||||
//Back/Escape
|
||||
if (dx < -150 && Math.Abs(dy) < 150)
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
private bool[] _ButtonStates;
|
||||
private Point _OldPosition;
|
||||
private bool _Connected;
|
||||
|
||||
|
||||
private Object _Sync;
|
||||
private bool _Active;
|
||||
private CRumbleTimer _RumbleTimer;
|
||||
@@ -46,7 +46,10 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
public override bool Init()
|
||||
{
|
||||
if (!base.Init())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_Sync = new Object();
|
||||
_RumbleTimer = new CRumbleTimer();
|
||||
_Gesture = new CGesture();
|
||||
@@ -74,9 +77,12 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
public override void Connect()
|
||||
{
|
||||
if (_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Active = true;
|
||||
|
||||
|
||||
|
||||
_WiiMote.Connect();
|
||||
}
|
||||
@@ -118,7 +124,7 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
_WiiMote.SetRumble(true);
|
||||
Thread.Sleep(250);
|
||||
_WiiMote.SetRumble(false);
|
||||
|
||||
|
||||
|
||||
bool startRumble;
|
||||
bool stopRumble;
|
||||
@@ -129,9 +135,13 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
}
|
||||
|
||||
if (startRumble)
|
||||
{
|
||||
_WiiMote.SetRumble(true);
|
||||
}
|
||||
else if (stopRumble)
|
||||
{
|
||||
_WiiMote.SetRumble(false);
|
||||
}
|
||||
|
||||
_Connected = true;
|
||||
}
|
||||
@@ -140,43 +150,69 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
private void _WmWiiMoteChanged(object sender, CWiiMoteChangedEventArgs args)
|
||||
{
|
||||
if (!_Active)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CWiiMoteStatus ws = args.WiiMoteState;
|
||||
var ws = args.WiiMoteState;
|
||||
|
||||
Point p = ws.IRState.Position;
|
||||
var p = ws.IRState.Position;
|
||||
p.X = 1023 - p.X;
|
||||
|
||||
EGesture gesture = _Gesture.GetGesture(p);
|
||||
bool lb = false;
|
||||
bool rb = gesture == EGesture.Back;
|
||||
var gesture = _Gesture.GetGesture(p);
|
||||
var lb = false;
|
||||
var rb = gesture == EGesture.Back;
|
||||
|
||||
var key = Keys.None;
|
||||
|
||||
if (ws.ButtonState.A && !_ButtonStates[0])
|
||||
{
|
||||
lb = true;
|
||||
}
|
||||
else if (ws.ButtonState.B && !_ButtonStates[1])
|
||||
{
|
||||
_Gesture.SetLockPosition(p);
|
||||
}
|
||||
else if (!ws.ButtonState.B && _ButtonStates[1])
|
||||
{
|
||||
_Gesture.Reset();
|
||||
}
|
||||
else if (ws.ButtonState.Down && !_ButtonStates[2])
|
||||
{
|
||||
key = Keys.Right;
|
||||
}
|
||||
else if (ws.ButtonState.Up && !_ButtonStates[3])
|
||||
{
|
||||
key = Keys.Left;
|
||||
}
|
||||
else if (ws.ButtonState.Left && !_ButtonStates[4])
|
||||
{
|
||||
key = Keys.Down;
|
||||
}
|
||||
else if (ws.ButtonState.Right && !_ButtonStates[5])
|
||||
{
|
||||
key = Keys.Up;
|
||||
}
|
||||
else if (ws.ButtonState.Home && !_ButtonStates[6])
|
||||
{
|
||||
key = Keys.Space;
|
||||
}
|
||||
else if (ws.ButtonState.Minus && !_ButtonStates[7])
|
||||
{
|
||||
key = Keys.Subtract;
|
||||
}
|
||||
else if (ws.ButtonState.Plus && !_ButtonStates[8])
|
||||
{
|
||||
key = Keys.Add;
|
||||
}
|
||||
else if (ws.ButtonState.One && !_ButtonStates[9])
|
||||
{
|
||||
key = Keys.Enter;
|
||||
}
|
||||
else if (ws.ButtonState.Two && !_ButtonStates[10])
|
||||
{
|
||||
key = Keys.Escape;
|
||||
}
|
||||
|
||||
_ButtonStates[0] = ws.ButtonState.A;
|
||||
_ButtonStates[1] = ws.ButtonState.B;
|
||||
@@ -192,30 +228,41 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
|
||||
|
||||
if (key != Keys.None)
|
||||
{
|
||||
AddKeyEvent(new SKeyEvent(ESender.WiiMote, false, false, false, false, char.MinValue, key));
|
||||
}
|
||||
|
||||
//mouse events
|
||||
const float reducing = 0.15f;
|
||||
const float factor = 1f / (1f - reducing * 2f);
|
||||
float rx = ((p.X / 1024f) - reducing) * factor;
|
||||
float ry = ((p.Y / 768f) - reducing) * factor;
|
||||
var rx = (p.X / 1024f - reducing) * factor;
|
||||
var ry = (p.Y / 768f - reducing) * factor;
|
||||
|
||||
var x = (int)(rx * CSettings.RenderW);
|
||||
var y = (int)(ry * CSettings.RenderH);
|
||||
|
||||
|
||||
bool lbh = !lb && ws.ButtonState.A;
|
||||
var lbh = !lb && ws.ButtonState.A;
|
||||
|
||||
int wheel = 0;
|
||||
var wheel = 0;
|
||||
if (gesture == EGesture.ScrollUp)
|
||||
{
|
||||
wheel = -1;
|
||||
}
|
||||
|
||||
if (gesture == EGesture.ScrollDown)
|
||||
{
|
||||
wheel = 1;
|
||||
}
|
||||
|
||||
if (!lb && !rb && (p.X != _OldPosition.X || p.Y != _OldPosition.Y))
|
||||
{
|
||||
AddMouseEvent(new SMouseEvent(ESender.WiiMote, EModifier.None, x, y, false, false, false, wheel, lbh, false, false, false));
|
||||
}
|
||||
else if (lb || rb)
|
||||
{
|
||||
AddMouseEvent(new SMouseEvent(ESender.WiiMote, EModifier.None, x, y, lb, false, rb, wheel, false, false, false, false));
|
||||
}
|
||||
|
||||
_OldPosition.X = p.X;
|
||||
_OldPosition.Y = p.Y;
|
||||
|
||||
@@ -18,13 +18,11 @@
|
||||
using System;
|
||||
using System.Drawing;
|
||||
using System.Threading;
|
||||
using Vocaluxe.Base;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Log;
|
||||
|
||||
namespace Vocaluxe.Lib.Input.WiiMote
|
||||
{
|
||||
|
||||
#region DataTypes
|
||||
public class CWiiMoteStatus
|
||||
{
|
||||
@@ -136,6 +134,7 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
WiiMoteState = ws;
|
||||
}
|
||||
}
|
||||
|
||||
public class CWiiMoteConnectionChangedEventArgs : EventArgs
|
||||
{
|
||||
public readonly bool Connected;
|
||||
@@ -150,10 +149,10 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
public sealed class CWiiMoteLib
|
||||
{
|
||||
// ReSharper disable InconsistentNaming
|
||||
private const ushort _VID = 0x057e;
|
||||
private const ushort _VId = 0x057e;
|
||||
// ReSharper restore InconsistentNaming
|
||||
private const ushort _PID = 0x0306; //Wiimotion
|
||||
private const ushort _PIDPlus = 0x0330; //Wiimotion Plus
|
||||
private const ushort _PId = 0x0306; //Wiimotion
|
||||
private const ushort _PIdPlus = 0x0330; //Wiimotion Plus
|
||||
|
||||
// registers
|
||||
private const int _RegisterIR = 0x04b00030;
|
||||
@@ -200,7 +199,9 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
_Connected = value;
|
||||
|
||||
if (WiiMoteConnectionChanged != null)
|
||||
{
|
||||
WiiMoteConnectionChanged.Invoke(this, new CWiiMoteConnectionChangedEventArgs(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,14 +233,17 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
|
||||
private void _StartReader()
|
||||
{
|
||||
_Reader = new Thread(_ReaderLoop) {Name = "WiiMoteLib"};
|
||||
_Reader = new Thread(_ReaderLoop) { Name = "WiiMoteLib" };
|
||||
_Reader.Start();
|
||||
}
|
||||
|
||||
private void _WaitForReader()
|
||||
{
|
||||
if (_Reader == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_Reader.Join();
|
||||
_Reader = null;
|
||||
}
|
||||
@@ -248,27 +252,35 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
{
|
||||
//We might have had a reader thread, that is not finished yet, so let it finish and close it's handle first or it will close the new one
|
||||
_WaitForReader();
|
||||
Connected = CHIDApi.Open(_VID, pid, out _Handle);
|
||||
Connected = CHIDApi.Open(_VId, pid, out _Handle);
|
||||
if (Connected)
|
||||
{
|
||||
_StartReader();
|
||||
if (!_ReadCalibration())
|
||||
{
|
||||
Connected = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool Connect()
|
||||
{
|
||||
if (Connected)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_Error)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_TryConnect(_PID); //Try WiiMotion
|
||||
_TryConnect(_PId); //Try WiiMotion
|
||||
|
||||
if (!Connected)
|
||||
_TryConnect(_PIDPlus); //Try WiiMotion Plus
|
||||
{
|
||||
_TryConnect(_PIdPlus); //Try WiiMotion Plus
|
||||
}
|
||||
|
||||
return Connected;
|
||||
}
|
||||
@@ -281,7 +293,9 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
public void SetReportType(EInputReport type, EIRSensitivity irSensitivity, bool continuous)
|
||||
{
|
||||
if (!Connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
@@ -309,7 +323,9 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
_WiiMoteState.LEDState.LED4 = led4;
|
||||
|
||||
if (!Connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_ClearReport();
|
||||
|
||||
@@ -329,9 +345,9 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
|
||||
// the LED report also handles rumble
|
||||
SetLEDs(_WiiMoteState.LEDState.LED1,
|
||||
_WiiMoteState.LEDState.LED2,
|
||||
_WiiMoteState.LEDState.LED3,
|
||||
_WiiMoteState.LEDState.LED4);
|
||||
_WiiMoteState.LEDState.LED2,
|
||||
_WiiMoteState.LEDState.LED3,
|
||||
_WiiMoteState.LEDState.LED4);
|
||||
}
|
||||
#endregion Interface
|
||||
|
||||
@@ -362,10 +378,14 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
if (bytesRead > 0 && _ParseInputReport(buff))
|
||||
{
|
||||
if (WiiMoteChanged != null)
|
||||
{
|
||||
WiiMoteChanged.Invoke(this, new CWiiMoteChangedEventArgs(_WiiMoteState));
|
||||
}
|
||||
}
|
||||
|
||||
Thread.Sleep(5);
|
||||
}
|
||||
|
||||
CHIDApi.Close(_Handle);
|
||||
}
|
||||
|
||||
@@ -473,6 +493,7 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
_WiiMoteState.IRState.Sensors[0].Position.Y = buff[7] | ((buff[8] >> 6) & 0x03) << 8;
|
||||
_WiiMoteState.IRState.Sensors[0].Width = 0;
|
||||
}
|
||||
|
||||
_WiiMoteState.IRState.Sensors[1].Active = !(buff[9] == 0xff && buff[10] == 0xff);
|
||||
if (_WiiMoteState.IRState.Sensors[1].Active)
|
||||
{
|
||||
@@ -480,17 +501,22 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
_WiiMoteState.IRState.Sensors[1].Position.Y = buff[10] | ((buff[8] >> 2) & 0x03) << 8;
|
||||
_WiiMoteState.IRState.Sensors[1].Width = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
case EIRMode.Extended:
|
||||
for (int i = 0; i < 4; i++)
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
_WiiMoteState.IRState.Sensors[i].Active = !(buff[6 + i * 3] == 0xff && buff[7 + i * 3] == 0xff && buff[8 + i * 3] == 0xff);
|
||||
if (!_WiiMoteState.IRState.Sensors[i].Active)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
_WiiMoteState.IRState.Sensors[i].Position.X = buff[6 + i * 3] | ((buff[8 + i * 3] >> 4) & 0x03) << 8;
|
||||
_WiiMoteState.IRState.Sensors[i].Position.Y = buff[7 + i * 3] | ((buff[8 + i * 3] >> 6) & 0x03) << 8;
|
||||
_WiiMoteState.IRState.Sensors[i].Width = buff[8 + i * 3] & 0x0f;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -505,14 +531,22 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
else if (_WiiMoteState.IRState.Sensors[0].Active)
|
||||
{
|
||||
if (_WiiMoteState.IRState.Sensors[0].Position.X > 512)
|
||||
{
|
||||
_WiiMoteState.IRState.Position.X = _WiiMoteState.IRState.Sensors[0].Position.X - _WiiMoteState.IRState.Distance.X / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
_WiiMoteState.IRState.Position.X = _WiiMoteState.IRState.Sensors[0].Position.X + _WiiMoteState.IRState.Distance.X / 2;
|
||||
}
|
||||
|
||||
if (_WiiMoteState.IRState.Sensors[0].Position.X < 384)
|
||||
{
|
||||
_WiiMoteState.IRState.Position.Y = _WiiMoteState.IRState.Sensors[0].Position.Y - _WiiMoteState.IRState.Distance.Y / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
_WiiMoteState.IRState.Position.Y = _WiiMoteState.IRState.Sensors[0].Position.Y + _WiiMoteState.IRState.Distance.Y / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -530,13 +564,15 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
Connected = false;
|
||||
}
|
||||
|
||||
int size = (buff[3] >> 4) + 1;
|
||||
int offset = buff[4] << 8 | buff[5];
|
||||
var size = (buff[3] >> 4) + 1;
|
||||
var offset = buff[4] << 8 | buff[5];
|
||||
|
||||
Array.Copy(buff, 6, _ReadBuff, offset - _Address, size);
|
||||
|
||||
if (_Address + _Size == offset + size)
|
||||
{
|
||||
_ReadDone.Set();
|
||||
}
|
||||
}
|
||||
|
||||
private byte _RumbleBit
|
||||
@@ -547,9 +583,11 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
private bool _ReadCalibration()
|
||||
{
|
||||
// this appears to change the report type to 0x31
|
||||
byte[] buff = _ReadData(0x0016, 7);
|
||||
var buff = _ReadData(0x0016, 7);
|
||||
if (buff == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_WiiMoteState.AccelCalibrationInfo.X0 = buff[0];
|
||||
_WiiMoteState.AccelCalibrationInfo.Y0 = buff[1];
|
||||
@@ -583,36 +621,37 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
switch (sensitivity)
|
||||
{
|
||||
case EIRSensitivity.Level1:
|
||||
_WriteData(_RegisterIRSensitivity1, 9, new byte[] {0x02, 0x00, 0x00, 0x71, 0x01, 0x00, 0x64, 0x00, 0xfe});
|
||||
_WriteData(_RegisterIRSensitivity1, 9, new byte[] { 0x02, 0x00, 0x00, 0x71, 0x01, 0x00, 0x64, 0x00, 0xfe });
|
||||
Thread.Sleep(50);
|
||||
_WriteData(_RegisterIRSensitivity2, 2, new byte[] {0xfd, 0x05});
|
||||
_WriteData(_RegisterIRSensitivity2, 2, new byte[] { 0xfd, 0x05 });
|
||||
break;
|
||||
case EIRSensitivity.Level2:
|
||||
_WriteData(_RegisterIRSensitivity1, 9, new byte[] {0x02, 0x00, 0x00, 0x71, 0x01, 0x00, 0x96, 0x00, 0xb4});
|
||||
_WriteData(_RegisterIRSensitivity1, 9, new byte[] { 0x02, 0x00, 0x00, 0x71, 0x01, 0x00, 0x96, 0x00, 0xb4 });
|
||||
Thread.Sleep(50);
|
||||
_WriteData(_RegisterIRSensitivity2, 2, new byte[] {0xb3, 0x04});
|
||||
_WriteData(_RegisterIRSensitivity2, 2, new byte[] { 0xb3, 0x04 });
|
||||
break;
|
||||
case EIRSensitivity.Level3:
|
||||
_WriteData(_RegisterIRSensitivity1, 9, new byte[] {0x02, 0x00, 0x00, 0x71, 0x01, 0x00, 0xaa, 0x00, 0x64});
|
||||
_WriteData(_RegisterIRSensitivity1, 9, new byte[] { 0x02, 0x00, 0x00, 0x71, 0x01, 0x00, 0xaa, 0x00, 0x64 });
|
||||
Thread.Sleep(50);
|
||||
_WriteData(_RegisterIRSensitivity2, 2, new byte[] {0x63, 0x03});
|
||||
_WriteData(_RegisterIRSensitivity2, 2, new byte[] { 0x63, 0x03 });
|
||||
break;
|
||||
case EIRSensitivity.Level4:
|
||||
_WriteData(_RegisterIRSensitivity1, 9, new byte[] {0x02, 0x00, 0x00, 0x71, 0x01, 0x00, 0xc8, 0x00, 0x36});
|
||||
_WriteData(_RegisterIRSensitivity1, 9, new byte[] { 0x02, 0x00, 0x00, 0x71, 0x01, 0x00, 0xc8, 0x00, 0x36 });
|
||||
Thread.Sleep(50);
|
||||
_WriteData(_RegisterIRSensitivity2, 2, new byte[] {0x35, 0x03});
|
||||
_WriteData(_RegisterIRSensitivity2, 2, new byte[] { 0x35, 0x03 });
|
||||
break;
|
||||
case EIRSensitivity.Level5:
|
||||
_WriteData(_RegisterIRSensitivity1, 9, new byte[] {0x07, 0x00, 0x00, 0x71, 0x01, 0x00, 0x72, 0x00, 0x20});
|
||||
_WriteData(_RegisterIRSensitivity1, 9, new byte[] { 0x07, 0x00, 0x00, 0x71, 0x01, 0x00, 0x72, 0x00, 0x20 });
|
||||
Thread.Sleep(50);
|
||||
_WriteData(_RegisterIRSensitivity2, 2, new byte[] {0x1, 0x03});
|
||||
_WriteData(_RegisterIRSensitivity2, 2, new byte[] { 0x1, 0x03 });
|
||||
break;
|
||||
case EIRSensitivity.Max:
|
||||
_WriteData(_RegisterIRSensitivity1, 9, new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x41});
|
||||
_WriteData(_RegisterIRSensitivity1, 9, new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x41 });
|
||||
Thread.Sleep(50);
|
||||
_WriteData(_RegisterIRSensitivity2, 2, new byte[] {0x40, 0x00});
|
||||
_WriteData(_RegisterIRSensitivity2, 2, new byte[] { 0x40, 0x00 });
|
||||
break;
|
||||
}
|
||||
|
||||
Thread.Sleep(50);
|
||||
_WriteData(_RegisterIRMode, (byte)mode);
|
||||
Thread.Sleep(50);
|
||||
@@ -670,7 +709,7 @@ namespace Vocaluxe.Lib.Input.WiiMote
|
||||
|
||||
private void _WriteData(int address, byte data)
|
||||
{
|
||||
_WriteData(address, 1, new byte[] {data});
|
||||
_WriteData(address, 1, new byte[] { data });
|
||||
}
|
||||
|
||||
private void _WriteData(int address, byte size, byte[] buff)
|
||||
|
||||
@@ -23,7 +23,6 @@ using Vocaluxe.Base;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Log;
|
||||
using VocaluxeLib.Menu;
|
||||
using VocaluxeLib.Songs;
|
||||
using VocaluxeLib.Xml;
|
||||
|
||||
namespace Vocaluxe.Lib.Playlist
|
||||
@@ -35,33 +34,37 @@ namespace Vocaluxe.Lib.Playlist
|
||||
public readonly int Id;
|
||||
public List<CPlaylistSong> Songs = new List<CPlaylistSong>();
|
||||
|
||||
private static int _NextID;
|
||||
private static int _NextId;
|
||||
|
||||
public CPlaylistFile()
|
||||
{
|
||||
Id = _NextID++;
|
||||
Id = _NextId++;
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
if (string.IsNullOrEmpty(File))
|
||||
{
|
||||
string filename = string.Empty;
|
||||
var filename = string.Empty;
|
||||
// ReSharper disable LoopCanBeConvertedToQuery
|
||||
foreach (char chr in Name)
|
||||
foreach (var chr in Name)
|
||||
// ReSharper restore LoopCanBeConvertedToQuery
|
||||
{
|
||||
if (char.IsLetter(chr))
|
||||
{
|
||||
filename += chr.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
if (filename == "")
|
||||
{
|
||||
filename = "1";
|
||||
}
|
||||
|
||||
File = CHelper.GetUniqueFileName(Path.Combine(CSettings.DataFolder, CConfig.FolderPlaylists), filename + ".xml");
|
||||
}
|
||||
|
||||
SPlaylist data = new SPlaylist {Info = {Name = Name}, Songs = Songs.Select(plSong => plSong.ToStruct()).ToArray()};
|
||||
var data = new SPlaylist { Info = { Name = Name }, Songs = Songs.Select(plSong => plSong.ToStruct()).ToArray() };
|
||||
|
||||
var xml = new CXmlSerializer();
|
||||
xml.Serialize(File, data);
|
||||
@@ -81,36 +84,40 @@ namespace Vocaluxe.Lib.Playlist
|
||||
CLog.Error("Cannot load playlist from " + file + ": " + e.Message);
|
||||
return false;
|
||||
}
|
||||
|
||||
Name = data.Info.Name;
|
||||
Songs = new List<CPlaylistSong>();
|
||||
foreach (SPlaylistSong songEntry in data.Songs)
|
||||
foreach (var songEntry in data.Songs)
|
||||
{
|
||||
CSong plSong = CSongs.AllSongs.FirstOrDefault(song => song.Artist == songEntry.Artist && song.Title == songEntry.Title);
|
||||
var plSong = CSongs.AllSongs.FirstOrDefault(song => song.Artist == songEntry.Artist && song.Title == songEntry.Title);
|
||||
if (plSong == null)
|
||||
{
|
||||
CLog.Error("Can't find song '" + songEntry.Title + "' from '" + songEntry.Artist + "' in playlist file: " + File);
|
||||
}
|
||||
else
|
||||
{
|
||||
var playlistSong = new CPlaylistSong(plSong.ID, songEntry.GameMode);
|
||||
var playlistSong = new CPlaylistSong(plSong.Id, songEntry.GameMode);
|
||||
Songs.Add(playlistSong);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void AddSong(int songID)
|
||||
public void AddSong(int songId)
|
||||
{
|
||||
var song = new CPlaylistSong
|
||||
{
|
||||
SongID = songID,
|
||||
GameMode = CSongs.GetSong(songID).IsGameModeAvailable(EGameMode.TR_GAMEMODE_DUET) ? EGameMode.TR_GAMEMODE_DUET : EGameMode.TR_GAMEMODE_NORMAL
|
||||
};
|
||||
{
|
||||
SongId = songId,
|
||||
GameMode = CSongs.GetSong(songId).IsGameModeAvailable(EGameMode.TR_GAMEMODE_DUET) ? EGameMode.TR_GAMEMODE_DUET : EGameMode.TR_GAMEMODE_NORMAL
|
||||
};
|
||||
|
||||
Songs.Add(song);
|
||||
}
|
||||
|
||||
public void AddSong(int songID, EGameMode gm)
|
||||
public void AddSong(int songId, EGameMode gm)
|
||||
{
|
||||
var song = new CPlaylistSong(songID, gm);
|
||||
var song = new CPlaylistSong(songId, gm);
|
||||
|
||||
Songs.Add(song);
|
||||
}
|
||||
@@ -123,31 +130,39 @@ namespace Vocaluxe.Lib.Playlist
|
||||
public void MoveSongUp(int songNr)
|
||||
{
|
||||
if (songNr < Songs.Count && songNr > 0)
|
||||
{
|
||||
Songs.Reverse(songNr - 1, 2);
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveSongDown(int songNr)
|
||||
{
|
||||
if (songNr < Songs.Count - 1 && songNr >= 0)
|
||||
{
|
||||
Songs.Reverse(songNr, 2);
|
||||
}
|
||||
}
|
||||
|
||||
public void MoveSong(int sourceNr, int destNr)
|
||||
{
|
||||
if (sourceNr < 0 || destNr < 0 || sourceNr == destNr || sourceNr >= Songs.Count || destNr >= Songs.Count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CPlaylistSong song = Songs[sourceNr];
|
||||
var song = Songs[sourceNr];
|
||||
Songs.RemoveAt(sourceNr);
|
||||
Songs.Insert(destNr, song);
|
||||
}
|
||||
|
||||
public void InsertSong(int destNr, int songID, EGameMode gm)
|
||||
public void InsertSong(int destNr, int songId, EGameMode gm)
|
||||
{
|
||||
if (destNr < 0 || destNr >= Songs.Count)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CPlaylistSong ps = new CPlaylistSong(songID, gm);
|
||||
var ps = new CPlaylistSong(songId, gm);
|
||||
Songs.Insert(destNr, ps);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using PortAudioSharp;
|
||||
using Vocaluxe.Base;
|
||||
using VocaluxeLib.Log;
|
||||
|
||||
namespace Vocaluxe.Lib.Sound
|
||||
@@ -49,8 +48,11 @@ namespace Vocaluxe.Lib.Sound
|
||||
if (_RefCount == 0)
|
||||
{
|
||||
if (CheckError("Initialize", PortAudio.Pa_Initialize()))
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
|
||||
_RefCount++;
|
||||
}
|
||||
}
|
||||
@@ -63,10 +65,14 @@ namespace Vocaluxe.Lib.Sound
|
||||
private void _Dispose(bool disposing)
|
||||
{
|
||||
if (_Disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!disposing)
|
||||
{
|
||||
CLog.Debug("Did not close CPortAudioHandle");
|
||||
}
|
||||
|
||||
IntPtr[] streamsToClose;
|
||||
lock (_Mutex)
|
||||
@@ -75,15 +81,21 @@ namespace Vocaluxe.Lib.Sound
|
||||
}
|
||||
|
||||
if (streamsToClose.Length > 0)
|
||||
{
|
||||
CLog.Debug("Did not close " + streamsToClose.Length + " PortAudio-Stream(s)");
|
||||
}
|
||||
|
||||
foreach (IntPtr stream in streamsToClose)
|
||||
foreach (var stream in streamsToClose)
|
||||
{
|
||||
CloseStream(stream);
|
||||
}
|
||||
|
||||
lock (_Mutex)
|
||||
{
|
||||
if (_Disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Assert(_RefCount > 0);
|
||||
_RefCount--;
|
||||
@@ -119,18 +131,23 @@ namespace Vocaluxe.Lib.Sound
|
||||
}
|
||||
|
||||
public PortAudio.PaError OpenStream(out IntPtr stream, ref PortAudio.PaStreamParameters? inputParameters, ref PortAudio.PaStreamParameters? outputParameters,
|
||||
double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags,
|
||||
PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData)
|
||||
double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags,
|
||||
PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData)
|
||||
{
|
||||
lock (_Mutex)
|
||||
{
|
||||
if (_Disposed)
|
||||
{
|
||||
throw new ObjectDisposedException("PortAudioHandle already disposed");
|
||||
}
|
||||
|
||||
PortAudio.PaError res = PortAudio.Pa_OpenStream(out stream, ref inputParameters, ref outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback,
|
||||
userData);
|
||||
var res = PortAudio.Pa_OpenStream(out stream, ref inputParameters, ref outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback,
|
||||
userData);
|
||||
if (res == PortAudio.PaError.paNoError)
|
||||
{
|
||||
_Streams.Add(stream);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -147,13 +164,13 @@ namespace Vocaluxe.Lib.Sound
|
||||
/// <param name="userData"></param>
|
||||
/// <returns>True on success</returns>
|
||||
public bool OpenInputStream(out IntPtr stream, ref PortAudio.PaStreamParameters? inputParameters,
|
||||
double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags,
|
||||
PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData)
|
||||
double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags,
|
||||
PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData)
|
||||
{
|
||||
PortAudio.PaStreamParameters? outputParameters = null;
|
||||
return
|
||||
!CheckError("OpenInputStream",
|
||||
OpenStream(out stream, ref inputParameters, ref outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData));
|
||||
OpenStream(out stream, ref inputParameters, ref outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -168,13 +185,13 @@ namespace Vocaluxe.Lib.Sound
|
||||
/// <param name="userData"></param>
|
||||
/// <returns>True on success</returns>
|
||||
public bool OpenOutputStream(out IntPtr stream, ref PortAudio.PaStreamParameters? outputParameters,
|
||||
double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags,
|
||||
PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData)
|
||||
double sampleRate, uint framesPerBuffer, PortAudio.PaStreamFlags streamFlags,
|
||||
PortAudio.PaStreamCallbackDelegate streamCallback, IntPtr userData)
|
||||
{
|
||||
PortAudio.PaStreamParameters? inputParameters = null;
|
||||
return
|
||||
!CheckError("OpenOutputStream",
|
||||
OpenStream(out stream, ref inputParameters, ref outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData));
|
||||
OpenStream(out stream, ref inputParameters, ref outputParameters, sampleRate, framesPerBuffer, streamFlags, streamCallback, userData));
|
||||
}
|
||||
|
||||
public void CloseStream(IntPtr stream)
|
||||
@@ -182,7 +199,9 @@ namespace Vocaluxe.Lib.Sound
|
||||
lock (_Mutex)
|
||||
{
|
||||
if (_Disposed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (stream == IntPtr.Zero)
|
||||
{
|
||||
@@ -190,7 +209,7 @@ namespace Vocaluxe.Lib.Sound
|
||||
return;
|
||||
}
|
||||
|
||||
bool wasTracked = _Streams.Remove(stream);
|
||||
var wasTracked = _Streams.Remove(stream);
|
||||
if (!wasTracked)
|
||||
{
|
||||
CLog.Debug("Stream was already removed or never tracked, skipping duplicate close.");
|
||||
@@ -201,10 +220,10 @@ namespace Vocaluxe.Lib.Sound
|
||||
{
|
||||
try
|
||||
{
|
||||
PortAudio.PaError isStoppedResult = PortAudio.Pa_IsStreamStopped(stream);
|
||||
var isStoppedResult = PortAudio.Pa_IsStreamStopped(stream);
|
||||
if (isStoppedResult == PortAudio.PaError.paStreamIsNotStopped)
|
||||
{
|
||||
PortAudio.PaError stopResult = PortAudio.Pa_StopStream(stream);
|
||||
var stopResult = PortAudio.Pa_StopStream(stream);
|
||||
if (stopResult != PortAudio.PaError.paNoError &&
|
||||
stopResult != PortAudio.PaError.paStreamIsStopped)
|
||||
{
|
||||
@@ -217,9 +236,11 @@ namespace Vocaluxe.Lib.Sound
|
||||
CLog.Error(ex, "Error stopping stream before close:");
|
||||
}
|
||||
|
||||
PortAudio.PaError closeResult = PortAudio.Pa_CloseStream(stream);
|
||||
var closeResult = PortAudio.Pa_CloseStream(stream);
|
||||
if (closeResult != PortAudio.PaError.paNoError)
|
||||
{
|
||||
CLog.Error("CloseStream error: " + PortAudio.Pa_GetErrorText(closeResult));
|
||||
}
|
||||
}
|
||||
catch (AccessViolationException ex)
|
||||
{
|
||||
@@ -242,18 +263,21 @@ namespace Vocaluxe.Lib.Sound
|
||||
public bool CheckError(String action, PortAudio.PaError errorCode)
|
||||
{
|
||||
if (_Disposed)
|
||||
{
|
||||
throw new ObjectDisposedException("PortAudioHandle already disposed");
|
||||
}
|
||||
|
||||
if (errorCode != PortAudio.PaError.paNoError)
|
||||
{
|
||||
CLog.Error(action + " error: " + PortAudio.Pa_GetErrorText(errorCode));
|
||||
if (errorCode == PortAudio.PaError.paUnanticipatedHostError)
|
||||
{
|
||||
PortAudio.PaHostErrorInfo errorInfo = PortAudio.Pa_GetLastHostErrorInfo();
|
||||
var errorInfo = PortAudio.Pa_GetLastHostErrorInfo();
|
||||
CLog.Error("- Host error API type: " + errorInfo.hostApiType);
|
||||
CLog.Error("- Host error code: " + errorInfo.errorCode);
|
||||
CLog.Error("- Host error text: " + errorInfo.errorText);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -267,18 +291,23 @@ namespace Vocaluxe.Lib.Sound
|
||||
public int GetHostApi()
|
||||
{
|
||||
if (_Disposed)
|
||||
throw new ObjectDisposedException("PortAudioHandle already disposed");
|
||||
|
||||
int selectedHostApi = PortAudio.Pa_GetDefaultHostApi();
|
||||
int apiCount = PortAudio.Pa_GetHostApiCount();
|
||||
for (int i = 0; i < apiCount; i++)
|
||||
{
|
||||
PortAudio.PaHostApiInfo apiInfo = PortAudio.Pa_GetHostApiInfo(i);
|
||||
if ((apiInfo.type == PortAudio.PaHostApiTypeId.paDirectSound)
|
||||
|| (apiInfo.type == PortAudio.PaHostApiTypeId.paALSA))
|
||||
selectedHostApi = i;
|
||||
throw new ObjectDisposedException("PortAudioHandle already disposed");
|
||||
}
|
||||
|
||||
var selectedHostApi = PortAudio.Pa_GetDefaultHostApi();
|
||||
var apiCount = PortAudio.Pa_GetHostApiCount();
|
||||
for (var i = 0; i < apiCount; i++)
|
||||
{
|
||||
var apiInfo = PortAudio.Pa_GetHostApiInfo(i);
|
||||
if (apiInfo.type == PortAudio.PaHostApiTypeId.paDirectSound
|
||||
|| apiInfo.type == PortAudio.PaHostApiTypeId.paALSA)
|
||||
{
|
||||
selectedHostApi = i;
|
||||
}
|
||||
}
|
||||
|
||||
return selectedHostApi;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Vocaluxe.Lib.Sound
|
||||
{
|
||||
@@ -11,4 +8,4 @@ namespace Vocaluxe.Lib.Sound
|
||||
None = 0,
|
||||
Karaoke = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,6 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
{
|
||||
abstract class CAudioStreamBase : IAudioStream
|
||||
{
|
||||
private readonly int _ID;
|
||||
protected readonly string _Medium;
|
||||
protected readonly bool _Loop;
|
||||
protected readonly EAudioEffect _Effect;
|
||||
@@ -33,10 +32,7 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
protected EStreamAction _AfterFadeAction = EStreamAction.Nothing;
|
||||
protected CFading _Fading;
|
||||
|
||||
public int ID
|
||||
{
|
||||
get { return _ID; }
|
||||
}
|
||||
public int Id { get; }
|
||||
|
||||
public bool IsFading
|
||||
{
|
||||
@@ -52,7 +48,7 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
|
||||
protected CAudioStreamBase(int id, string medium, bool loop, EAudioEffect effect = EAudioEffect.None)
|
||||
{
|
||||
_ID = id;
|
||||
Id = id;
|
||||
_Medium = medium;
|
||||
_Loop = loop;
|
||||
_Effect = effect;
|
||||
@@ -72,7 +68,9 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
protected virtual void _Dispose(bool disposing)
|
||||
{
|
||||
if (!disposing)
|
||||
{
|
||||
CLog.Debug("Audio stream " + _Medium + " was not closed.");
|
||||
}
|
||||
}
|
||||
|
||||
public void Close()
|
||||
@@ -116,6 +114,7 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
IsPaused = true;
|
||||
break;
|
||||
}
|
||||
|
||||
_Fading = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
protected readonly List<IAudioStream> _Streams = new List<IAudioStream>();
|
||||
private readonly List<IAudioStream> _StreamsToDelete = new List<IAudioStream>();
|
||||
private bool _InUpdate;
|
||||
private int _NextID;
|
||||
private int _NextId;
|
||||
protected float _GlobalVolume = 1f;
|
||||
|
||||
public abstract bool Init();
|
||||
@@ -36,56 +36,82 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
public virtual void Close()
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return;
|
||||
List<IAudioStream> streams = new List<IAudioStream>();
|
||||
}
|
||||
|
||||
var streams = new List<IAudioStream>();
|
||||
//Get all streams but do not modify list without holding the lock
|
||||
//Calling dispose from within the lock may deadlock in closeproc (if a thread is already there)
|
||||
lock (_Streams)
|
||||
{
|
||||
streams.AddRange(_Streams);
|
||||
}
|
||||
foreach (IAudioStream stream in streams)
|
||||
|
||||
foreach (var stream in streams)
|
||||
{
|
||||
stream.Dispose();
|
||||
}
|
||||
|
||||
while (_Streams.Count > 0)
|
||||
{
|
||||
Thread.Sleep(5);
|
||||
}
|
||||
|
||||
_Initialized = false;
|
||||
}
|
||||
|
||||
public void CloseAll()
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_Streams)
|
||||
{
|
||||
foreach (IAudioStream stream in _Streams)
|
||||
foreach (var stream in _Streams)
|
||||
{
|
||||
stream.Close();
|
||||
}
|
||||
|
||||
_Streams.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public int GetGlobalVolume()
|
||||
{
|
||||
return (_Initialized) ? (int) Math.Round(_GlobalVolume * 100) : 100;
|
||||
return _Initialized ? (int)Math.Round(_GlobalVolume * 100) : 100;
|
||||
}
|
||||
|
||||
public void SetGlobalVolume(int volume)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return;
|
||||
float volumeF = volume.Clamp(0, 100) / 100f;
|
||||
}
|
||||
|
||||
var volumeF = volume.Clamp(0, 100) / 100f;
|
||||
lock (_Streams)
|
||||
{
|
||||
foreach (IAudioStream stream in _Streams)
|
||||
foreach (var stream in _Streams)
|
||||
{
|
||||
if (!stream.IsFading)
|
||||
{
|
||||
stream.VolumeMax = volumeF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_GlobalVolume = volumeF;
|
||||
}
|
||||
|
||||
public int GetStreamCount()
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
lock (_Streams)
|
||||
{
|
||||
@@ -96,19 +122,28 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
public void Update()
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_Streams)
|
||||
{
|
||||
_InUpdate = true;
|
||||
foreach (IAudioStream stream in _Streams)
|
||||
foreach (var stream in _Streams)
|
||||
{
|
||||
stream.Update();
|
||||
}
|
||||
|
||||
//This is required because a stream may call the close listener from inside the update method
|
||||
//lock() only protects from different threads not from the same, so we use StreamsToDelete to not modify _Streams while iterating it
|
||||
_InUpdate = false;
|
||||
if (_StreamsToDelete.Count > 0)
|
||||
{
|
||||
foreach (IAudioStream stream in _StreamsToDelete)
|
||||
foreach (var stream in _StreamsToDelete)
|
||||
{
|
||||
_Streams.Remove(stream);
|
||||
}
|
||||
|
||||
_StreamsToDelete.Clear();
|
||||
}
|
||||
}
|
||||
@@ -121,8 +156,11 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
public int Load(string medium, bool loop = false, bool prescan = false, EAudioEffect effect = EAudioEffect.None)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return -1;
|
||||
IAudioStream stream = _CreateStream(_NextID++, medium, loop, effect);
|
||||
}
|
||||
|
||||
var stream = _CreateStream(_NextId++, medium, loop, effect);
|
||||
|
||||
if (stream.Open(prescan))
|
||||
{
|
||||
@@ -132,153 +170,216 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
stream.VolumeMax = _GlobalVolume;
|
||||
stream.SetOnCloseListener(this);
|
||||
_Streams.Add(stream);
|
||||
return stream.ID;
|
||||
return stream.Id;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void Close(int streamID)
|
||||
public void Close(int streamId)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_Streams)
|
||||
{
|
||||
int index = _GetStreamIndex(streamID);
|
||||
var index = _GetStreamIndex(streamId);
|
||||
if (index >= 0)
|
||||
_Streams[index].Close();
|
||||
}
|
||||
}
|
||||
|
||||
public void Play(int streamID)
|
||||
{
|
||||
if (!_Initialized)
|
||||
return;
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamID))
|
||||
_Streams[_GetStreamIndex(streamID)].Play();
|
||||
}
|
||||
}
|
||||
|
||||
public void Pause(int streamID)
|
||||
{
|
||||
if (!_Initialized)
|
||||
return;
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamID))
|
||||
_Streams[_GetStreamIndex(streamID)].IsPaused = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop(int streamID)
|
||||
{
|
||||
if (!_Initialized)
|
||||
return;
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamID))
|
||||
_Streams[_GetStreamIndex(streamID)].Stop();
|
||||
}
|
||||
}
|
||||
|
||||
public void Fade(int streamID, int targetVolume, float seconds, EStreamAction afterFadeAction = EStreamAction.Nothing)
|
||||
{
|
||||
if (!_Initialized)
|
||||
return;
|
||||
float targetVolumeF = targetVolume.Clamp(0, 100) / 100f;
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamID))
|
||||
_Streams[_GetStreamIndex(streamID)].Fade(targetVolumeF, seconds, afterFadeAction);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetStreamVolume(int streamID, int volume)
|
||||
{
|
||||
if (!_Initialized)
|
||||
return;
|
||||
float volumeF = volume.Clamp(0, 100) / 100f;
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamID))
|
||||
{
|
||||
_Streams[_GetStreamIndex(streamID)].Volume = volumeF;
|
||||
_Streams[_GetStreamIndex(streamID)].CancelFading();
|
||||
_Streams[index].Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float GetLength(int streamID)
|
||||
public void Play(int streamId)
|
||||
{
|
||||
if (!_Initialized)
|
||||
return -1f;
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamID))
|
||||
return _Streams[_GetStreamIndex(streamID)].Length;
|
||||
}
|
||||
return -1f;
|
||||
}
|
||||
|
||||
public float GetPosition(int streamID)
|
||||
{
|
||||
if (!_Initialized)
|
||||
return -1f;
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamID))
|
||||
return _Streams[_GetStreamIndex(streamID)].Position;
|
||||
}
|
||||
|
||||
return -1f;
|
||||
}
|
||||
|
||||
public void SetPosition(int streamID, float position)
|
||||
{
|
||||
if (!_Initialized)
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamID))
|
||||
_Streams[_GetStreamIndex(streamID)].Position = position;
|
||||
if (_StreamExists(streamId))
|
||||
{
|
||||
_Streams[_GetStreamIndex(streamId)].Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPlaying(int streamID)
|
||||
public void Pause(int streamId)
|
||||
{
|
||||
if (!_Initialized)
|
||||
return false;
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamID))
|
||||
return !_Streams[_GetStreamIndex(streamID)].IsPaused && !_Streams[_GetStreamIndex(streamID)].IsFinished;
|
||||
if (_StreamExists(streamId))
|
||||
{
|
||||
_Streams[_GetStreamIndex(streamId)].IsPaused = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Stop(int streamId)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamId))
|
||||
{
|
||||
_Streams[_GetStreamIndex(streamId)].Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Fade(int streamId, int targetVolume, float seconds, EStreamAction afterFadeAction = EStreamAction.Nothing)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var targetVolumeF = targetVolume.Clamp(0, 100) / 100f;
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamId))
|
||||
{
|
||||
_Streams[_GetStreamIndex(streamId)].Fade(targetVolumeF, seconds, afterFadeAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetStreamVolume(int streamId, int volume)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var volumeF = volume.Clamp(0, 100) / 100f;
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamId))
|
||||
{
|
||||
_Streams[_GetStreamIndex(streamId)].Volume = volumeF;
|
||||
_Streams[_GetStreamIndex(streamId)].CancelFading();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public float GetLength(int streamId)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamId))
|
||||
{
|
||||
return _Streams[_GetStreamIndex(streamId)].Length;
|
||||
}
|
||||
}
|
||||
|
||||
return -1f;
|
||||
}
|
||||
|
||||
public float GetPosition(int streamId)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return -1f;
|
||||
}
|
||||
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamId))
|
||||
{
|
||||
return _Streams[_GetStreamIndex(streamId)].Position;
|
||||
}
|
||||
}
|
||||
|
||||
return -1f;
|
||||
}
|
||||
|
||||
public void SetPosition(int streamId, float position)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamId))
|
||||
{
|
||||
_Streams[_GetStreamIndex(streamId)].Position = position;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsPlaying(int streamId)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamId))
|
||||
{
|
||||
return !_Streams[_GetStreamIndex(streamId)].IsPaused && !_Streams[_GetStreamIndex(streamId)].IsFinished;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsPaused(int streamID)
|
||||
public bool IsPaused(int streamId)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamID))
|
||||
return _Streams[_GetStreamIndex(streamID)].IsPaused;
|
||||
if (_StreamExists(streamId))
|
||||
{
|
||||
return _Streams[_GetStreamIndex(streamId)].IsPaused;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool IsFinished(int streamID)
|
||||
public bool IsFinished(int streamId)
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_StreamExists(streamID))
|
||||
return _Streams[_GetStreamIndex(streamID)].IsFinished;
|
||||
if (_StreamExists(streamId))
|
||||
{
|
||||
return _Streams[_GetStreamIndex(streamId)].IsFinished;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -286,26 +387,29 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
/// Returns true if stream with given id is found
|
||||
/// MUST hold _Stream-lock
|
||||
/// </summary>
|
||||
/// <param name="streamID">Stream id</param>
|
||||
/// <param name="streamId">Stream id</param>
|
||||
/// <returns></returns>
|
||||
protected bool _StreamExists(int streamID)
|
||||
protected bool _StreamExists(int streamId)
|
||||
{
|
||||
return _GetStreamIndex(streamID) != -1;
|
||||
return _GetStreamIndex(streamId) != -1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of the stream with the given id
|
||||
/// MUST hold _Stream-lock
|
||||
/// </summary>
|
||||
/// <param name="streamID">Stream id</param>
|
||||
/// <param name="streamId">Stream id</param>
|
||||
/// <returns></returns>
|
||||
protected int _GetStreamIndex(int streamID)
|
||||
protected int _GetStreamIndex(int streamId)
|
||||
{
|
||||
for (int i = 0; i < _Streams.Count; i++)
|
||||
for (var i = 0; i < _Streams.Count; i++)
|
||||
{
|
||||
if (_Streams[i].ID == streamID)
|
||||
if (_Streams[i].Id == streamId)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
#endregion Stream Handling
|
||||
@@ -315,10 +419,14 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
lock (_Streams)
|
||||
{
|
||||
if (_InUpdate) //This is only possible if this is called from inside the update method
|
||||
{
|
||||
_StreamsToDelete.Add(stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
_Streams.Remove(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -25,12 +25,8 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
private readonly int _Size;
|
||||
private int _ReadPos;
|
||||
private int _WritePos;
|
||||
private int _BytesNotRead;
|
||||
|
||||
public int BytesNotRead
|
||||
{
|
||||
get { return _BytesNotRead; }
|
||||
}
|
||||
public int BytesNotRead { get; private set; }
|
||||
|
||||
public CRingBuffer(int size)
|
||||
{
|
||||
@@ -43,17 +39,20 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
{
|
||||
_ReadPos = 0;
|
||||
_WritePos = 0;
|
||||
_BytesNotRead = 0;
|
||||
BytesNotRead = 0;
|
||||
}
|
||||
|
||||
public void Write(byte[] data)
|
||||
{
|
||||
int start = 0;
|
||||
int end = data.Length;
|
||||
var start = 0;
|
||||
var end = data.Length;
|
||||
if (end - start > _Size)
|
||||
{
|
||||
start = end - _Size;
|
||||
int lenTotal = end - start;
|
||||
int len = Math.Min(lenTotal, _Size - _WritePos);
|
||||
}
|
||||
|
||||
var lenTotal = end - start;
|
||||
var len = Math.Min(lenTotal, _Size - _WritePos);
|
||||
Buffer.BlockCopy(data, start, _Data, _WritePos, len);
|
||||
_WritePos += len;
|
||||
if (_WritePos >= _Size)
|
||||
@@ -67,22 +66,25 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
_WritePos += len;
|
||||
}
|
||||
}
|
||||
_BytesNotRead += lenTotal;
|
||||
|
||||
BytesNotRead += lenTotal;
|
||||
}
|
||||
|
||||
public void Read(byte[] data)
|
||||
{
|
||||
int lenTotal = Math.Min(data.Length, _BytesNotRead);
|
||||
var lenTotal = Math.Min(data.Length, BytesNotRead);
|
||||
if (lenTotal == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int len = Math.Min(lenTotal, _Size - _ReadPos);
|
||||
var len = Math.Min(lenTotal, _Size - _ReadPos);
|
||||
Buffer.BlockCopy(_Data, _ReadPos, data, 0, len);
|
||||
_ReadPos += len;
|
||||
if (_ReadPos >= _Size)
|
||||
{
|
||||
_ReadPos = 0;
|
||||
int start = len;
|
||||
var start = len;
|
||||
len = lenTotal - len;
|
||||
if (len > 0)
|
||||
{
|
||||
@@ -90,7 +92,8 @@ namespace Vocaluxe.Lib.Sound.Playback
|
||||
_ReadPos += len;
|
||||
}
|
||||
}
|
||||
_BytesNotRead -= lenTotal;
|
||||
|
||||
BytesNotRead -= lenTotal;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,6 @@
|
||||
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using Vocaluxe.Base;
|
||||
using Vocaluxe.Lib.Video.Acinerella;
|
||||
using VocaluxeLib.Log;
|
||||
|
||||
@@ -81,11 +80,11 @@ namespace Vocaluxe.Lib.Sound.Playback.Decoder
|
||||
}
|
||||
|
||||
_FormatInfo = new SFormatInfo
|
||||
{
|
||||
SamplesPerSecond = audiodecoder.StreamInfo.AudioInfo.SamplesPerSecond,
|
||||
BitDepth = audiodecoder.StreamInfo.AudioInfo.BitDepth,
|
||||
ChannelCount = audiodecoder.StreamInfo.AudioInfo.ChannelCount
|
||||
};
|
||||
{
|
||||
SamplesPerSecond = audiodecoder.StreamInfo.AudioInfo.SamplesPerSecond,
|
||||
BitDepth = audiodecoder.StreamInfo.AudioInfo.BitDepth,
|
||||
ChannelCount = audiodecoder.StreamInfo.AudioInfo.ChannelCount
|
||||
};
|
||||
|
||||
_CurrentTime = 0f;
|
||||
|
||||
@@ -95,6 +94,7 @@ namespace Vocaluxe.Lib.Sound.Playback.Decoder
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
_FileOpened = true;
|
||||
return true;
|
||||
}
|
||||
@@ -106,6 +106,7 @@ namespace Vocaluxe.Lib.Sound.Playback.Decoder
|
||||
CAcinerella.AcFreeDecoder(_Audiodecoder);
|
||||
_Audiodecoder = IntPtr.Zero;
|
||||
}
|
||||
|
||||
if (_InstancePtr != IntPtr.Zero)
|
||||
{
|
||||
CAcinerella.AcClose(_InstancePtr);
|
||||
@@ -129,11 +130,13 @@ namespace Vocaluxe.Lib.Sound.Playback.Decoder
|
||||
public void SetPosition(float time)
|
||||
{
|
||||
if (!_FileOpened)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
CAcinerella.AcSeek(_Audiodecoder, (time > _CurrentTime) ? 0 : -1, (Int64)(time * 1000f));
|
||||
CAcinerella.AcSeek(_Audiodecoder, time > _CurrentTime ? 0 : -1, (Int64)(time * 1000f));
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -156,7 +159,7 @@ namespace Vocaluxe.Lib.Sound.Playback.Decoder
|
||||
return;
|
||||
}
|
||||
|
||||
bool frameFinished = CAcinerella.AcGetAudioFrame(_InstancePtr, _Audiodecoder);
|
||||
var frameFinished = CAcinerella.AcGetAudioFrame(_InstancePtr, _Audiodecoder);
|
||||
|
||||
if (frameFinished)
|
||||
{
|
||||
@@ -168,7 +171,9 @@ namespace Vocaluxe.Lib.Sound.Playback.Decoder
|
||||
buffer = new byte[decoder.BufferSize];
|
||||
|
||||
if (decoder.BufferSize > 0)
|
||||
{
|
||||
Marshal.Copy(decoder.Buffer, buffer, 0, buffer.Length);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -177,6 +182,6 @@ namespace Vocaluxe.Lib.Sound.Playback.Decoder
|
||||
timeStamp = 0f;
|
||||
}
|
||||
|
||||
public void Dispose() {}
|
||||
public void Dispose() { }
|
||||
}
|
||||
}
|
||||
@@ -15,10 +15,9 @@
|
||||
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
|
||||
#endregion
|
||||
|
||||
using Gst;
|
||||
using System;
|
||||
using Vocaluxe.Base;
|
||||
using System.IO;
|
||||
using Gst;
|
||||
using VocaluxeLib.Log;
|
||||
|
||||
namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
@@ -28,8 +27,10 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
public override bool Init()
|
||||
{
|
||||
if (_Initialized)
|
||||
{
|
||||
return false;
|
||||
#if WIN
|
||||
}
|
||||
#if WIN
|
||||
#if ARCH_X86
|
||||
const string varName = "GSTREAMER_1_0_ROOT_X86";
|
||||
#endif
|
||||
@@ -46,7 +47,7 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
#endif
|
||||
if (!Directory.Exists(dllDirectory))
|
||||
{
|
||||
string gstreamerEnvVar = Environment.GetEnvironmentVariable(varName, EnvironmentVariableTarget.User);
|
||||
var gstreamerEnvVar = Environment.GetEnvironmentVariable(varName, EnvironmentVariableTarget.User);
|
||||
|
||||
if (gstreamerEnvVar == null || !Directory.Exists(gstreamerEnvVar))
|
||||
{
|
||||
@@ -58,10 +59,10 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
dllDirectory = gstreamerEnvVar + "bin\\";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
COSFunctions.AddEnvironmentPath(dllDirectory);
|
||||
#endif
|
||||
#endif
|
||||
Application.Init();
|
||||
|
||||
_Initialized = Application.IsInitialized;
|
||||
@@ -71,7 +72,10 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
public override void Close()
|
||||
{
|
||||
if (!_Initialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
base.Close();
|
||||
Application.Deinit();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ using System;
|
||||
using GLib;
|
||||
using Gst;
|
||||
using Vocaluxe.Base;
|
||||
using VocaluxeLib;
|
||||
using VocaluxeLib.Log;
|
||||
|
||||
namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
@@ -62,7 +61,10 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
//TODO: Is it ok, to remove this? Gst should post a message if duration was changed so this should not be required
|
||||
// Removing would not work in some cases where length is not know at startup
|
||||
if (base.Length < 0 && _Element != null)
|
||||
{
|
||||
_UpdateDuration();
|
||||
}
|
||||
|
||||
return base.Length >= 0f ? base.Length : 0f;
|
||||
}
|
||||
}
|
||||
@@ -71,26 +73,31 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
if (_Element == null || (_Element.CurrentState == State.Paused && _Element.PendingState != State.VoidPending))
|
||||
{
|
||||
return _Position;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
long position;
|
||||
if (!_Element.QueryPosition(Format.Time, out position))
|
||||
{
|
||||
CLog.Error("Could not query position");
|
||||
}
|
||||
else
|
||||
_Position = ((float)position / Constants.SECOND);
|
||||
|
||||
|
||||
{
|
||||
_Position = (float)position / Constants.SECOND;
|
||||
}
|
||||
|
||||
|
||||
return _Position;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (_Element != null)
|
||||
{
|
||||
_Element.SeekSimple(Format.Time, SeekFlags.Accurate | SeekFlags.Flush, (long)(value * Constants.SECOND));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,28 +112,39 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
set
|
||||
{
|
||||
if (_Element != null)
|
||||
{
|
||||
_Element.SetState(value ? State.Paused : State.Playing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CGstreamerSharpAudioStream(int id, string medium, bool loop, EAudioEffect effect = EAudioEffect.None) : base(id, medium, loop, effect) {}
|
||||
public CGstreamerSharpAudioStream(int id, string medium, bool loop, EAudioEffect effect = EAudioEffect.None) : base(id, medium, loop, effect) { }
|
||||
|
||||
public override bool Open(bool prescan)
|
||||
{
|
||||
System.Diagnostics.Debug.Assert(!_FileOpened);
|
||||
if (_FileOpened)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Length = -1;
|
||||
Element convert = ElementFactory.Make("audioconvert", "convert");
|
||||
Element audiosink = ElementFactory.Make("autoaudiosink", "audiosink");
|
||||
var convert = ElementFactory.Make("audioconvert", "convert");
|
||||
var audiosink = ElementFactory.Make("autoaudiosink", "audiosink");
|
||||
|
||||
if (convert == null || audiosink == null)
|
||||
{
|
||||
CLog.Error("Could not create pipeline");
|
||||
if (convert != null)
|
||||
{
|
||||
convert.Dispose();
|
||||
}
|
||||
|
||||
if (audiosink != null)
|
||||
{
|
||||
audiosink.Dispose();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -136,13 +154,13 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
{
|
||||
audiokaraoke = ElementFactory.Make("audiokaraoke", "karaoke");
|
||||
audioSinkBin.Add(audiokaraoke);
|
||||
audioSinkBin.Add(convert);
|
||||
audioSinkBin.Add(audiosink);
|
||||
|
||||
audioSinkBin.Add(convert);
|
||||
audioSinkBin.Add(audiosink);
|
||||
|
||||
audiokaraoke.Link(audiosink);
|
||||
audiokaraoke["level"] = CConfig.Config.Sound.KaraokeEffectLevel;
|
||||
audiokaraoke["mono-level"] = CConfig.Config.Sound.KaraokeEffectLevel;
|
||||
|
||||
|
||||
convert.Link(audiokaraoke);
|
||||
}
|
||||
else
|
||||
@@ -152,10 +170,9 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
convert.Link(audiosink);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Pad pad = convert.GetStaticPad("sink");
|
||||
GhostPad ghostpad = new GhostPad("sink", pad);
|
||||
|
||||
var pad = convert.GetStaticPad("sink");
|
||||
var ghostpad = new GhostPad("sink", pad);
|
||||
|
||||
if (pad == null)
|
||||
{
|
||||
@@ -167,6 +184,7 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
{
|
||||
audiokaraoke.Dispose();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -181,8 +199,10 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
{
|
||||
audiokaraoke.Dispose();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!audioSinkBin.AddPad(ghostpad))
|
||||
{
|
||||
CLog.Error("Could not add pad");
|
||||
@@ -194,6 +214,7 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
{
|
||||
audiokaraoke.Dispose();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -209,8 +230,10 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
{
|
||||
audiokaraoke.Dispose();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
_Element["audio-sink"] = audioSinkBin;
|
||||
_Element["flags"] = 1 << 1;
|
||||
_Element["uri"] = new Uri(_Medium).AbsoluteUri;
|
||||
@@ -219,12 +242,13 @@ 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);
|
||||
var msg = _Element.Bus.TimedPopFiltered(prescan ? ulong.MaxValue : 0L, MessageType.AsyncDone | MessageType.Error);
|
||||
if (!_OnMessage(msg))
|
||||
{
|
||||
_Dispose(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
_FileOpened = true;
|
||||
return true;
|
||||
}
|
||||
@@ -232,34 +256,51 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
protected override void _Dispose(bool disposing)
|
||||
{
|
||||
if (_Element == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Element element;
|
||||
lock (_ElementLock)
|
||||
{
|
||||
//Atomic get and set
|
||||
if (_Element == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
element = _Element;
|
||||
_Element = null; //Now everything "seems" closed
|
||||
}
|
||||
|
||||
// Should not be needed but we had an error report (#226) - so we double check here to prevent a crash
|
||||
if (element == null)
|
||||
{
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
if (element.TargetState == State.Playing)
|
||||
{
|
||||
element.SetState(State.Paused); //Stop output
|
||||
}
|
||||
|
||||
if (_CloseStreamListener != null)
|
||||
{
|
||||
_CloseStreamListener.OnCloseStream(this);
|
||||
}
|
||||
|
||||
//Now really close it in the background
|
||||
var t = new System.Threading.Thread(() => _TerminateStream(element)) {Name = "GSt Terminate"};
|
||||
var t = new System.Threading.Thread(() => _TerminateStream(element)) { Name = "GSt Terminate" };
|
||||
t.Start();
|
||||
}
|
||||
|
||||
private static void _TerminateStream(Element element)
|
||||
{
|
||||
if (element == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
//One of these might take a bit, so better do this in the background to avoid lags
|
||||
element.SetState(State.Null);
|
||||
element.Dispose();
|
||||
@@ -268,33 +309,48 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
public override void Play()
|
||||
{
|
||||
if (_Element != null)
|
||||
{
|
||||
_Element.SetState(State.Playing);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
{
|
||||
if (_Element != null)
|
||||
{
|
||||
_Element.SetState(State.Ready);
|
||||
}
|
||||
|
||||
Position = 0;
|
||||
}
|
||||
|
||||
private void _SetElementVolume()
|
||||
{
|
||||
if (_Element != null)
|
||||
{
|
||||
_Element["volume"] = Volume * VolumeMax;
|
||||
}
|
||||
}
|
||||
|
||||
private bool _OnMessage(Message msg)
|
||||
{
|
||||
if (msg == null || msg.Handle == IntPtr.Zero)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (msg.Type)
|
||||
{
|
||||
case MessageType.Eos:
|
||||
if (_Loop)
|
||||
{
|
||||
Position = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
_IsFinished = true;
|
||||
}
|
||||
|
||||
break;
|
||||
case MessageType.Error:
|
||||
GException error;
|
||||
@@ -306,6 +362,7 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
_UpdateDuration();
|
||||
break;
|
||||
}
|
||||
|
||||
msg.Dispose();
|
||||
return true;
|
||||
}
|
||||
@@ -314,7 +371,9 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
{
|
||||
base.Update();
|
||||
while (_Element != null && _Element.Bus != null && _Element.Bus.HavePending())
|
||||
{
|
||||
_OnMessage(_Element.Bus.Pop());
|
||||
}
|
||||
}
|
||||
|
||||
private void _UpdateDuration()
|
||||
@@ -322,10 +381,15 @@ namespace Vocaluxe.Lib.Sound.Playback.GstreamerSharp
|
||||
lock (_ElementLock)
|
||||
{
|
||||
if (_Element == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
long duration;
|
||||
if (_Element.QueryDuration(Format.Time, out duration))
|
||||
{
|
||||
Length = duration / (float)Constants.SECOND;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loaded 100 of 236 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user