From 76087c502a81f206eec5ca9a6d2ff42f764c0faf Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Thu, 1 Mar 2012 21:33:41 +0100 Subject: [PATCH 01/17] roadmap update --- Vocaluxe/Doc/Roadmap.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Vocaluxe/Doc/Roadmap.txt b/Vocaluxe/Doc/Roadmap.txt index ed4f88e1..66024f04 100644 --- a/Vocaluxe/Doc/Roadmap.txt +++ b/Vocaluxe/Doc/Roadmap.txt @@ -79,7 +79,8 @@ + v0.2.0: - Medley - WiiMote Support - - Jukebox light + - Jukebox light (bg music controls) + - Show Avatars and Player Name in Sing Screen (and perhaps some other screens) + v0.3.0: - Song Editor From 6ba68f868a7ba9eeb4bb3ea265fb87f23266ba77 Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Fri, 2 Mar 2012 16:25:12 +0100 Subject: [PATCH 02/17] search and import "Ultrastar.db" --- Vocaluxe/Base/CDataBase.cs | 14 ++++++++++++++ Vocaluxe/Base/CSettings.cs | 1 + 2 files changed, 15 insertions(+) diff --git a/Vocaluxe/Base/CDataBase.cs b/Vocaluxe/Base/CDataBase.cs index 90b52a93..97d4278c 100644 --- a/Vocaluxe/Base/CDataBase.cs +++ b/Vocaluxe/Base/CDataBase.cs @@ -262,6 +262,20 @@ namespace Vocaluxe.Base private static bool InitHighscoreDB() { + string OldDBFilePath = Path.Combine(Environment.CurrentDirectory, CSettings.sFileOldHighscoreDB); + if (File.Exists(OldDBFilePath)) + { + if (File.Exists(_HighscoreFilePath)) + { + CLog.LogError("Found old Highscore DB (" + OldDBFilePath + "). If you want to import it just delete the new one (" + _HighscoreFilePath + ")"); + } + else + { + File.Copy(OldDBFilePath, _HighscoreFilePath); + File.Move(OldDBFilePath, OldDBFilePath + ".old"); + } + } + SQLiteConnection connection = new SQLiteConnection(); connection.ConnectionString = "Data Source=" + _HighscoreFilePath; SQLiteCommand command; diff --git a/Vocaluxe/Base/CSettings.cs b/Vocaluxe/Base/CSettings.cs index bbd6164f..a1aa2db7 100644 --- a/Vocaluxe/Base/CSettings.cs +++ b/Vocaluxe/Base/CSettings.cs @@ -69,6 +69,7 @@ namespace Vocaluxe.Base public const string sFileCover = "Cover.xml"; public const string sFileFonts = "Fonts.xml"; + public const string sFileOldHighscoreDB = "Ultrastar.db"; public static string sFileHighscoreDB = "HighscoreDB.sqlite"; public const string sFileCoverDB = "CoverDB.sqlite"; public const string sFilePerformanceLog = "Performance.log"; From b5355d1cd3b9fdb40d4cefe008b84a462c8351d3 Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Fri, 2 Mar 2012 16:33:44 +0100 Subject: [PATCH 03/17] added additional constructor to particle effect and particle, made the area changeable --- Vocaluxe/Base/CDraw.cs | 73 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 6 deletions(-) diff --git a/Vocaluxe/Base/CDraw.cs b/Vocaluxe/Base/CDraw.cs index 514d3adc..3a62415b 100644 --- a/Vocaluxe/Base/CDraw.cs +++ b/Vocaluxe/Base/CDraw.cs @@ -319,6 +319,7 @@ namespace Vocaluxe.Base { #region private vars private string _TextureName; + private STexture _Texture; private SRectF _Rect; private float _Size; private SColorF _Color; @@ -333,7 +334,7 @@ namespace Vocaluxe.Base private float _Vsize; //size changing speed: period [s] private float _LastTime; private EParticeType _Type; - + private Stopwatch _Timer; #endregion private vars @@ -386,6 +387,7 @@ namespace Vocaluxe.Base public CParticle(string textureName, SColorF color, float x, float y, float size, float maxage, float z, float vx, float vy, float vr, float vsize, EParticeType type) { _TextureName = textureName; + _Texture = new STexture(-1); _Color = color; _Rect = new SRectF(x, y, size, size, z); _Size = size; @@ -403,6 +405,29 @@ namespace Vocaluxe.Base _MaxAge = maxage; _Rotation = (float)(CGame.Rand.NextDouble() * 360.0); } + + public CParticle(STexture texture, SColorF color, float x, float y, float size, float maxage, float z, float vx, float vy, float vr, float vsize, EParticeType type) + { + _TextureName = String.Empty; + _Texture = texture; + _Color = color; + _Rect = new SRectF(x, y, size, size, z); + _Size = size; + _Alpha = 1f; + _Angle = 0f; + _Vx = vx; + _Vy = vy; + _Vr = vr; + _Vsize = vsize; + _LastTime = 0f; + _Type = type; + + _Timer = new Stopwatch(); + _Age = 0f; + _MaxAge = maxage; + _Rotation = (float)(CGame.Rand.NextDouble() * 360.0); + } + #endregion Constructors public void Update() @@ -553,7 +578,10 @@ namespace Vocaluxe.Base public void Draw() { - CDraw.DrawTexture(CTheme.GetSkinTexture(_TextureName), _Rect, new SColorF(_Color.R, _Color.G, _Color.B, _Color.A * Alpha2 * _Alpha)); + if (_TextureName != String.Empty) + CDraw.DrawTexture(CTheme.GetSkinTexture(_TextureName), _Rect, new SColorF(_Color.R, _Color.G, _Color.B, _Color.A * Alpha2 * _Alpha)); + else + CDraw.DrawTexture(_Texture, _Rect, new SColorF(_Color.R, _Color.G, _Color.B, _Color.A * Alpha2 * _Alpha)); } } @@ -561,6 +589,7 @@ namespace Vocaluxe.Base { private List _Stars; private string _TextureName; + private STexture _Texture; private int _MaxNumber; private SRectF _Area; private SColorF _Color; @@ -579,12 +608,33 @@ namespace Vocaluxe.Base } } + public SRectF Area + { + get { return _Area; } + set { _Area = value; } + } + public CParticleEffect(int MaxNumber, SColorF Color, SRectF Area, string TextureName, float Size, EParticeType Type) { _Stars = new List(); _Area = Area; _Color = Color; _TextureName = TextureName; + _Texture = new STexture(-1); + _MaxNumber = MaxNumber; + _Size = Size; + _Type = Type; + _SpawnTimer = new Stopwatch(); + _NextSpawnTime = 0f; + } + + public CParticleEffect(int MaxNumber, SColorF Color, SRectF Area, STexture texture, float Size, EParticeType Type) + { + _Stars = new List(); + _Area = Area; + _Color = Color; + _TextureName = String.Empty; + _Texture = texture; _MaxNumber = MaxNumber; _Size = Size; _Type = Type; @@ -682,10 +732,21 @@ namespace Vocaluxe.Base if (h < 0) h = 0; - CParticle star = new CParticle(_TextureName, _Color, - CGame.Rand.Next(w) + _Area.X - size / 4f, - CGame.Rand.Next(h) + _Area.Y - size / 4f, - size, lifetime, _Area.Z, vx, vy, vr, vsize, _Type); + CParticle star; + if (_TextureName != String.Empty) + { + star = new CParticle(_TextureName, _Color, + CGame.Rand.Next(w) + _Area.X - size / 4f, + CGame.Rand.Next(h) + _Area.Y - size / 4f, + size, lifetime, _Area.Z, vx, vy, vr, vsize, _Type); + } + else + { + star = new CParticle(_Texture, _Color, + CGame.Rand.Next(w) + _Area.X - size / 4f, + CGame.Rand.Next(h) + _Area.Y - size / 4f, + size, lifetime, _Area.Z, vx, vy, vr, vsize, _Type); + } _Stars.Add(star); } From 98535e9ae1e8eadfce290b5e01cf1cd7cb4cd5de Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Sat, 3 Mar 2012 12:05:03 +0100 Subject: [PATCH 04/17] bugfix: the score was not added, if someone didn't hit the last note of the song --- Vocaluxe/Base/CGame.cs | 88 ++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 50 deletions(-) diff --git a/Vocaluxe/Base/CGame.cs b/Vocaluxe/Base/CGame.cs index 07ea2d2d..9c2b6c7d 100644 --- a/Vocaluxe/Base/CGame.cs +++ b/Vocaluxe/Base/CGame.cs @@ -247,72 +247,60 @@ namespace Vocaluxe.Base for (int p = 0; p < _NumPlayer; p++) { - CSound.AnalyzeBuffer(p); - - if (CSound.RecordToneValid(p) || DEBUG_HIT) + + for (int beat = _OldBeatD + 1; beat <= _CurrentBeatD; beat++) { - for (int beat = _OldBeatD + 1; beat <= _CurrentBeatD; beat++) - { - CLine[] lines = song.Notes.GetLines(_Player[p].LineNr).Line; - int Line = -1; + CLine[] lines = song.Notes.GetLines(_Player[p].LineNr).Line; + int Line = -1; - for (int j = 0; j < lines.Length; j++) + for (int j = 0; j < lines.Length; j++) + { + if (beat >= lines[j].StartBeat && beat <= lines[j].EndBeat) { - if (beat >= lines[j].StartBeat && beat <= lines[j].EndBeat) - { - Line = j; - break; - } + Line = j; + break; + } + } + + if (Line >= 0) + { + if (Line != _Player[p].CurrentLine) + _Player[p].CurrentNote = -1; + + _Player[p].CurrentLine = Line; + + while (_Player[p].SingLine.Count <= Line) + { + _Player[p].SingLine.Add(new CLine()); } - if (Line >= 0) + CNote[] notes = lines[Line].Notes; + int Note = -1; + for (int j = 0; j < notes.Length; j++) { - if (Line != _Player[p].CurrentLine) - _Player[p].CurrentNote = -1; - - _Player[p].CurrentLine = Line; - - while (_Player[p].SingLine.Count <= Line) + if (beat >= notes[j].StartBeat && beat <= notes[j].EndBeat) { - _Player[p].SingLine.Add(new CLine()); + Note = j; + break; } + } - CNote[] notes = lines[Line].Notes; - int Note = -1; - for (int j = 0; j < notes.Length; j++) - { - if (beat >= notes[j].StartBeat && beat <= notes[j].EndBeat) - { - if (notes[j].PointsForBeat > 0) - Note = j; - break; - } - } + if (Note >= 0) + { + _Player[p].CurrentNote = Note; - if (Note >= 0) + if (Line == lines.Length - 1) { - if (Line == lines.Length - 1) + if (Note == lines[Line].NoteCount - 1) { - if (Note == lines[Line].NoteCount - 1) - { + if (notes[Note].EndBeat == beat) _Player[p].SongFinished = true; - } } } - if (Note >= 0 && notes[Note].PointsForBeat > 0) + CSound.AnalyzeBuffer(p); + if (notes[Note].PointsForBeat > 0 && (CSound.RecordToneValid(p) || DEBUG_HIT)) { - _Player[p].CurrentNote = Note; - - if (Line == lines.Length - 1) - { - if (Note == lines[Line].NoteCount - 1) - { - if (notes[Note].EndBeat == beat) - _Player[p].SongFinished = true; - } - } - int Tone = notes[Note].Tone; int TonePlayer = CSound.RecordGetTone(p); @@ -383,8 +371,8 @@ namespace Vocaluxe.Base } } } - } + } } _OldBeatD = _CurrentBeatD; From 620a66fa1c8a6b92add0d60c4b80fde2a63a9852 Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Sat, 3 Mar 2012 21:48:19 +0100 Subject: [PATCH 05/17] changed high score import: delete old file after import, add data to existing database file, don't add data raws twice --- Vocaluxe/Base/CDataBase.cs | 394 +++++++++++++++++++++++++++++-------- 1 file changed, 315 insertions(+), 79 deletions(-) diff --git a/Vocaluxe/Base/CDataBase.cs b/Vocaluxe/Base/CDataBase.cs index 97d4278c..4dec5522 100644 --- a/Vocaluxe/Base/CDataBase.cs +++ b/Vocaluxe/Base/CDataBase.cs @@ -38,10 +38,45 @@ namespace Vocaluxe.Base } #region Highscores + public static int AddScore(string PlayerName, int Score, int LineNr, long Date, int Medley, int Duet, int Diff, + string Artist, string Title, int NumPlayed, string FilePath) + { + SPlayer player = new SPlayer(); + player.Name = PlayerName; + player.Points = Score; + player.LineNr = LineNr; + player.DateTicks = Date; + player.Medley = (Medley == 1); + player.Duet = (Duet == 1); + player.Difficulty = (EGameDifficulty)Diff; + + SQLiteConnection connection = new SQLiteConnection(); + connection.ConnectionString = "Data Source=" + FilePath; + SQLiteCommand command; + + try + { + connection.Open(); + } + catch (Exception) + { + return -1; + } + + command = new SQLiteCommand(connection); + + int DataBaseSongID = GetDataBaseSongID(Artist, Title, NumPlayed, command); + int result = AddScore(player, command, DataBaseSongID); + + command.Dispose(); + connection.Close(); + connection.Dispose(); + + return result; + } + public static int AddScore(SPlayer player) { - int lastInsertID = -1; - SQLiteConnection connection = new SQLiteConnection(); connection.ConnectionString = "Data Source=" + _HighscoreFilePath; SQLiteCommand command; @@ -58,6 +93,18 @@ namespace Vocaluxe.Base command = new SQLiteCommand(connection); int DataBaseSongID = GetDataBaseSongID(player, command); + int result = AddScore(player, command, DataBaseSongID); + + connection.Close(); + connection.Dispose(); + + return result; + } + + private static int AddScore(SPlayer player, SQLiteCommand command, int DataBaseSongID) + { + int lastInsertID = -1; + if (DataBaseSongID >= 0) { @@ -68,7 +115,38 @@ namespace Vocaluxe.Base int Duet = 0; if (player.Duet) Duet = 1; + + 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 Difficulty = @Difficulty"; + command.Parameters.Add("@SongID", System.Data.DbType.Int32, 0).Value = DataBaseSongID; + command.Parameters.Add("@PlayerName", System.Data.DbType.String, 0).Value = player.Name; + command.Parameters.Add("@Score", System.Data.DbType.Int32, 0).Value = (int)Math.Round(player.Points); + command.Parameters.Add("@LineNr", System.Data.DbType.Int32, 0).Value = (int)player.LineNr; + command.Parameters.Add("@Date", System.Data.DbType.Int64, 0).Value = player.DateTicks; + command.Parameters.Add("@Medley", System.Data.DbType.Int32, 0).Value = Medley; + command.Parameters.Add("@Duet", System.Data.DbType.Int32, 0).Value = Duet; + command.Parameters.Add("@Difficulty", System.Data.DbType.Int32, 0).Value = (int)player.Difficulty; + SQLiteDataReader reader = null; + try + { + reader = command.ExecuteReader(); + } + catch (Exception) + { + ; + } + + if (reader != null && reader.HasRows) + { + if (reader.Read()) + return reader.GetInt32(0); + } + + if (reader != null) + reader.Close(); + + command.CommandText = "INSERT INTO Scores (SongID, PlayerName, Score, LineNr, Date, Medley, Duet, Difficulty) " + "VALUES (@SongID, @PlayerName, @Score, @LineNr, @Date, @Medley, @Duet, @Difficulty)"; command.Parameters.Add("@SongID", System.Data.DbType.Int32, 0).Value = DataBaseSongID; @@ -84,7 +162,7 @@ namespace Vocaluxe.Base //Read last insert line command.CommandText = "SELECT id FROM Scores ORDER BY Date DESC LIMIT 0, 1"; - SQLiteDataReader reader = null; + reader = null; try { reader = command.ExecuteReader(); @@ -106,10 +184,6 @@ namespace Vocaluxe.Base } } - command.Dispose(); - connection.Close(); - connection.Dispose(); - return lastInsertID; } @@ -194,9 +268,38 @@ namespace Vocaluxe.Base if (song == null) return -1; + return GetDataBaseSongID(song.Artist, song.Title, 0, command); + } + + private static int GetDataBaseSongID(string Artist, string Title, string FilePath, int DefNumPlayed) + { + SQLiteConnection connection = new SQLiteConnection(); + connection.ConnectionString = "Data Source=" + FilePath; + SQLiteCommand command; + + try + { + connection.Open(); + } + catch (Exception) + { + return -1; + } + + command = new SQLiteCommand(connection); + int id = GetDataBaseSongID(Artist, Title, DefNumPlayed, command); + command.Dispose(); + connection.Close(); + connection.Dispose(); + + return id; + } + + private static int GetDataBaseSongID(string Artist, string Title, int DefNumPlayed, SQLiteCommand command) + { command.CommandText = "SELECT id FROM Songs WHERE [Title] = @title AND [Artist] = @artist"; - command.Parameters.Add("@title", System.Data.DbType.String, 0).Value = song.Title; - command.Parameters.Add("@artist", System.Data.DbType.String, 0).Value = song.Artist; + command.Parameters.Add("@title", System.Data.DbType.String, 0).Value = Title; + command.Parameters.Add("@artist", System.Data.DbType.String, 0).Value = Artist; SQLiteDataReader reader = null; try @@ -222,14 +325,15 @@ namespace Vocaluxe.Base reader.Close(); command.CommandText = "INSERT INTO Songs (Title, Artist, NumPlayed) " + - "VALUES (@title, @artist, 0)"; - command.Parameters.Add("@title", System.Data.DbType.String, 0).Value = song.Title; - command.Parameters.Add("@artist", System.Data.DbType.String, 0).Value = song.Artist; + "VALUES (@title, @artist, @numplayed)"; + command.Parameters.Add("@title", System.Data.DbType.String, 0).Value = Title; + command.Parameters.Add("@artist", System.Data.DbType.String, 0).Value = Artist; + command.Parameters.Add("@numplayed", System.Data.DbType.Int32, 0).Value = DefNumPlayed; command.ExecuteNonQuery(); command.CommandText = "SELECT id FROM Songs WHERE [Title] = @title AND [Artist] = @artist"; - command.Parameters.Add("@title", System.Data.DbType.String, 0).Value = song.Title; - command.Parameters.Add("@artist", System.Data.DbType.String, 0).Value = song.Artist; + command.Parameters.Add("@title", System.Data.DbType.String, 0).Value = Title; + command.Parameters.Add("@artist", System.Data.DbType.String, 0).Value = Artist; reader = null; try @@ -260,24 +364,136 @@ namespace Vocaluxe.Base return -1; } - private static bool InitHighscoreDB() + private static bool GetDataBaseSongInfos(int SongID, out string Artist, out string Title, out int NumPlayed, string FilePath) + { + Artist = String.Empty; + Title = String.Empty; + NumPlayed = 0; + + SQLiteConnection connection = new SQLiteConnection(); + connection.ConnectionString = "Data Source=" + FilePath; + SQLiteCommand command; + + try + { + connection.Open(); + } + catch (Exception) + { + return false; + } + + command = new SQLiteCommand(connection); + command.CommandText = "SELECT Artist, Title, NumPlayed FROM Songs WHERE [id] = @id"; + command.Parameters.Add("@id", System.Data.DbType.String, 0).Value = SongID; + + SQLiteDataReader reader = null; + try + { + reader = command.ExecuteReader(); + } + catch (Exception) + { + return false; + } + + if (reader != null && reader.HasRows) + { + reader.Read(); + Artist = reader.GetString(0); + Title = reader.GetString(1); + NumPlayed = reader.GetInt32(2); + reader.Close(); + reader.Dispose(); + + command.Dispose(); + connection.Close(); + connection.Dispose(); + return true; + } + else + { + if (reader != null) + reader.Close(); + } + + command.Dispose(); + connection.Close(); + connection.Dispose(); + + return false; + } + + private static void InitHighscoreDB() { string OldDBFilePath = Path.Combine(Environment.CurrentDirectory, CSettings.sFileOldHighscoreDB); if (File.Exists(OldDBFilePath)) { if (File.Exists(_HighscoreFilePath)) { - CLog.LogError("Found old Highscore DB (" + OldDBFilePath + "). If you want to import it just delete the new one (" + _HighscoreFilePath + ")"); + CreateOrConvert(OldDBFilePath); + CreateOrConvert(_HighscoreFilePath); + ImportData(OldDBFilePath, _HighscoreFilePath); + + File.Delete(OldDBFilePath); } else { File.Copy(OldDBFilePath, _HighscoreFilePath); - File.Move(OldDBFilePath, OldDBFilePath + ".old"); + CreateOrConvert(_HighscoreFilePath); + File.Delete(OldDBFilePath); } } + else + CreateOrConvert(_HighscoreFilePath); + } + private static void CreateHighscoreDB(string FilePath) + { SQLiteConnection connection = new SQLiteConnection(); - connection.ConnectionString = "Data Source=" + _HighscoreFilePath; + connection.ConnectionString = "Data Source=" + FilePath; + SQLiteCommand command; + + try + { + connection.Open(); + } + catch (Exception) + { + return; + } + + command = new SQLiteCommand(connection); + + command.CommandText = "CREATE TABLE IF NOT EXISTS Version ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, Value INTEGER NOT NULL);"; + command.ExecuteNonQuery(); + + command.CommandText = "INSERT INTO Version (id, Value) VALUES(NULL, " + CSettings.iDatabaseHighscoreVersion.ToString() + ")"; + command.ExecuteNonQuery(); + + command.CommandText = "CREATE TABLE IF NOT EXISTS Songs ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " + + "Artist TEXT NOT NULL, Title TEXT NOT NULL, NumPlayed INTEGER);"; + 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, " + + "Medley INTEGER NOT NULL, Duet INTEGER NOT NULL, Difficulty INTEGER NOT NULL);"; + command.ExecuteNonQuery(); + + command.Dispose(); + connection.Close(); + connection.Dispose(); + } + + /// + /// Creates a new Vocaluxe Database if no file exists. Converts an existing old Ultrastar Deluxe highscore database into vocaluxe format. + /// + /// Database file path + /// + private static bool CreateOrConvert(string FilePath) + { + SQLiteConnection connection = new SQLiteConnection(); + connection.ConnectionString = "Data Source=" + FilePath; SQLiteCommand command; try @@ -306,12 +522,12 @@ namespace Vocaluxe.Base if (reader == null) { // create new database/tables - CreateHighscoreDB(); + CreateHighscoreDB(FilePath); } else if (reader.FieldCount == 0) { // create new database/tables - CreateHighscoreDB(); + CreateHighscoreDB(FilePath); } else { @@ -349,10 +565,10 @@ namespace Vocaluxe.Base //Check for USDX 1.1 DB if (version == 1) - ConvertFrom110(); + ConvertFrom110(FilePath); //Check for USDX 1.01 or CMD Mod DB else if (version == 0 && scoresTableExists) - ConvertFrom101(); + ConvertFrom101(FilePath); command.Dispose(); @@ -362,61 +578,15 @@ namespace Vocaluxe.Base return true; } - private static void CreateHighscoreDB() - { - SQLiteConnection connection = new SQLiteConnection(); - connection.ConnectionString = "Data Source=" + _HighscoreFilePath; - SQLiteCommand command; - - try - { - connection.Open(); - } - catch (Exception) - { - return; - } - - command = new SQLiteCommand(connection); - - command.CommandText = "CREATE TABLE IF NOT EXISTS Version ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, Value INTEGER NOT NULL);"; - command.ExecuteNonQuery(); - - command.CommandText = "INSERT INTO Version (id, Value) VALUES(NULL, " + CSettings.iDatabaseHighscoreVersion.ToString() + ")"; - command.ExecuteNonQuery(); - - command.CommandText = "CREATE TABLE IF NOT EXISTS Songs ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " + - "Artist TEXT NOT NULL, Title TEXT NOT NULL, NumPlayed INTEGER);"; - 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, " + - "Medley INTEGER NOT NULL, Duet INTEGER NOT NULL, Difficulty INTEGER NOT NULL);"; - command.ExecuteNonQuery(); - - command.Dispose(); - connection.Close(); - connection.Dispose(); - - /* - // Auslesen des zuletzt eingefügten Datensatzes. - command.CommandText = "SELECT id, name FROM beispiel ORDER BY id DESC LIMIT 0, 1"; - - while (reader.Read()) - { - Console.WriteLine("Dies ist der {0}. eingefügte Datensatz mit dem Wert: \"{1}\"", reader[0].ToString(), reader[1].ToString()); - } - */ - } - /// /// Converts a USDX 1.1 database into the Vocaluxe format /// + /// Database file path /// True if succeeded - private static bool ConvertFrom110() + private static bool ConvertFrom110(string FilePath) { SQLiteConnection connection = new SQLiteConnection(); - connection.ConnectionString = "Data Source=" + _HighscoreFilePath; + connection.ConnectionString = "Data Source=" + FilePath; SQLiteCommand command; try @@ -534,11 +704,12 @@ namespace Vocaluxe.Base /// /// Converts a USDX 1.01 or CMD 1.01 database to Vocaluxe format /// + /// Database file path /// True if succeeded - private static bool ConvertFrom101() + private static bool ConvertFrom101(string FilePath) { SQLiteConnection connection = new SQLiteConnection(); - connection.ConnectionString = "Data Source=" + _HighscoreFilePath; + connection.ConnectionString = "Data Source=" + FilePath; SQLiteCommand command; SQLiteDataReader reader = null; @@ -591,11 +762,11 @@ namespace Vocaluxe.Base List songs = new List(); Sqlite3.sqlite3 OldDB; - int res = Sqlite3.sqlite3_open(_HighscoreFilePath, out OldDB); + int res = Sqlite3.sqlite3_open(FilePath, out OldDB); if (res != Sqlite3.SQLITE_OK) { - CLog.LogError("Error opening Database: " + _HighscoreFilePath + " (" + Sqlite3.sqlite3_errmsg(OldDB) + ")"); + CLog.LogError("Error opening Database: " + FilePath + " (" + Sqlite3.sqlite3_errmsg(OldDB) + ")"); } else { @@ -604,11 +775,11 @@ namespace Vocaluxe.Base if (res != Sqlite3.SQLITE_OK) { - CLog.LogError("Error query Database: " + _HighscoreFilePath + " (" + Sqlite3.sqlite3_errmsg(OldDB) + ")"); + CLog.LogError("Error query Database: " + FilePath + " (" + Sqlite3.sqlite3_errmsg(OldDB) + ")"); } else { - Sqlite3.sqlite3_step(Stmt); + //Sqlite3.sqlite3_step(Stmt); Encoding UTF8 = Encoding.UTF8; Encoding CP1252 = Encoding.GetEncoding(1252); @@ -639,11 +810,11 @@ namespace Vocaluxe.Base if (res != Sqlite3.SQLITE_OK) { - CLog.LogError("Error query Database: " + _HighscoreFilePath + " (" + Sqlite3.sqlite3_errmsg(OldDB) + ")"); + CLog.LogError("Error query Database: " + FilePath + " (" + Sqlite3.sqlite3_errmsg(OldDB) + ")"); } else { - Sqlite3.sqlite3_step(Stmt); + //Sqlite3.sqlite3_step(Stmt); Encoding UTF8 = Encoding.UTF8; Encoding CP1252 = Encoding.GetEncoding(1252); @@ -707,6 +878,71 @@ namespace Vocaluxe.Base return true; } + + private static bool ImportData(string SourceDBPath, string DestinationDBPath) + { + #region open db + SQLiteConnection connSource = new SQLiteConnection(); + connSource.ConnectionString = "Data Source=" + SourceDBPath; + + try + { + connSource.Open(); + } + catch (Exception e) + { + CLog.LogError("Error on import high score data. Can't open source database \"" + SourceDBPath + "\" (" + e.Message + ")"); + return false; + } + #endregion open db + + SQLiteCommand cmdSource = new SQLiteCommand(connSource); + SQLiteDataReader rSource; + + #region import table scores + cmdSource.CommandText = "SELECT SongID, PlayerName, Score, LineNr, Date, Medley, Duet, Difficulty FROM Scores"; + rSource = cmdSource.ExecuteReader(); + if (rSource == null) + { + cmdSource.Dispose(); + connSource.Close(); + return false; + } + + if (rSource.FieldCount == 0) + { + rSource.Close(); + cmdSource.Dispose(); + connSource.Close(); + return true; + } + + while (rSource.Read()) + { + int songid = rSource.GetInt32(0); + string player = rSource.GetString(1); + int score = rSource.GetInt32(2); + int linenr = rSource.GetInt32(3); + long date = rSource.GetInt64(4); + int medley = rSource.GetInt32(5); + int duet = rSource.GetInt32(6); + int diff = rSource.GetInt32(7); + + string artist, title; + int numplayed; + if (GetDataBaseSongInfos(songid, out artist, out title, out numplayed, SourceDBPath)) + { + AddScore(player, score, linenr, date, medley, duet, diff, artist, title, numplayed, _HighscoreFilePath); + } + } + #endregion import table scores + + rSource.Close(); + cmdSource.Dispose(); + connSource.Close(); + + return true; + } #endregion Highscores #region Cover From ca5132bf2c4c698aa41e64bc324f4457023feaf3 Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Sat, 3 Mar 2012 22:23:06 +0100 Subject: [PATCH 06/17] made the splash screen transparent (thx to Klafhor) --- Vocaluxe/Program.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Vocaluxe/Program.cs b/Vocaluxe/Program.cs index 6ff04a93..be340960 100644 --- a/Vocaluxe/Program.cs +++ b/Vocaluxe/Program.cs @@ -230,6 +230,7 @@ namespace Vocaluxe this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.Text = CSettings.sProgramName; this.CenterToScreen(); + this.TransparencyKey = this.BackColor; //thx to Klafhor :> this.Show(); } } From b62e726dfc42bfe326007335eddbbd31f81acd5c Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Sat, 3 Mar 2012 22:32:31 +0100 Subject: [PATCH 07/17] added readme content (by bohning) --- README | 128 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/README b/README index e69de29b..94701424 100644 --- a/README +++ b/README @@ -0,0 +1,128 @@ +Vocaluxe 0.1 README +---------------------------- + +================================= += 1. About = += 2. Release Notes = += 3. Command-Line Parameters = += 4. Controls = += 5. Help & Support = += 6. Source Code = +================================= + + +================================= += 1. About = +================================= + +Vocaluxe is a free and open source singing game. It allows up to three players (currently) to sing +along with music using microphones in order to score points, depending on the pitch of the voice +and the rhythm of singing. + +Vocaluxe is an entirely new development in C#, inspired by the original UltraStar (developed by corvus5) +and the great Ultrastar Deluxe project. + +Supported Operating Systems / Requirements: +- WinXP, Vista, Windows 7 with .NET 2.0 +- 1 GHz CPU, 512 MB RAM, Graphics card with OpenGL 2.1 or DirectX 9.0 support + + +================================= += 2. Release Notes = +================================= + +- The program supports 32bit and 64bit (Vocaluxe_x64.exe) operating systems. + +- The program uses OpenGL as the default renderer. If your graphics card driver does not or not + properly support OpenGL, you can try the Direct3D renderer by editing your Config.xml in the + application's main directory: + + + + TR_CONFIG_DIRECT3D + +- To add your existing song collection to Vocaluxe, put your songs into the 'Songs' subfolder. + + Alternatively, you can add multiple song paths to Vocaluxe by editing your Config.xml: + + + + C:\Vocaluxe\Songs + D:\EvenMore\Songs + +- To use your highscore database from UltraStar deluxe 1.0.1, UltraStar deluxe CMD Mod or + UltraStar deluxe 1.1, simply copy your Ultrastar.db (rename if necessary) into the main + directory. Your highscore database will be imported into the HighscoreDB.sqlite file when + Vocaluxe is started. Upon successful import, the old database is deleted. + +- To add your own player avatars, simply add some picture files to the 'Profiles' subfolder. + Supported file types: png, jpg (jpeg), bmp. + Images should have square proportions, e.g. 400x400 px. + + +================================= += 3. Command-Line Parameters = +================================= +commandline parameter: SongFolder, SongPath + +The following command-line parameters may be passed to the game when starting it through a shortcut +or from the console: + +-ConfigFile [Path\File]: Use [Path\File] as configuration file instead of Config.xml in the main folder. + The path to the file has to exist and needs to be an absolute path. + If only a filename is specified, the file is assumed to be in the current directory. + Examples: Vocaluxe.exe -ConfigFile MyConfig.xml + Vocaluxe.exe -ConfigFile C:\Vocaluxe\Configs\MyConfig.xml + +-ScoreFile [Path\File] : Use [File] as score database instead of HighscoreDB.sqlite in the application's + main folder. The path to the file has to exist and needs to be an absolute path. + If only a filename is specified, the file is assumed to be in the current directory. + Example: Vocaluxe.exe -ScoreFile MyHighscoreDB.sqlite + Vocaluxe.exe -Scorefile C:\Vocaluxe\Highscores\MyHighscoreDB.sqlite + +-SongFolder [Path] : Use [Path] as song folder. The path has to exist and needs to be an absolute path. + Note that any song folders set in the config file will be ignored. + This parameter may be used multiple times to use different song folders. + Example: Vocaluxe.exe -SongFolder D:\MySongCollection + Vocaluxe.exe -SongFolder D:\MySongCollection -SongFolder E:\MoreSongs + +-SongPath [Path] : Deprecated, see SongFolder [Path]. This alias is provided for convenience. + +Complete example: +Vocaluxe.exe -ConfigFile MyConfig.xml -ScoreFile C:\Vocaluxe\Highscores\MyHighscoreDB.sqlite -SongFolder D:\MySongCollection + + +================================= += 4. Controls = +================================= +[Mouse] to navigate through the screens: Left button: select/manipulate elements, + Right button: go to previous screen. +[Cursor] to navigate through the screens. +[Enter] to confirm +[Escape] or [Back] to go to the previous screen. + +[ALT] + [P] to take a ScreenShot. Screenshots are saved in the directory "Screenshots". +[ALT] + [ENTER] to toggle full screen mode. +[SHIFT] + [F1] to toggle theme edit mode. The theme edit mode ist experimental. It allows you + to change the size and position of the element on the screens. You can save + your changes with [S] before leaving the theme edit mode. +[TAB] to open the background music controls (not on all screens). + +Songscreen +[R] to select a random song +[F3] or [CTRL]+[F] to open/close the song search menu +[A] to sing all songs from a category + + +================================= += 5. Help & Suppport = +================================= +Support Forum (German): http://www.ultra-star.de +Song-DataBase (USDB): ttp://usdb.animux.de/ + + +================================= += 6. Source Code = +================================= +Source Code (GitHub): https://github.com/Vocaluxe/Vocaluxe +SF.Net Page: http://sourceforge.net/projects/vocaluxe/ \ No newline at end of file From 05fa8a74ce11d1bfdc286b374f0d9467575a442f Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Sat, 3 Mar 2012 22:46:19 +0100 Subject: [PATCH 08/17] moved Readme to Output folder, deleted main readme (it must be rewritten) --- Output/Readme.txt | 128 ++++++++++++++++++++++++++++++++++++++++++++++ README | 128 ---------------------------------------------- 2 files changed, 128 insertions(+), 128 deletions(-) create mode 100644 Output/Readme.txt diff --git a/Output/Readme.txt b/Output/Readme.txt new file mode 100644 index 00000000..e48eda3f --- /dev/null +++ b/Output/Readme.txt @@ -0,0 +1,128 @@ +Vocaluxe 0.1 README +---------------------------- + +================================= += 1. About = += 2. Release Notes = += 3. Command-Line Parameters = += 4. Controls = += 5. Help & Support = += 6. Source Code = +================================= + + +================================= += 1. About = +================================= + +Vocaluxe is a free and open source singing game. It allows up to three players (currently) to sing +along with music using microphones in order to score points, depending on the pitch of the voice +and the rhythm of singing. + +Vocaluxe is an entirely new development in C#, inspired by the original UltraStar (developed by corvus5) +and the great Ultrastar Deluxe project. + +Supported Operating Systems / Requirements: +- WinXP, Vista, Windows 7 with .NET 2.0 +- 1 GHz CPU, 512 MB RAM, Graphics card with OpenGL 2.1 or DirectX 9.0 support + + +================================= += 2. Release Notes = +================================= + +- The program supports 32bit and 64bit (Vocaluxe_x64.exe) operating systems. + +- The program uses OpenGL as the default renderer. If your graphics card driver does not or not + properly support OpenGL, you can try the Direct3D renderer by editing your Config.xml in the + application's main directory: + + + + TR_CONFIG_DIRECT3D + +- To add your existing song collection to Vocaluxe, put your songs into the 'Songs' subfolder. + + Alternatively, you can add multiple song paths to Vocaluxe by editing your Config.xml: + + + + C:\Vocaluxe\Songs + D:\EvenMore\Songs + +- To use your highscore database from UltraStar deluxe 1.0.1, UltraStar deluxe CMD Mod or + UltraStar deluxe 1.1, simply copy your Ultrastar.db (rename if necessary) into the main + directory. Your highscore database will be imported into the HighscoreDB.sqlite file when + Vocaluxe is started. Upon successful import, the old database is deleted. + +- To add your own player avatars, simply add some picture files to the 'Profiles' subfolder. + Supported file types: png, jpg (jpeg), bmp. + Images should have square proportions, e.g. 400x400 px. + + +================================= += 3. Command-Line Parameters = +================================= +commandline parameter: SongFolder, SongPath + +The following command-line parameters may be passed to the game when starting it through a shortcut +or from the console: + +-ConfigFile [Path\File]: Use [Path\File] as configuration file instead of Config.xml in the main folder. + The path to the file has to exist and needs to be an absolute path. + If only a filename is specified, the file is assumed to be in the current directory. + Examples: Vocaluxe.exe -ConfigFile MyConfig.xml + Vocaluxe.exe -ConfigFile C:\Vocaluxe\Configs\MyConfig.xml + +-ScoreFile [Path\File] : Use [File] as score database instead of HighscoreDB.sqlite in the application's + main folder. The path to the file has to exist and needs to be an absolute path. + If only a filename is specified, the file is assumed to be in the current directory. + Example: Vocaluxe.exe -ScoreFile MyHighscoreDB.sqlite + Vocaluxe.exe -Scorefile C:\Vocaluxe\Highscores\MyHighscoreDB.sqlite + +-SongFolder [Path] : Use [Path] as song folder. The path has to exist and needs to be an absolute path. + Note that any song folders set in the config file will be ignored. + This parameter may be used multiple times to use different song folders. + Example: Vocaluxe.exe -SongFolder D:\MySongCollection + Vocaluxe.exe -SongFolder D:\MySongCollection -SongFolder E:\MoreSongs + +-SongPath [Path] : Deprecated, see SongFolder [Path]. This alias is provided for convenience. + +Complete example: +Vocaluxe.exe -ConfigFile MyConfig.xml -ScoreFile C:\Vocaluxe\Highscores\MyHighscoreDB.sqlite -SongFolder D:\MySongCollection + + +================================= += 4. Controls = +================================= +[Mouse] to navigate through the screens: Left button: select/manipulate elements, + Right button: go to previous screen. +[Cursor] to navigate through the screens. +[Enter] to confirm +[Escape] or [Back] to go to the previous screen. + +[ALT] + [P] to take a ScreenShot. Screenshots are saved in the directory "Screenshots". +[ALT] + [ENTER] to toggle full screen mode. +[SHIFT] + [F1] to toggle theme edit mode. The theme edit mode ist experimental. It allows you + to change the size and position of the element on the screens. You can save + your changes with [S] before leaving the theme edit mode. +[TAB] to open the background music controls (not on all screens). + +Songscreen +[R] to select a random song +[F3] or [CTRL]+[F] to open/close the song search menu +[A] to sing all songs from a category + + +================================= += 5. Help & Suppport = +================================= +Support Forum (German): http://www.ultra-star.de +Song-DataBase (USDB): http://usdb.animux.de/ + + +================================= += 6. Source Code = +================================= +Source Code (GitHub): https://github.com/Vocaluxe/Vocaluxe +SF.Net Page: http://sourceforge.net/projects/vocaluxe/ \ No newline at end of file diff --git a/README b/README index 94701424..e69de29b 100644 --- a/README +++ b/README @@ -1,128 +0,0 @@ -Vocaluxe 0.1 README ----------------------------- - -================================= -= 1. About = -= 2. Release Notes = -= 3. Command-Line Parameters = -= 4. Controls = -= 5. Help & Support = -= 6. Source Code = -================================= - - -================================= -= 1. About = -================================= - -Vocaluxe is a free and open source singing game. It allows up to three players (currently) to sing -along with music using microphones in order to score points, depending on the pitch of the voice -and the rhythm of singing. - -Vocaluxe is an entirely new development in C#, inspired by the original UltraStar (developed by corvus5) -and the great Ultrastar Deluxe project. - -Supported Operating Systems / Requirements: -- WinXP, Vista, Windows 7 with .NET 2.0 -- 1 GHz CPU, 512 MB RAM, Graphics card with OpenGL 2.1 or DirectX 9.0 support - - -================================= -= 2. Release Notes = -================================= - -- The program supports 32bit and 64bit (Vocaluxe_x64.exe) operating systems. - -- The program uses OpenGL as the default renderer. If your graphics card driver does not or not - properly support OpenGL, you can try the Direct3D renderer by editing your Config.xml in the - application's main directory: - - - - TR_CONFIG_DIRECT3D - -- To add your existing song collection to Vocaluxe, put your songs into the 'Songs' subfolder. - - Alternatively, you can add multiple song paths to Vocaluxe by editing your Config.xml: - - - - C:\Vocaluxe\Songs - D:\EvenMore\Songs - -- To use your highscore database from UltraStar deluxe 1.0.1, UltraStar deluxe CMD Mod or - UltraStar deluxe 1.1, simply copy your Ultrastar.db (rename if necessary) into the main - directory. Your highscore database will be imported into the HighscoreDB.sqlite file when - Vocaluxe is started. Upon successful import, the old database is deleted. - -- To add your own player avatars, simply add some picture files to the 'Profiles' subfolder. - Supported file types: png, jpg (jpeg), bmp. - Images should have square proportions, e.g. 400x400 px. - - -================================= -= 3. Command-Line Parameters = -================================= -commandline parameter: SongFolder, SongPath - -The following command-line parameters may be passed to the game when starting it through a shortcut -or from the console: - --ConfigFile [Path\File]: Use [Path\File] as configuration file instead of Config.xml in the main folder. - The path to the file has to exist and needs to be an absolute path. - If only a filename is specified, the file is assumed to be in the current directory. - Examples: Vocaluxe.exe -ConfigFile MyConfig.xml - Vocaluxe.exe -ConfigFile C:\Vocaluxe\Configs\MyConfig.xml - --ScoreFile [Path\File] : Use [File] as score database instead of HighscoreDB.sqlite in the application's - main folder. The path to the file has to exist and needs to be an absolute path. - If only a filename is specified, the file is assumed to be in the current directory. - Example: Vocaluxe.exe -ScoreFile MyHighscoreDB.sqlite - Vocaluxe.exe -Scorefile C:\Vocaluxe\Highscores\MyHighscoreDB.sqlite - --SongFolder [Path] : Use [Path] as song folder. The path has to exist and needs to be an absolute path. - Note that any song folders set in the config file will be ignored. - This parameter may be used multiple times to use different song folders. - Example: Vocaluxe.exe -SongFolder D:\MySongCollection - Vocaluxe.exe -SongFolder D:\MySongCollection -SongFolder E:\MoreSongs - --SongPath [Path] : Deprecated, see SongFolder [Path]. This alias is provided for convenience. - -Complete example: -Vocaluxe.exe -ConfigFile MyConfig.xml -ScoreFile C:\Vocaluxe\Highscores\MyHighscoreDB.sqlite -SongFolder D:\MySongCollection - - -================================= -= 4. Controls = -================================= -[Mouse] to navigate through the screens: Left button: select/manipulate elements, - Right button: go to previous screen. -[Cursor] to navigate through the screens. -[Enter] to confirm -[Escape] or [Back] to go to the previous screen. - -[ALT] + [P] to take a ScreenShot. Screenshots are saved in the directory "Screenshots". -[ALT] + [ENTER] to toggle full screen mode. -[SHIFT] + [F1] to toggle theme edit mode. The theme edit mode ist experimental. It allows you - to change the size and position of the element on the screens. You can save - your changes with [S] before leaving the theme edit mode. -[TAB] to open the background music controls (not on all screens). - -Songscreen -[R] to select a random song -[F3] or [CTRL]+[F] to open/close the song search menu -[A] to sing all songs from a category - - -================================= -= 5. Help & Suppport = -================================= -Support Forum (German): http://www.ultra-star.de -Song-DataBase (USDB): ttp://usdb.animux.de/ - - -================================= -= 6. Source Code = -================================= -Source Code (GitHub): https://github.com/Vocaluxe/Vocaluxe -SF.Net Page: http://sourceforge.net/projects/vocaluxe/ \ No newline at end of file From c377a583da0511ff7a6aadbf49db893e3d25753d Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Sat, 3 Mar 2012 23:08:29 +0100 Subject: [PATCH 09/17] fixed typo --- Output/Readme.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Output/Readme.txt b/Output/Readme.txt index e48eda3f..4c70d54f 100644 --- a/Output/Readme.txt +++ b/Output/Readme.txt @@ -103,7 +103,7 @@ Vocaluxe.exe -ConfigFile MyConfig.xml -ScoreFile C:\Vocaluxe\Highscores\MyHighsc [ALT] + [P] to take a ScreenShot. Screenshots are saved in the directory "Screenshots". [ALT] + [ENTER] to toggle full screen mode. -[SHIFT] + [F1] to toggle theme edit mode. The theme edit mode ist experimental. It allows you +[SHIFT] + [F1] to toggle theme edit mode. The theme edit mode is experimental. It allows you to change the size and position of the element on the screens. You can save your changes with [S] before leaving the theme edit mode. [TAB] to open the background music controls (not on all screens). From bd36b3d1d4f50eac6f97b59f342f4491d09a89eb Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Sun, 4 Mar 2012 00:41:07 +0100 Subject: [PATCH 10/17] fixed lyric sub fading --- Vocaluxe/Screens/CScreenSing.cs | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs index 48ea1105..8dc101cf 100644 --- a/Vocaluxe/Screens/CScreenSing.cs +++ b/Vocaluxe/Screens/CScreenSing.cs @@ -581,7 +581,8 @@ namespace Vocaluxe.Screens lines[i] = song.Notes.GetLines(i); CLine[] line = lines[i].Line; - + + // find current line (it must be the same as in CalcFadingAlpha) int nr = -1; for (int j = 0; j < line.Length; j++) { @@ -850,12 +851,16 @@ namespace Vocaluxe.Screens lines[i] = Song.Notes.GetLines(i); CLine[] line = lines[i].Line; + // find current line (it must be the same as in UpdateLyrics) int CurrentLine = 0; for (int j = 0; j < line.Length; j++) { - if (line[j].FirstBeat <= _CurrentBeat) + if (line[j].StartBeat <= _CurrentBeat) { - CurrentLine = j; + if (CGame.GetTimeFromBeats(line[j].FirstBeat, Song.BPM) <= _CurrentTime - Song.Gap + 10f) + { + CurrentLine = j; + } } } @@ -863,9 +868,11 @@ namespace Vocaluxe.Screens Alpha[i * 2] = 1f; Alpha[i * 2 + 1] = 1f; - // main + // main line alpha if (CurrentLine == 0 && CurrentTime < CGame.GetTimeFromBeats(line[CurrentLine].FirstBeat, Song.BPM)) { + // first main line and fist note is not reached + // => fade in float diff = CGame.GetTimeFromBeats(line[CurrentLine].FirstBeat, Song.BPM) - CurrentTime; if (diff > dt) { @@ -875,20 +882,29 @@ namespace Vocaluxe.Screens else if (CurrentLine < line.Length - 1 && CGame.GetTimeFromBeats(line[CurrentLine].LastBeat, Song.BPM) < CurrentTime && CGame.GetTimeFromBeats(line[CurrentLine + 1].FirstBeat, Song.BPM) > CurrentTime) { + // current position is between two lines + + // time between the to lines float diff = CGame.GetTimeFromBeats(line[CurrentLine + 1].FirstBeat, Song.BPM) - CGame.GetTimeFromBeats(line[CurrentLine].LastBeat, Song.BPM); + // fade only if there is enough time for fading if (diff > 3.3f * dt) { + // time elapsed since last line float last = CurrentTime - CGame.GetTimeFromBeats(line[CurrentLine].LastBeat, Song.BPM); + + // time to next line float next = CGame.GetTimeFromBeats(line[CurrentLine + 1].FirstBeat, Song.BPM) - CurrentTime; if (last < next) { + // fade out Alpha[i * 2] = 1f - last / rt; } else { + // fade in if it is time for if (next > dt) Alpha[i * 2] = 1f - (next - dt) / rt; } @@ -896,6 +912,8 @@ namespace Vocaluxe.Screens } else if (CurrentLine == line.Length - 1 && CGame.GetTimeFromBeats(line[CurrentLine].LastBeat, Song.BPM) < CurrentTime) { + // last main line and last note was reached + // => fade out float diff = CurrentTime - CGame.GetTimeFromBeats(line[CurrentLine].LastBeat, Song.BPM); Alpha[i * 2] = 1f - diff / rt; } @@ -903,7 +921,9 @@ namespace Vocaluxe.Screens // sub if (CurrentLine < line.Length - 2) { - float diff = CGame.GetTimeFromBeats(line[CurrentLine + 1].FirstBeat, Song.BPM) - CurrentTime; + float diff = 0f; + diff = CGame.GetTimeFromBeats(line[CurrentLine + 1].FirstBeat, Song.BPM) - CurrentTime; + if (diff > dt) { Alpha[i * 2 + 1] = 1f - (diff - dt) / rt; From 848f5b62aa4cae2758d009cf3af8266a810e0a33 Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Sun, 4 Mar 2012 01:21:02 +0100 Subject: [PATCH 11/17] new splash screen logo file (with transparency), new splash screen drawing method --- Output/Graphics/Logo.png | Bin 37695 -> 66732 bytes Vocaluxe/Program.cs | 19 ++++++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Output/Graphics/Logo.png b/Output/Graphics/Logo.png index 2ad40d2f13131c8b31473857e28b2fac9b0e0021..0977ea9356599e16195b4706483eb18d800ec7f3 100644 GIT binary patch delta 64529 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�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 r`fp12f4{5$=Wkjpd#{8LkYp;W187W6*=5J4sV delta 35264 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

93H9dH@f9l2)=-41;w?zn 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 this.Show(); } + + protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) + { + } + + protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e) + { + if (logo == null) + return; + + Graphics g = e.Graphics; + g.DrawImage(logo, new Rectangle(0, 0, this.Width, this.Height)); + } } } From 54a9856626fa1131181ceb6676fa90f2d5f6f2a5 Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Sun, 4 Mar 2012 13:09:04 +0100 Subject: [PATCH 12/17] fixed transparency of splash screen --- Vocaluxe/Program.cs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Vocaluxe/Program.cs b/Vocaluxe/Program.cs index 144db8f6..0f843119 100644 --- a/Vocaluxe/Program.cs +++ b/Vocaluxe/Program.cs @@ -141,7 +141,7 @@ namespace Vocaluxe CLog.StopBenchmark(0, "Init Game"); Application.DoEvents(); - + System.Threading.Thread.Sleep(10000); // Start Main Loop _SplashScreen.Close(); CDraw.MainLoop(); @@ -193,6 +193,7 @@ namespace Vocaluxe class SplashScreen : Form { Bitmap logo; + Timer UpdateTimer; public SplashScreen() { @@ -227,15 +228,18 @@ namespace Vocaluxe } else CLog.LogError("Can't find " + path); - + + SetStyle(ControlStyles.SupportsTransparentBackColor, true); + this.BackColor = Color.Transparent; + this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None; this.Text = CSettings.sProgramName; this.CenterToScreen(); this.Show(); } - + protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) - { + { } protected override void OnPaintBackground(System.Windows.Forms.PaintEventArgs e) @@ -245,6 +249,6 @@ namespace Vocaluxe Graphics g = e.Graphics; g.DrawImage(logo, new Rectangle(0, 0, this.Width, this.Height)); - } + } } } From 36e15f2c5528ac0394895564dfef32de25644783 Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Sun, 4 Mar 2012 13:09:45 +0100 Subject: [PATCH 13/17] removed unneeded update timer --- Vocaluxe/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/Vocaluxe/Program.cs b/Vocaluxe/Program.cs index 0f843119..940951f5 100644 --- a/Vocaluxe/Program.cs +++ b/Vocaluxe/Program.cs @@ -193,7 +193,6 @@ namespace Vocaluxe class SplashScreen : Form { Bitmap logo; - Timer UpdateTimer; public SplashScreen() { From bca806b8d311ef00f79eb4acfc5ec1e1ee1ced8f Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Sun, 4 Mar 2012 13:37:18 +0100 Subject: [PATCH 14/17] fixed lyric fading (no popping effect any more) --- Vocaluxe/Screens/CScreenSing.cs | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs index 8dc101cf..8e947a04 100644 --- a/Vocaluxe/Screens/CScreenSing.cs +++ b/Vocaluxe/Screens/CScreenSing.cs @@ -851,19 +851,29 @@ namespace Vocaluxe.Screens lines[i] = Song.Notes.GetLines(i); CLine[] line = lines[i].Line; - // find current line (it must be the same as in UpdateLyrics) - int CurrentLine = 0; + // find current line for lyric sub fading (it must be the same as in UpdateLyrics) + int CurrentLineSub = 0; for (int j = 0; j < line.Length; j++) { if (line[j].StartBeat <= _CurrentBeat) { if (CGame.GetTimeFromBeats(line[j].FirstBeat, Song.BPM) <= _CurrentTime - Song.Gap + 10f) { - CurrentLine = j; + CurrentLineSub = j; } } } + // find current line for lyric main fading + int CurrentLine = 0; + for (int j = 0; j < line.Length; j++) + { + if (line[j].FirstBeat <= _CurrentBeat) + { + CurrentLine = j; + } + } + // default values Alpha[i * 2] = 1f; Alpha[i * 2 + 1] = 1f; @@ -919,10 +929,10 @@ namespace Vocaluxe.Screens } // sub - if (CurrentLine < line.Length - 2) + if (CurrentLineSub < line.Length - 2) { float diff = 0f; - diff = CGame.GetTimeFromBeats(line[CurrentLine + 1].FirstBeat, Song.BPM) - CurrentTime; + diff = CGame.GetTimeFromBeats(line[CurrentLineSub + 1].FirstBeat, Song.BPM) - CurrentTime; if (diff > dt) { From 937804c7a92825f10f97e43e561833f427578ecb Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Sun, 4 Mar 2012 13:52:31 +0100 Subject: [PATCH 15/17] update of readme --- Output/Readme.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/Output/Readme.txt b/Output/Readme.txt index 4c70d54f..94565fbb 100644 --- a/Output/Readme.txt +++ b/Output/Readme.txt @@ -63,8 +63,6 @@ Supported Operating Systems / Requirements: ================================= = 3. Command-Line Parameters = ================================= -commandline parameter: SongFolder, SongPath - The following command-line parameters may be passed to the game when starting it through a shortcut or from the console: From 35d32272a2b472dab443e9d66cc680144f5fec0b Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Sun, 4 Mar 2012 14:00:14 +0100 Subject: [PATCH 16/17] update of readme --- Output/Readme.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Output/Readme.txt b/Output/Readme.txt index 94565fbb..4f05511a 100644 --- a/Output/Readme.txt +++ b/Output/Readme.txt @@ -75,13 +75,13 @@ or from the console: -ScoreFile [Path\File] : Use [File] as score database instead of HighscoreDB.sqlite in the application's main folder. The path to the file has to exist and needs to be an absolute path. If only a filename is specified, the file is assumed to be in the current directory. - Example: Vocaluxe.exe -ScoreFile MyHighscoreDB.sqlite + Examples: Vocaluxe.exe -ScoreFile MyHighscoreDB.sqlite Vocaluxe.exe -Scorefile C:\Vocaluxe\Highscores\MyHighscoreDB.sqlite -SongFolder [Path] : Use [Path] as song folder. The path has to exist and needs to be an absolute path. Note that any song folders set in the config file will be ignored. This parameter may be used multiple times to use different song folders. - Example: Vocaluxe.exe -SongFolder D:\MySongCollection + Examples: Vocaluxe.exe -SongFolder D:\MySongCollection Vocaluxe.exe -SongFolder D:\MySongCollection -SongFolder E:\MoreSongs -SongPath [Path] : Deprecated, see SongFolder [Path]. This alias is provided for convenience. From 41afaca2b83c6a9ba2ba8429f06b01aa922c15f1 Mon Sep 17 00:00:00 2001 From: Alexander Eckart Date: Sun, 4 Mar 2012 16:37:59 +0100 Subject: [PATCH 17/17] do not load songs if the mp3 does not exists --- Vocaluxe/Lib/Song/CSong.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Vocaluxe/Lib/Song/CSong.cs b/Vocaluxe/Lib/Song/CSong.cs index 39c1d35f..1327363b 100644 --- a/Vocaluxe/Lib/Song/CSong.cs +++ b/Vocaluxe/Lib/Song/CSong.cs @@ -237,6 +237,11 @@ namespace Vocaluxe.Lib.Song this.MP3FileName = Value; HeaderFlags |= EHeaderFlags.MP3; } + else + { + CLog.LogError("Can't find audio file: " + Path.Combine(this.Folder, Value)); + return false; + } break; case "BPM": if (CHelper.TryParse(Value, out this.BPM)) @@ -283,6 +288,9 @@ namespace Vocaluxe.Lib.Song case "VIDEO": if (File.Exists(Path.Combine(this.Folder, Value))) this.VideoFileName = Value; + else + CLog.LogError("Can't find video file: " + Path.Combine(this.Folder, Value)); + break; case "VIDEOGAP": CHelper.TryParse(Value, out this.VideoGap);