diff --git a/Output/x64/hidapi.dll b/Output/x64/hidapi.dll index 9e65d33a..54422765 100644 Binary files a/Output/x64/hidapi.dll and b/Output/x64/hidapi.dll differ diff --git a/Output/x86/hidapi.dll b/Output/x86/hidapi.dll index b24dfb33..7bdc8fe2 100644 Binary files a/Output/x86/hidapi.dll and b/Output/x86/hidapi.dll differ diff --git a/Vocaluxe/Base/CDataBase.cs b/Vocaluxe/Base/CDataBase.cs index 2e9c4b65..2878045f 100644 --- a/Vocaluxe/Base/CDataBase.cs +++ b/Vocaluxe/Base/CDataBase.cs @@ -71,6 +71,76 @@ namespace Vocaluxe.Base } #region Highscores + + public static bool GetDataBaseSongInfos(string artist, string title, out int numPlayed, out string dateAdded, out int highscoreID) + { + string sArtist = string.Empty; + string sTitle = string.Empty; + int songID = -1; + using (SQLiteConnection connection = new SQLiteConnection()) + { + connection.ConnectionString = "Data Source=" + _HighscoreFilePath; + + try + { + connection.Open(); + } + catch (Exception) + { + } + + using (SQLiteCommand command = new SQLiteCommand(connection)) + { + songID = _GetDataBaseSongID(artist, title, 0, command); + highscoreID = songID; + } + } + return _GetDataBaseSongInfos(songID, out sArtist, out sTitle, out numPlayed, out dateAdded, _HighscoreFilePath); + } + + public static void IncreaseSongCounter(SPlayer player) + { + using (SQLiteConnection connection = new SQLiteConnection()) + { + connection.ConnectionString = "Data Source=" + _HighscoreFilePath; + + try + { + connection.Open(); + } + catch (Exception) + { + } + + using (SQLiteCommand command = new SQLiteCommand(connection)) + { + int dataBaseSongID = _GetDataBaseSongID(player, command); + _IncreaseSongCounter(dataBaseSongID, command); + } + } + } + + public static void IncreaseSongCounter(int dataBaseSongID) + { + using (SQLiteConnection connection = new SQLiteConnection()) + { + connection.ConnectionString = "Data Source=" + _HighscoreFilePath; + + try + { + connection.Open(); + } + catch (Exception) + { + } + + using (SQLiteCommand command = new SQLiteCommand(connection)) + { + _IncreaseSongCounter(dataBaseSongID, command); + } + } + } + public static 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) { @@ -113,7 +183,7 @@ namespace Vocaluxe.Base using (SQLiteCommand command = new SQLiteCommand(connection)) { - int dataBaseSongID = _GetDataBaseSongID(player, command); + int dataBaseSongID = CSongs.GetSong(player.SongID).DataBaseSongID; return _AddScore(CProfiles.GetPlayerName(player.ProfileID), (int)Math.Round(player.Points), player.LineNr, player.DateTicks, player.Medley ? 1 : 0, player.Duet ? 1 : 0, player.ShortSong ? 1 : 0, (int)CProfiles.GetDifficulty(player.ProfileID), dataBaseSongID, command); } @@ -250,6 +320,13 @@ namespace Vocaluxe.Base } } + private static void _IncreaseSongCounter(int dataBaseSongID, SQLiteCommand command) + { + command.CommandText = "UPDATE Songs SET NumPlayed = NumPlayed + 1 WHERE [id] = @id"; + command.Parameters.Add("@id", DbType.Int32, 0).Value = dataBaseSongID; + command.ExecuteNonQuery(); + } + private static int _GetDataBaseSongID(SPlayer player, SQLiteCommand command) { CSong song = CSongs.GetSong(player.SongID); @@ -275,14 +352,16 @@ namespace Vocaluxe.Base reader.Dispose(); return id; } + if (reader != null) reader.Close(); - command.CommandText = "INSERT INTO Songs (Title, Artist, NumPlayed) " + - "VALUES (@title, @artist, @numplayed)"; + command.CommandText = "INSERT INTO Songs (Title, Artist, NumPlayed, DateAdded) " + + "VALUES (@title, @artist, @numplayed, @dateadded)"; command.Parameters.Add("@title", DbType.String, 0).Value = title; command.Parameters.Add("@artist", DbType.String, 0).Value = artist; command.Parameters.Add("@numplayed", DbType.Int32, 0).Value = defNumPlayed; + command.Parameters.Add("@dateadded", System.Data.DbType.Int64, 0).Value = DateTime.Now.Ticks; command.ExecuteNonQuery(); command.CommandText = "SELECT id FROM Songs WHERE [Title] = @title AND [Artist] = @artist"; @@ -302,11 +381,12 @@ namespace Vocaluxe.Base return -1; } - private static bool _GetDataBaseSongInfos(int songID, out string artist, out string title, out int numPlayed, string filePath) + private static bool _GetDataBaseSongInfos(int songID, out string artist, out string title, out int numPlayed, out string dateAdded, string filePath) { artist = String.Empty; title = String.Empty; numPlayed = 0; + dateAdded = String.Empty; using (SQLiteConnection connection = new SQLiteConnection()) { @@ -323,7 +403,7 @@ namespace Vocaluxe.Base using (SQLiteCommand command = new SQLiteCommand(connection)) { - command.CommandText = "SELECT Artist, Title, NumPlayed FROM Songs WHERE [id] = @id"; + command.CommandText = "SELECT Artist, Title, NumPlayed, DateAdded FROM Songs WHERE [id] = @id"; command.Parameters.Add("@id", DbType.String, 0).Value = songID; SQLiteDataReader reader; @@ -342,6 +422,7 @@ namespace Vocaluxe.Base artist = reader.GetString(0); title = reader.GetString(1); numPlayed = reader.GetInt32(2); + dateAdded = new DateTime(reader.GetInt64(3)).ToString("dd/MM/yyyy"); reader.Dispose(); return true; } @@ -504,6 +585,7 @@ namespace Vocaluxe.Base _CreateHighscoreDBV1(filePath); _ConvertFrom110(filePath); _UpdateDatabase(1, connection); + _UpdateDatabase(2, connection); } else if (version == 0 && scoresTableExists) { @@ -511,6 +593,7 @@ namespace Vocaluxe.Base _CreateHighscoreDBV1(filePath); _ConvertFrom101(filePath); _UpdateDatabase(1, connection); + _UpdateDatabase(2, connection); } else _CreateHighscoreDB(filePath); @@ -524,6 +607,7 @@ namespace Vocaluxe.Base _CreateHighscoreDBV1(filePath); _ConvertFrom110(filePath); _UpdateDatabase(1, connection); + _UpdateDatabase(2, connection); } else if (version == 0 && scoresTableExists) { @@ -531,6 +615,7 @@ namespace Vocaluxe.Base _CreateHighscoreDBV1(filePath); _ConvertFrom101(filePath); _UpdateDatabase(1, connection); + _UpdateDatabase(2, connection); } else _CreateHighscoreDB(filePath); @@ -831,8 +916,16 @@ namespace Vocaluxe.Base private static bool _UpdateDatabase(int currentVersion, SQLiteConnection connection) { bool updated = true; + if (currentVersion < 2) + { updated &= _ConvertV1toV2(connection); + } + if (currentVersion < 3) + { + updated &= _ConvertV2toV3(connection); + } + return updated; } @@ -853,6 +946,60 @@ namespace Vocaluxe.Base return true; } + private static bool _ConvertV2toV3(SQLiteConnection connection) + { + SQLiteCommand command; + + command = new SQLiteCommand(connection); + + command.CommandText = "ALTER TABLE Songs ADD DateAdded BIGINT"; + command.ExecuteNonQuery(); + command.CommandText = "UPDATE Songs SET [DateAdded] = @DateAdded"; + command.Parameters.Add("@DateAdded",System.Data.DbType.Int64, 0).Value = DateTime.Now.Ticks; + command.ExecuteNonQuery(); + command.CommandText = "UPDATE Version SET [Value] = @version"; + command.Parameters.Add("@version", System.Data.DbType.Int32, 0).Value = 3; + command.ExecuteNonQuery(); + + //Read NumPlayed from Scores and save to Songs + command.CommandText = "SELECT SongID, Date FROM Scores ORDER BY Date ASC"; + + SQLiteDataReader reader; + try + { + reader = command.ExecuteReader(); + } + catch (Exception e) + { + return false; + } + + long lastDateAdded = -1; + int lastID = -1; + DateTime dt = new DateTime(1, 1, 1, 0, 0, 5); + long sec = dt.Ticks; + List ids = new List(); + while (reader.Read()) + { + int id = reader.GetInt32(0); + long dateAdded = reader.GetInt64(1); + if (id != lastID || dateAdded > lastDateAdded + sec) + { + ids.Add(id); + lastID = id; + lastDateAdded = dateAdded; + } + } + if (reader != null) + reader.Dispose(); + + foreach (int id in ids) + _IncreaseSongCounter(id, command); + command.Dispose(); + + return true; + } + private static bool _ImportData(string sourceDBPath) { #region open db @@ -897,9 +1044,9 @@ namespace Vocaluxe.Base int shortsong = source.GetInt32(7); int diff = source.GetInt32(8); - string artist, title; + string artist, title, dateadded; int numplayed; - if (_GetDataBaseSongInfos(songid, out artist, out title, out numplayed, sourceDBPath)) + if (_GetDataBaseSongInfos(songid, out artist, out title, out numplayed, out dateadded, sourceDBPath)) AddScore(player, score, linenr, date, medley, duet, shortsong, diff, artist, title, numplayed, _HighscoreFilePath); } #endregion import table scores diff --git a/Vocaluxe/Base/CMain.cs b/Vocaluxe/Base/CMain.cs index 61a997ea..fdf8a305 100644 --- a/Vocaluxe/Base/CMain.cs +++ b/Vocaluxe/Base/CMain.cs @@ -782,6 +782,11 @@ namespace Vocaluxe.Base { return CDataBase.GetCover(fileName, ref texture, coverSize); } + + public bool GetDataBaseSongInfos(string artist, string title, out int numPlayed, out string dateAdded, out int highscoreID) + { + return CDataBase.GetDataBaseSongInfos(artist, title, out numPlayed, out dateAdded, out highscoreID); + } } class CBcontrollers : IControllers diff --git a/Vocaluxe/Base/CSettings.cs b/Vocaluxe/Base/CSettings.cs index eeaffaef..71cfd196 100644 --- a/Vocaluxe/Base/CSettings.cs +++ b/Vocaluxe/Base/CSettings.cs @@ -55,7 +55,7 @@ namespace Vocaluxe.Base public const ERevision VersionRevision = ERevision.Beta; - public const int DatabaseHighscoreVersion = 2; + public const int DatabaseHighscoreVersion = 3; public const int DatabaseCoverVersion = 1; public const int DatabaseCreditsRessourcesVersion = 1; @@ -224,4 +224,4 @@ namespace Vocaluxe.Base Directory.CreateDirectory(path); } } -} \ No newline at end of file +} diff --git a/Vocaluxe/Lib/Input/CHIDAPI.cs b/Vocaluxe/Lib/Input/CHIDAPI.cs index d90e50d7..1ec63509 100644 --- a/Vocaluxe/Lib/Input/CHIDAPI.cs +++ b/Vocaluxe/Lib/Input/CHIDAPI.cs @@ -23,20 +23,20 @@ using Vocaluxe.Base; namespace Vocaluxe.Lib.Input { - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct SHIDDeviceInfo { // ReSharper disable MemberCanBePrivate.Global [MarshalAs(UnmanagedType.LPTStr)] public readonly String Path; public readonly ushort VendorString; public readonly ushort ProductID; - public readonly String SerialNumber; + [MarshalAs(UnmanagedType.LPWStr)] public readonly String SerialNumber; public readonly ushort ReleaseNumber; - public readonly String ManufacturerString; - 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; - public readonly int InterfaceNumber; + [MarshalAs(UnmanagedType.LPWStr)] public readonly int InterfaceNumber; internal IntPtr Next; // ReSharper restore MemberCanBePrivate.Global } @@ -62,7 +62,6 @@ namespace Vocaluxe.Lib.Input private const string _HIDApiDll = "libhidapi.so"; #endif #endif - [DllImport(_HIDApiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_init", CharSet = CharSet.Unicode)] private static extern int hid_init(); @@ -160,11 +159,9 @@ namespace Vocaluxe.Lib.Input [DllImport(_HIDApiDll, ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, EntryPoint = "hid_read_timeout", CharSet = CharSet.Unicode)] private static extern int hid_read_timeout(IntPtr device, IntPtr data, int length, int milliseconds); - public static int ReadTimeout(IntPtr device, out byte[] data, int length, int milliseconds) + public static int ReadTimeout(IntPtr device, ref byte[] data, int length, int milliseconds) { - data = new byte[length]; IntPtr dataPtr = Marshal.AllocHGlobal(length); - int result; try { @@ -182,6 +179,7 @@ namespace Vocaluxe.Lib.Input data = null; Marshal.FreeHGlobal(dataPtr); + return result; } diff --git a/Vocaluxe/Lib/Input/WiiMote/CWiiMote.cs b/Vocaluxe/Lib/Input/WiiMote/CWiiMote.cs index 6fffb49c..c57354ba 100644 --- a/Vocaluxe/Lib/Input/WiiMote/CWiiMote.cs +++ b/Vocaluxe/Lib/Input/WiiMote/CWiiMote.cs @@ -71,6 +71,7 @@ namespace Vocaluxe.Lib.Input.WiiMote public void Close() { _Active = false; + _WiiMote.Disconnect(); } public void Connect() diff --git a/Vocaluxe/Lib/Input/WiiMote/WiiMoteLib.cs b/Vocaluxe/Lib/Input/WiiMote/WiiMoteLib.cs index b4e234c9..bc6db789 100644 --- a/Vocaluxe/Lib/Input/WiiMote/WiiMoteLib.cs +++ b/Vocaluxe/Lib/Input/WiiMote/WiiMoteLib.cs @@ -198,6 +198,16 @@ namespace Vocaluxe.Lib.Input.WiiMote _Error = false; _Reader = new Thread(_ReaderLoop); _Reader.Start(); + + if (!CHIDApi.Init()) + { + CLog.LogError("WiiMoteLib: Can't initialize HID API"); + const string msg = "Please install the Visual C++ Redistributable Packages 2008!"; + CLog.LogError(msg); + + _Active = false; + _Error = true; + } } ~CWiiMoteLib() @@ -224,25 +234,31 @@ namespace Vocaluxe.Lib.Input.WiiMote if (_Error) return false; - CHIDApi.Exit(); - - if (!CHIDApi.Init()) - { - CLog.LogError("WiiMoteLib: Can't initialize HID API"); - const string msg = "Please install the Visual C++ Redistributable Packages 2008!"; - CLog.LogError(msg); - - _Active = false; - _Error = true; - return false; - } - //Try WiiMotion - Connected = _TryConnect(_PID); + Connected = CHIDApi.Open(_VID, _PID, out _Handle); + if (Connected) + { + Connected = _ReadCalibration(); + if (!Connected) + CHIDApi.Close(_Handle); + } + else + CHIDApi.Close(_Handle); + + if (Connected) + return true; //Try WiiMotion Plus - if (!Connected) - Connected = _TryConnect(_PIDPlus); + Connected = CHIDApi.Open(_VID, _PIDPlus, out _Handle); + if (Connected) + { + Connected = _ReadCalibration(); + if (!Connected) + CHIDApi.Close(_Handle); + } + else + CHIDApi.Close(_Handle); + return Connected; } @@ -324,7 +340,7 @@ namespace Vocaluxe.Lib.Input.WiiMote try { - CHIDApi.ReadTimeout(_Handle, out buff, _ReportLength, 100); + CHIDApi.ReadTimeout(_Handle, ref buff, _ReportLength, 200); } catch (Exception e) { diff --git a/Vocaluxe/Screens/CScreenProfiles.cs b/Vocaluxe/Screens/CScreenProfiles.cs index 08e37d59..a5991bd3 100644 --- a/Vocaluxe/Screens/CScreenProfiles.cs +++ b/Vocaluxe/Screens/CScreenProfiles.cs @@ -446,13 +446,16 @@ namespace Vocaluxe.Screens int selectedAvatarID = _SelectSlides[_SelectSlideAvatars].ValueIndex; _SelectSlides[_SelectSlideAvatars].Clear(); IEnumerable avatars = CProfiles.GetAvatars(); - foreach (CAvatar avatar in avatars) + if (avatars != null) { - _SelectSlides[_SelectSlideAvatars].AddValue( - Path.GetFileName(avatar.FileName), - null, - avatar.ID, - -1); + foreach (CAvatar avatar in avatars) + { + _SelectSlides[_SelectSlideAvatars].AddValue( + Path.GetFileName(avatar.FileName), + null, + avatar.ID, + -1); + } } if (keep) diff --git a/Vocaluxe/Screens/CScreenScore.cs b/Vocaluxe/Screens/CScreenScore.cs index 94838312..bbed2113 100644 --- a/Vocaluxe/Screens/CScreenScore.cs +++ b/Vocaluxe/Screens/CScreenScore.cs @@ -123,6 +123,8 @@ namespace Vocaluxe.Screens _Round = CGame.NumRounds > 1 ? 0 : 1; _Points = CGame.GetPoints(); + _SavePlayedSongs(); + _SetVisibility(); _UpdateRatings(); } @@ -389,6 +391,25 @@ namespace Vocaluxe.Screens } } + private void _SavePlayedSongs() + { + for (int round = 0; round < _Points.NumRounds; round++) + { + SPlayer[] players = _Points.GetPlayer(round, CGame.NumPlayer); + + for (int p = 0; p < players.Length; p++) + { + if (players[p].Points > CSettings.MinScoreForDB && players[p].SongFinished) + { + CSong song = CSongs.GetSong(players[p].SongID); + CDataBase.IncreaseSongCounter(song.DataBaseSongID); + song.NumPlayed++; + break; + } + } + } + } + private void _LeaveScreen() { CParty.LeavingScore(); diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs index 9e9d4ebd..57a4825b 100644 --- a/Vocaluxe/Screens/CScreenSing.cs +++ b/Vocaluxe/Screens/CScreenSing.cs @@ -546,12 +546,14 @@ namespace Vocaluxe.Screens public override void ApplyVolume() { - CSound.SetStreamVolumeMax(_CurrentStream, CConfig.GameMusicVolume); + if(_CurrentStream > -1) + CSound.SetStreamVolumeMax(_CurrentStream, CConfig.GameMusicVolume); } private void _CloseSong() { - CSound.FadeAndStop(_CurrentStream, 0f, 0.5f); + if(_CurrentStream > -1) + CSound.FadeAndStop(_CurrentStream, 0f, 0.5f); CSound.RecordStop(); if (_CurrentVideo != -1) { diff --git a/VocaluxeLib/IBasic.cs b/VocaluxeLib/IBasic.cs index 2c85ba9d..afbbf8d4 100644 --- a/VocaluxeLib/IBasic.cs +++ b/VocaluxeLib/IBasic.cs @@ -262,6 +262,7 @@ namespace VocaluxeLib public interface IDataBase { bool GetCover(string fileName, ref CTexture texture, int coverSize); + bool GetDataBaseSongInfos(string artist, string title, out int numPlayed, out string dateAdded, out int highscoreID); } public interface IControllers diff --git a/VocaluxeLib/Songs/CSong.cs b/VocaluxeLib/Songs/CSong.cs index adf7f34d..d999f5c4 100644 --- a/VocaluxeLib/Songs/CSong.cs +++ b/VocaluxeLib/Songs/CSong.cs @@ -147,6 +147,10 @@ namespace VocaluxeLib.Songs public readonly List Language = new List(); + public int DataBaseSongID = -1; + public string DateAdded = ""; + public int NumPlayed = 0; + // Notes public readonly CNotes Notes = new CNotes(); @@ -240,6 +244,10 @@ namespace VocaluxeLib.Songs foreach (string value in song.Language) Language.Add(value); + DataBaseSongID = song.DataBaseSongID; + DateAdded = song.DateAdded; + NumPlayed = song.NumPlayed; + Notes = new CNotes(song.Notes); } @@ -353,10 +361,12 @@ namespace VocaluxeLib.Songs if (value != "") ArtistSorting = value; break; + case "DUETSINGERP1": case "P1": if (value != "") DuetPart1 = value; break; + case "DUETSINGERP2": case "P2": if (value != "") DuetPart2 = value; @@ -528,6 +538,8 @@ namespace VocaluxeLib.Songs sr.Dispose(); _CheckFiles(); + CBase.DataBase.GetDataBaseSongInfos(Artist, Title, out NumPlayed, out DateAdded, out DataBaseSongID); + //Before saving this tags to .txt: Check, if ArtistSorting and Artist are equal, then don't save this tag. if (ArtistSorting == "") ArtistSorting = Artist;