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:
Quentin Bray authored and GitHub committed 2026-06-22 19:52:06 +02:00
1 parent b9b0f7c8df
commit 6ffa63b923
236 files changed
+14194 -7278

No files matched your search

+3 -1
View File
@@ -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 -2
View File
@@ -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
View File
@@ -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>
+34 -41
View File
@@ -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
}
}
}
File diff suppressed because it is too large. Load diff
+17 -17
View File
@@ -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
}
}
}
+150 -144
View File
@@ -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
}
}
}
+39 -7
View File
@@ -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">&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;Profile name="Cleanup"&gt;&lt;CSArrangeThisQualifier&gt;True&lt;/CSArrangeThisQualifier&gt;&lt;CSRemoveCodeRedundancies&gt;True&lt;/CSRemoveCodeRedundancies&gt;&lt;CSUseVar&gt;&lt;BehavourStyle&gt;CAN_CHANGE_TO_EXPLICIT&lt;/BehavourStyle&gt;&lt;LocalVariableStyle&gt;IMPLICIT_WHEN_INITIALIZER_HAS_TYPE&lt;/LocalVariableStyle&gt;&lt;ForeachVariableStyle&gt;ALWAYS_EXPLICIT&lt;/ForeachVariableStyle&gt;&lt;/CSUseVar&gt;&lt;CSOptimizeUsings&gt;&lt;OptimizeUsings&gt;False&lt;/OptimizeUsings&gt;&lt;EmbraceInRegion&gt;False&lt;/EmbraceInRegion&gt;&lt;RegionName&gt;&lt;/RegionName&gt;&lt;/CSOptimizeUsings&gt;&lt;CSReformatCode&gt;True&lt;/CSReformatCode&gt;&lt;CSharpFormatDocComments&gt;True&lt;/CSharpFormatDocComments&gt;&lt;CSShortenReferences&gt;True&lt;/CSShortenReferences&gt;&lt;StyleCop.Documentation&gt;&lt;SA1600ElementsMustBeDocumented&gt;False&lt;/SA1600ElementsMustBeDocumented&gt;&lt;SA1604ElementDocumentationMustHaveSummary&gt;False&lt;/SA1604ElementDocumentationMustHaveSummary&gt;&lt;SA1609PropertyDocumentationMustHaveValueDocumented&gt;False&lt;/SA1609PropertyDocumentationMustHaveValueDocumented&gt;&lt;SA1611ElementParametersMustBeDocumented&gt;False&lt;/SA1611ElementParametersMustBeDocumented&gt;&lt;SA1615ElementReturnValueMustBeDocumented&gt;False&lt;/SA1615ElementReturnValueMustBeDocumented&gt;&lt;SA1617VoidReturnValueMustNotBeDocumented&gt;False&lt;/SA1617VoidReturnValueMustNotBeDocumented&gt;&lt;SA1618GenericTypeParametersMustBeDocumented&gt;False&lt;/SA1618GenericTypeParametersMustBeDocumented&gt;&lt;SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes&gt;False&lt;/SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes&gt;&lt;SA1628DocumentationTextMustBeginWithACapitalLetter&gt;False&lt;/SA1628DocumentationTextMustBeginWithACapitalLetter&gt;&lt;SA1629DocumentationTextMustEndWithAPeriod&gt;False&lt;/SA1629DocumentationTextMustEndWithAPeriod&gt;&lt;SA1633SA1641UpdateFileHeader&gt;Ignore&lt;/SA1633SA1641UpdateFileHeader&gt;&lt;SA1639FileHeaderMustHaveSummary&gt;False&lt;/SA1639FileHeaderMustHaveSummary&gt;&lt;SA1642ConstructorSummaryDocumentationMustBeginWithStandardText&gt;False&lt;/SA1642ConstructorSummaryDocumentationMustBeginWithStandardText&gt;&lt;SA1643DestructorSummaryDocumentationMustBeginWithStandardText&gt;False&lt;/SA1643DestructorSummaryDocumentationMustBeginWithStandardText&gt;&lt;SA1644DocumentationHeadersMustNotContainBlankLines&gt;False&lt;/SA1644DocumentationHeadersMustNotContainBlankLines&gt;&lt;/StyleCop.Documentation&gt;&lt;StyleCop.Layout&gt;&lt;SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine&gt;False&lt;/SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine&gt;&lt;SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine&gt;True&lt;/SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine&gt;&lt;SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine&gt;True&lt;/SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine&gt;&lt;SA1511WhileDoFooterMustNotBePrecededByBlankLine&gt;True&lt;/SA1511WhileDoFooterMustNotBePrecededByBlankLine&gt;&lt;SA1512SingleLineCommentsMustNotBeFollowedByBlankLine&gt;True&lt;/SA1512SingleLineCommentsMustNotBeFollowedByBlankLine&gt;&lt;SA1513ClosingCurlyBracketMustBeFollowedByBlankLine&gt;False&lt;/SA1513ClosingCurlyBracketMustBeFollowedByBlankLine&gt;&lt;SA1514ElementDocumentationHeaderMustBePrecededByBlankLine&gt;False&lt;/SA1514ElementDocumentationHeaderMustBePrecededByBlankLine&gt;&lt;SA1515SingleLineCommentMustBeProceededByBlankLine&gt;False&lt;/SA1515SingleLineCommentMustBeProceededByBlankLine&gt;&lt;/StyleCop.Layout&gt;&lt;StyleCop.Readability&gt;&lt;SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists&gt;True&lt;/SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists&gt;&lt;SA1106CodeMustNotContainEmptyStatements&gt;True&lt;/SA1106CodeMustNotContainEmptyStatements&gt;&lt;SA1108BlockStatementsMustNotContainEmbeddedComments&gt;True&lt;/SA1108BlockStatementsMustNotContainEmbeddedComments&gt;&lt;SA1109BlockStatementsMustNotContainEmbeddedRegions&gt;True&lt;/SA1109BlockStatementsMustNotContainEmbeddedRegions&gt;&lt;SA1120CommentsMustContainText&gt;False&lt;/SA1120CommentsMustContainText&gt;&lt;SA1121UseBuiltInTypeAlias&gt;False&lt;/SA1121UseBuiltInTypeAlias&gt;&lt;SA1122UseStringEmptyForEmptyStrings&gt;False&lt;/SA1122UseStringEmptyForEmptyStrings&gt;&lt;SA1123DoNotPlaceRegionsWithinElements&gt;False&lt;/SA1123DoNotPlaceRegionsWithinElements&gt;&lt;SA1124CodeMustNotContainEmptyRegions&gt;True&lt;/SA1124CodeMustNotContainEmptyRegions&gt;&lt;/StyleCop.Readability&gt;&lt;StyleCop.Spacing&gt;&lt;SA1001CommasMustBeSpacedCorrectly&gt;False&lt;/SA1001CommasMustBeSpacedCorrectly&gt;&lt;SA1005SingleLineCommentsMustBeginWithSingleSpace&gt;False&lt;/SA1005SingleLineCommentsMustBeginWithSingleSpace&gt;&lt;SA1006PreprocessorKeywordsMustNotBePrecededBySpace&gt;True&lt;/SA1006PreprocessorKeywordLine truncated
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Cleanup/@EntryIndexedValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;Profile name="Cleanup"&gt;&lt;CSArrangeThisQualifier&gt;True&lt;/CSArrangeThisQualifier&gt;&lt;CSRemoveCodeRedundancies&gt;True&lt;/CSRemoveCodeRedundancies&gt;&lt;CSUseVar&gt;&lt;BehavourStyle&gt;CAN_CHANGE_TO_EXPLICIT&lt;/BehavourStyle&gt;&lt;LocalVariableStyle&gt;IMPLICIT_WHEN_INITIALIZER_HAS_TYPE&lt;/LocalVariableStyle&gt;&lt;ForeachVariableStyle&gt;ALWAYS_EXPLICIT&lt;/ForeachVariableStyle&gt;&lt;/CSUseVar&gt;&lt;CSOptimizeUsings&gt;&lt;OptimizeUsings&gt;True&lt;/OptimizeUsings&gt;&lt;/CSOptimizeUsings&gt;&lt;CSReformatCode&gt;True&lt;/CSReformatCode&gt;&lt;StyleCop.Documentation&gt;&lt;SA1600ElementsMustBeDocumented&gt;False&lt;/SA1600ElementsMustBeDocumented&gt;&lt;SA1604ElementDocumentationMustHaveSummary&gt;False&lt;/SA1604ElementDocumentationMustHaveSummary&gt;&lt;SA1609PropertyDocumentationMustHaveValueDocumented&gt;False&lt;/SA1609PropertyDocumentationMustHaveValueDocumented&gt;&lt;SA1611ElementParametersMustBeDocumented&gt;False&lt;/SA1611ElementParametersMustBeDocumented&gt;&lt;SA1615ElementReturnValueMustBeDocumented&gt;False&lt;/SA1615ElementReturnValueMustBeDocumented&gt;&lt;SA1617VoidReturnValueMustNotBeDocumented&gt;False&lt;/SA1617VoidReturnValueMustNotBeDocumented&gt;&lt;SA1618GenericTypeParametersMustBeDocumented&gt;False&lt;/SA1618GenericTypeParametersMustBeDocumented&gt;&lt;SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes&gt;False&lt;/SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes&gt;&lt;SA1628DocumentationTextMustBeginWithACapitalLetter&gt;False&lt;/SA1628DocumentationTextMustBeginWithACapitalLetter&gt;&lt;SA1629DocumentationTextMustEndWithAPeriod&gt;False&lt;/SA1629DocumentationTextMustEndWithAPeriod&gt;&lt;SA1633SA1641UpdateFileHeader&gt;Ignore&lt;/SA1633SA1641UpdateFileHeader&gt;&lt;SA1639FileHeaderMustHaveSummary&gt;False&lt;/SA1639FileHeaderMustHaveSummary&gt;&lt;SA1642ConstructorSummaryDocumentationMustBeginWithStandardText&gt;False&lt;/SA1642ConstructorSummaryDocumentationMustBeginWithStandardText&gt;&lt;SA1643DestructorSummaryDocumentationMustBeginWithStandardText&gt;False&lt;/SA1643DestructorSummaryDocumentationMustBeginWithStandardText&gt;&lt;SA1644DocumentationHeadersMustNotContainBlankLines&gt;False&lt;/SA1644DocumentationHeadersMustNotContainBlankLines&gt;&lt;/StyleCop.Documentation&gt;&lt;StyleCop.Layout&gt;&lt;SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine&gt;False&lt;/SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine&gt;&lt;SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine&gt;True&lt;/SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine&gt;&lt;SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine&gt;True&lt;/SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine&gt;&lt;SA1511WhileDoFooterMustNotBePrecededByBlankLine&gt;True&lt;/SA1511WhileDoFooterMustNotBePrecededByBlankLine&gt;&lt;SA1512SingleLineCommentsMustNotBeFollowedByBlankLine&gt;True&lt;/SA1512SingleLineCommentsMustNotBeFollowedByBlankLine&gt;&lt;SA1513ClosingCurlyBracketMustBeFollowedByBlankLine&gt;False&lt;/SA1513ClosingCurlyBracketMustBeFollowedByBlankLine&gt;&lt;SA1514ElementDocumentationHeaderMustBePrecededByBlankLine&gt;False&lt;/SA1514ElementDocumentationHeaderMustBePrecededByBlankLine&gt;&lt;SA1515SingleLineCommentMustBeProceededByBlankLine&gt;False&lt;/SA1515SingleLineCommentMustBeProceededByBlankLine&gt;&lt;/StyleCop.Layout&gt;&lt;StyleCop.Readability&gt;&lt;SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists&gt;True&lt;/SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists&gt;&lt;SA1106CodeMustNotContainEmptyStatements&gt;True&lt;/SA1106CodeMustNotContainEmptyStatements&gt;&lt;SA1108BlockStatementsMustNotContainEmbeddedComments&gt;True&lt;/SA1108BlockStatementsMustNotContainEmbeddedComments&gt;&lt;SA1109BlockStatementsMustNotContainEmbeddedRegions&gt;True&lt;/SA1109BlockStatementsMustNotContainEmbeddedRegions&gt;&lt;SA1120CommentsMustContainText&gt;False&lt;/SA1120CommentsMustContainText&gt;&lt;SA1121UseBuiltInTypeAlias&gt;False&lt;/SA1121UseBuiltInTypeAlias&gt;&lt;SA1122UseStringEmptyForEmptyStrings&gt;False&lt;/SA1122UseStringEmptyForEmptyStrings&gt;&lt;SA1123DoNotPlaceRegionsWithinElements&gt;False&lt;/SA1123DoNotPlaceRegionsWithinElements&gt;&lt;SA1124CodeMustNotContainEmptyRegions&gt;True&lt;/SA1124CodeMustNotContainEmptyRegions&gt;&lt;/StyleCop.Readability&gt;&lt;StyleCop.Spacing&gt;&lt;SA1001CommasMustBeSpacedCorrectly&gt;False&lt;/SA1001CommasMustBeSpacedCorrectly&gt;&lt;SA1005SingleLineCommentsMustBeginWithSingleSpace&gt;False&lt;/SA1005SingleLineCommentsMustBeginWithSingleSpace&gt;&lt;SA1006PreprocessorKeywordsMustNotBePrecededBySpace&gt;True&lt;/SA1006PreprocessorKeywordsMustNotBePrecededBySpace&gt;&lt;SA1021NegativeSignsMustBeSpacedCorrectly&gt;True&lt;/SA1021NegativeSignsMustBeSpacedCorrectly&gt;&lt;SA1022PositiveSignsMustBeSpacedCorrectly&gt;True&lt;/SA1022PositiveSignsMustBeSpacLine truncated
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=Simple_0020Reformat/@EntryIndexedValue">&lt;?xml version="1.0" encoding="utf-16"?&gt;&lt;Profile name="Simple Reformat"&gt;&lt;CSOptimizeUsings&gt;&lt;OptimizeUsings&gt;False&lt;/OptimizeUsings&gt;&lt;EmbraceInRegion&gt;False&lt;/EmbraceInRegion&gt;&lt;RegionName&gt;&lt;/RegionName&gt;&lt;/CSOptimizeUsings&gt;&lt;CSReformatCode&gt;True&lt;/CSReformatCode&gt;&lt;StyleCop.Documentation&gt;&lt;SA1600ElementsMustBeDocumented&gt;False&lt;/SA1600ElementsMustBeDocumented&gt;&lt;SA1604ElementDocumentationMustHaveSummary&gt;False&lt;/SA1604ElementDocumentationMustHaveSummary&gt;&lt;SA1609PropertyDocumentationMustHaveValueDocumented&gt;False&lt;/SA1609PropertyDocumentationMustHaveValueDocumented&gt;&lt;SA1611ElementParametersMustBeDocumented&gt;False&lt;/SA1611ElementParametersMustBeDocumented&gt;&lt;SA1615ElementReturnValueMustBeDocumented&gt;False&lt;/SA1615ElementReturnValueMustBeDocumented&gt;&lt;SA1617VoidReturnValueMustNotBeDocumented&gt;False&lt;/SA1617VoidReturnValueMustNotBeDocumented&gt;&lt;SA1618GenericTypeParametersMustBeDocumented&gt;False&lt;/SA1618GenericTypeParametersMustBeDocumented&gt;&lt;SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes&gt;False&lt;/SA1626SingleLineCommentsMustNotUseDocumentationStyleSlashes&gt;&lt;SA1628DocumentationTextMustBeginWithACapitalLetter&gt;False&lt;/SA1628DocumentationTextMustBeginWithACapitalLetter&gt;&lt;SA1629DocumentationTextMustEndWithAPeriod&gt;False&lt;/SA1629DocumentationTextMustEndWithAPeriod&gt;&lt;SA1633SA1641UpdateFileHeader&gt;Ignore&lt;/SA1633SA1641UpdateFileHeader&gt;&lt;SA1639FileHeaderMustHaveSummary&gt;False&lt;/SA1639FileHeaderMustHaveSummary&gt;&lt;SA1642ConstructorSummaryDocumentationMustBeginWithStandardText&gt;False&lt;/SA1642ConstructorSummaryDocumentationMustBeginWithStandardText&gt;&lt;SA1643DestructorSummaryDocumentationMustBeginWithStandardText&gt;False&lt;/SA1643DestructorSummaryDocumentationMustBeginWithStandardText&gt;&lt;SA1644DocumentationHeadersMustNotContainBlankLines&gt;False&lt;/SA1644DocumentationHeadersMustNotContainBlankLines&gt;&lt;/StyleCop.Documentation&gt;&lt;StyleCop.Spacing&gt;&lt;SA1001CommasMustBeSpacedCorrectly&gt;False&lt;/SA1001CommasMustBeSpacedCorrectly&gt;&lt;SA1005SingleLineCommentsMustBeginWithSingleSpace&gt;False&lt;/SA1005SingleLineCommentsMustBeginWithSingleSpace&gt;&lt;SA1006PreprocessorKeywordsMustNotBePrecededBySpace&gt;True&lt;/SA1006PreprocessorKeywordsMustNotBePrecededBySpace&gt;&lt;SA1021NegativeSignsMustBeSpacedCorrectly&gt;True&lt;/SA1021NegativeSignsMustBeSpacedCorrectly&gt;&lt;SA1022PositiveSignsMustBeSpacedCorrectly&gt;True&lt;/SA1022PositiveSignsMustBeSpacedCorrectly&gt;&lt;SA1025CodeMustNotContainMultipleWhitespaceInARow&gt;True&lt;/SA1025CodeMustNotContainMultipleWhitespaceInARow&gt;&lt;/StyleCop.Spacing&gt;&lt;StyleCop.Readability&gt;&lt;SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists&gt;True&lt;/SA1100DoNotPrefixCallsWithBaseUnlessLocalImplementationExists&gt;&lt;SA1106CodeMustNotContainEmptyStatements&gt;True&lt;/SA1106CodeMustNotContainEmptyStatements&gt;&lt;SA1108BlockStatementsMustNotContainEmbeddedComments&gt;True&lt;/SA1108BlockStatementsMustNotContainEmbeddedComments&gt;&lt;SA1109BlockStatementsMustNotContainEmbeddedRegions&gt;True&lt;/SA1109BlockStatementsMustNotContainEmbeddedRegions&gt;&lt;SA1120CommentsMustContainText&gt;False&lt;/SA1120CommentsMustContainText&gt;&lt;SA1121UseBuiltInTypeAlias&gt;False&lt;/SA1121UseBuiltInTypeAlias&gt;&lt;SA1122UseStringEmptyForEmptyStrings&gt;False&lt;/SA1122UseStringEmptyForEmptyStrings&gt;&lt;SA1123DoNotPlaceRegionsWithinElements&gt;False&lt;/SA1123DoNotPlaceRegionsWithinElements&gt;&lt;SA1124CodeMustNotContainEmptyRegions&gt;True&lt;/SA1124CodeMustNotContainEmptyRegions&gt;&lt;/StyleCop.Readability&gt;&lt;StyleCop.Layout&gt;&lt;SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine&gt;False&lt;/SA1500CurlyBracketsForMultiLineStatementsMustNotShareLine&gt;&lt;SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine&gt;True&lt;/SA1509OpeningCurlyBracketsMustNotBePrecededByBlankLine&gt;&lt;SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine&gt;True&lt;/SA1510ChainedStatementBlocksMustNotBePrecededByBlankLine&gt;&lt;SA1511WhileDoFooterMustNotBePrecededByBlankLine&gt;True&lt;/SA1511WhileDoFooterMustNotBePrecededByBlankLine&gt;&lt;SA1512SingleLineCommentsMustNotBeFollowedByBlankLine&gt;True&lt;/SA1512SingleLineCommentsMustNotBeFollowedByBlankLine&gt;&lt;SA1513ClosingCurlyBracketMustBeFollowedByBlankLine&gt;False&lt;/SA1513ClosingCurlyBracketMustBeFollowedByBlankLine&gt;&lt;SA1514ElementDocumentationHeaderMustBePrecededByBlankLine&gt;False&lt;/SA1514ElementDocumentationHeaderMustBePrecededByBlankLine&gt;&lt;SA1515SingleLineCommentMustBeProceededByBlankLine&gt;False&lt;/SA1515SingleLineCommentMustBeProceededByBlankLine&gt;&lt;/StyleCop.Layout&gt;&lt;StyleCop.Ordering&gt;&lt;AlphabeticalUsingDirectives&gt;Ignore&lt;/AlphabeticalUsingDirectives&gt;&lt;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">&lt;Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns" /&gt;</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$.&#xD;
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderText/@EntryValue">This file is part of ${File.SolutionName}.&#xD;
&#xD;
$SOLUTION$ is free software: you can redistribute it and/or modify&#xD;
${File.SolutionName} is free software: you can redistribute it and/or modify&#xD;
it under the terms of the GNU General Public License as published by&#xD;
the Free Software Foundation, either version 3 of the License, or&#xD;
(at your option) any later version.&#xD;
&#xD;
$SOLUTION$ is distributed in the hope that it will be useful,&#xD;
${File.SolutionName} is distributed in the hope that it will be useful,&#xD;
but WITHOUT ANY WARRANTY; without even the implied warranty of&#xD;
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#xD;
GNU General Public License for more details.&#xD;
&#xD;
You should have received a copy of the GNU General Public License&#xD;
along with $SOLUTION$. If not, see &lt;http://www.gnu.org/licenses/&gt;.</s:String>
along with ${File.SolutionName}. If not, see &lt;http://www.gnu.org/licenses/&gt;.</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 &lt;http://www.gnu.org/licenses/&gt;.</s:Stri
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=PublicFields/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypeParameters/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/PredefinedNamingRules/=TypesAndNamespaces/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=15b5b1f1_002D457c_002D4ca6_002Db278_002D5615aedc07d3/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="_" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=236f7aa5_002D7b06_002D43ca_002Dbf2a_002D9b31bfcff09a/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CONSTANT_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="_" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=27c8359b_002D97bf_002D4e1d_002Db126_002D4f613028bcc5/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static, Instance" AccessRightKinds="Private, Protected, ProtectedInternal, Internal, Public" Description="Enums"&gt;&lt;ElementKinds&gt;&lt;Kind Name="ENUM" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="E" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=2c62818f_002D621b_002D4425_002Dadc9_002D78611099bfcb/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Type parameters"&gt;&lt;ElementKinds&gt;&lt;Kind Name="TYPE_PARAMETER" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="T" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=4a98fdf6_002D7d98_002D4f5a_002Dafeb_002Dea44ad98c70c/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Instance" AccessRightKinds="Private" Description="Instance fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="_" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=53eecf85_002Dd821_002D40e8_002Dac97_002Dfdb734542b84/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Instance" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Instance fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=669e5282_002Dfb4b_002D4e90_002D91e7_002D07d269d04b60/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Constant fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CONSTANT_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=70345118_002D4b40_002D4ece_002D937c_002Dbbeb7a0b2e70/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Static fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8a85b61a_002D1024_002D4f87_002Db9ef_002D1fdae19930a1/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Parameters"&gt;&lt;ElementKinds&gt;&lt;Kind Name="PARAMETER" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8b8504e3_002Df0be_002D4c14_002D9103_002Dc732f2bddc15/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Enum members"&gt;&lt;ElementKinds&gt;&lt;Kind Name="ENUM_MEMBER" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=8cff90ce_002Def0d_002D436d_002Db8f2_002D5b5bdb923d3b/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static, Instance" AccessRightKinds="Private, Protected, ProtectedInternal, Internal, Public" Description="Classes"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CLASS" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="C" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=9aa707ae_002Dd4fb_002D4760_002Da649_002Dffcedfabd5dc/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static, Instance" AccessRightKinds="Private, Protected" Description="Fields (not public)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;Kind Name="METHOD" /&gt;&lt;Kind Name="PROPERTY" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=a0b4bc4d_002Dd13b_002D4a37_002Db37e_002Dc9c6864e4302/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Any" Description="Types and namespaces"&gt;&lt;ElementKinds&gt;&lt;Kind Name="NAMESPACE" /&gt;&lt;Kind Name="CLASS" /&gt;&lt;Kind Name="STRUCT" /&gt;&lt;Kind Name="ENUM" /&gt;&lt;Kind Name="DELEGATE" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=da335a8d_002D4b6e_002D4df6_002D8434_002D29ffe5e2547b/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static, Instance" AccessRightKinds="Private, Protected, ProtectedInternal, Internal, Public" Description="Structs"&gt;&lt;ElementKinds&gt;&lt;Kind Name="STRUCT" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="S" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=f9fce829_002De6f4_002D4cb2_002D80f1_002D5497c44f51df/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" WarnAboutPrefixesAndSuffixes="False" Prefix="_" Suffix="" Style="AaBb" /&gt;&lt;/Policy&gt;</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>
+107 -17
View File
@@ -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
View File
@@ -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;
}
}
}
}
}
}
}
+22 -5
View File
@@ -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
View File
@@ -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));
}
}
}
}
}
}
+157 -77
View 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;
}
}
+16 -4
View File
@@ -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);
}
+17 -9
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+11 -5
View File
@@ -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
View File
@@ -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
View File
@@ -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
+18 -8
View File
@@ -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
View File
@@ -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
}
}
}
}
}
+33 -10
View File
@@ -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;
}
}
}
}
+96 -35
View File
@@ -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;
}
}
}
}
+39 -16
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
}
}
+18 -3
View File
@@ -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();
+20 -2
View File
@@ -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();
}
}
}
+11 -2
View File
@@ -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);
}
}
+91 -45
View File
@@ -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);
+42 -24
View File
@@ -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);
}
}
}
}
+222 -128
View File
@@ -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;
+102 -33
View 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;
}
+69 -69
View File
@@ -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
}
+9 -26
View File
@@ -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;
}
}
}
+22 -15
View File
@@ -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;
}
+44 -44
View File
@@ -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);
}
}
}
+7 -7
View File
@@ -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 : "";
}
}
+19 -6
View File
@@ -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;
}
+13 -1
View File
@@ -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;
}
+18 -2
View File
@@ -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);
}
}
+15 -4
View File
@@ -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;
}
+35 -16
View File
@@ -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;
}
+20 -12
View File
@@ -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);
}
}
}
}
+79 -39
View File
@@ -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
View File
@@ -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
+4 -1
View File
@@ -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
View File
@@ -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
}
}
}
}
+9 -3
View File
@@ -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));
}
}
+6 -5
View File
@@ -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;
}
+27 -13
View File
@@ -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);
+1 -1
View File
@@ -21,6 +21,6 @@ namespace Vocaluxe.GameModes
{
interface IGameMode
{
CSong GetSong(int songID);
CSong GetSong(int songId);
}
}
+50 -17
View File
@@ -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;
}
}
+12 -1
View File
@@ -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();
}
}
+232 -157
View File
@@ -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
View File
@@ -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;
}
+96 -20
View File
@@ -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();
}
}
}
}
+15 -9
View File
@@ -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;
+58 -26
View File
@@ -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);
}
}
+76 -25
View File
@@ -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);
+12
View File
@@ -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;
}
+195 -68
View File
@@ -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;
}
+37 -2
View File
@@ -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);
+55 -19
View File
@@ -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;
}
}
}
}
+30 -15
View File
@@ -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;
}
+4 -2
View File
@@ -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)
+59 -12
View File
@@ -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;
+68 -29
View File
@@ -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)
+34 -19
View File
@@ -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);
}
}
+56 -27
View File
@@ -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 -4
View File
@@ -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;
}
}
+225 -117
View File
@@ -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);
}
}
}
}
}
}
+18 -15
View File
@@ -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