diff --git a/Output/CreditsRessourcesDB.sqlite b/Output/CreditsRessourcesDB.sqlite
new file mode 100644
index 00000000..dbfe78bb
Binary files /dev/null and b/Output/CreditsRessourcesDB.sqlite differ
diff --git a/Output/Graphics/Logo.png b/Output/Graphics/Logo.png
index 2ad40d2f..0977ea93 100644
Binary files a/Output/Graphics/Logo.png and b/Output/Graphics/Logo.png differ
diff --git a/Output/Languages/Spanish.xml b/Output/Languages/Spanish.xml
index 8787eca0..cb106774 100644
--- a/Output/Languages/Spanish.xml
+++ b/Output/Languages/Spanish.xml
@@ -55,7 +55,7 @@
Lista
Dreidel
- TileBoard
+ Cuadrícula
Libro
Según Sean Necesarias
diff --git a/Output/Readme.txt b/Output/Readme.txt
new file mode 100644
index 00000000..4f05511a
--- /dev/null
+++ b/Output/Readme.txt
@@ -0,0 +1,126 @@
+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 =
+=================================
+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.
+ 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.
+ 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.
+
+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 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).
+
+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/Output/Themes/Ambient/Screens/ScreenOptionsSound.xml b/Output/Themes/Ambient/Screens/ScreenOptionsSound.xml
index 5d3d0e9e..259915bd 100644
--- a/Output/Themes/Ambient/Screens/ScreenOptionsSound.xml
+++ b/Output/Themes/Ambient/Screens/ScreenOptionsSound.xml
@@ -1,7 +1,7 @@
- 1
+ 2
Video
@@ -394,4 +394,4 @@
1
-
\ No newline at end of file
+
diff --git a/Output/Themes/Changelog/Changelog_ScreenOptionsSound.txt b/Output/Themes/Changelog/Changelog_ScreenOptionsSound.txt
new file mode 100644
index 00000000..5bdf4bfd
--- /dev/null
+++ b/Output/Themes/Changelog/Changelog_ScreenOptionsSound.txt
@@ -0,0 +1,18 @@
+ScreenOptionsSound
+
+++++++++++
+Version 2:
+
+Add:
+
+
+
+
+
+
+
+and some texts for description (Text2, Text3, Text4)
+"TR_SCREENOSOUND_BACKGROUNDMUSIC"
+"TR_SCREENOSOUND_BACKGROUNDMUSICVOLUME"
+"TR_SCREENOSOUND_BACKGROUNDMUSICSOURCE"
+++++++++++
diff --git a/Vocaluxe/Base/CConfig.cs b/Vocaluxe/Base/CConfig.cs
index 9bbafce3..00ced7f0 100644
--- a/Vocaluxe/Base/CConfig.cs
+++ b/Vocaluxe/Base/CConfig.cs
@@ -66,6 +66,19 @@ namespace Vocaluxe.Base
TR_CONFIG_LEVEL_MAX //all debug infos
}
+ public enum EBufferSize
+ {
+ b0 = 0,
+ b512 = 512,
+ b1024 = 1024,
+ b1536 = 1536,
+ b2048 = 2048,
+ b2560 = 2560,
+ b3072 = 3072,
+ b3584 = 3584,
+ b4096 = 4096
+ }
+
public enum EPlaybackLib
{
PortAudio,
@@ -177,7 +190,8 @@ namespace Vocaluxe.Base
// Sound
public static EPlaybackLib PlayBackLib = EPlaybackLib.PortAudio;
public static ERecordLib RecordLib = ERecordLib.PortAudio;
- public static uint PortAudioBufferSize = 1024;
+ public static EBufferSize AudioBufferSize = EBufferSize.b2048;
+ public static int AudioLatency = 125;
public static int BackgroundMusicVolume = 50;
public static EOffOn BackgroundMusic = EOffOn.TR_CONFIG_ON;
public static EBackgroundMusicSource BackgroundMusicSource = EBackgroundMusicSource.TR_CONFIG_NO_OWN_MUSIC;
@@ -287,6 +301,14 @@ namespace Vocaluxe.Base
#region Sound
CHelper.TryGetEnumValueFromXML("//root/Sound/PlayBackLib", navigator, ref PlayBackLib);
CHelper.TryGetEnumValueFromXML("//root/Sound/RecordLib", navigator, ref RecordLib);
+ CHelper.TryGetEnumValueFromXML("//root/Sound/AudioBufferSize", navigator, ref AudioBufferSize);
+
+ CHelper.TryGetIntValueFromXML("//root/Sound/AudioLatency", navigator, ref AudioLatency);
+ if (AudioLatency < -500)
+ AudioLatency = -500;
+ if (AudioLatency > 500)
+ AudioLatency = 500;
+
CHelper.TryGetEnumValueFromXML("//root/Sound/BackgroundMusic", navigator, ref BackgroundMusic);
CHelper.TryGetIntValueFromXML("//root/Sound/BackgroundMusicVolume", navigator, ref BackgroundMusicVolume);
CHelper.TryGetEnumValueFromXML("//root/Sound/BackgroundMusicSource", navigator, ref BackgroundMusicSource);
@@ -482,8 +504,14 @@ namespace Vocaluxe.Base
writer.WriteComment("RecordLib: " + ListStrings(Enum.GetNames(typeof(ERecordLib))));
writer.WriteElementString("RecordLib", Enum.GetName(typeof(ERecordLib), RecordLib));
+ writer.WriteComment("AudioBufferSize: " + ListStrings(Enum.GetNames(typeof(EBufferSize))));
+ writer.WriteElementString("AudioBufferSize", Enum.GetName(typeof(EBufferSize), AudioBufferSize));
+
+ writer.WriteComment("AudioLatency from -500 to 500 ms");
+ writer.WriteElementString("AudioLatency", AudioLatency.ToString());
+
writer.WriteComment("Background Music");
- writer.WriteElementString("BackgroundMusicEnabled", Enum.GetName(typeof(EOffOn), BackgroundMusic));
+ writer.WriteElementString("BackgroundMusic", Enum.GetName(typeof(EOffOn), BackgroundMusic));
writer.WriteComment("Background Music Volume from 0 to 100");
writer.WriteElementString("BackgroundMusicVolume", BackgroundMusicVolume.ToString());
diff --git a/Vocaluxe/Base/CDataBase.cs b/Vocaluxe/Base/CDataBase.cs
index 90b52a93..15c6f6f2 100644
--- a/Vocaluxe/Base/CDataBase.cs
+++ b/Vocaluxe/Base/CDataBase.cs
@@ -27,21 +27,59 @@ namespace Vocaluxe.Base
private static string _HighscoreFilePath;
private static string _CoverFilePath;
+ private static string _CreditsRessourcesFilePath;
public static void Init()
{
_HighscoreFilePath = Path.Combine(System.Environment.CurrentDirectory, CSettings.sFileHighscoreDB);
_CoverFilePath = Path.Combine(System.Environment.CurrentDirectory, CSettings.sFileCoverDB);
+ _CreditsRessourcesFilePath = Path.Combine(System.Environment.CurrentDirectory, CSettings.sFileCreditsRessourcesDB);
InitHighscoreDB();
InitCoverDB();
+ InitCreditsRessourcesDB();
}
#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 +96,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 +118,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 +165,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 +187,6 @@ namespace Vocaluxe.Base
}
}
- command.Dispose();
- connection.Close();
- connection.Dispose();
-
return lastInsertID;
}
@@ -120,7 +197,7 @@ namespace Vocaluxe.Base
SQLiteCommand command;
Score = new List();
-
+
try
{
connection.Open();
@@ -149,7 +226,7 @@ namespace Vocaluxe.Base
command.Parameters.Add("@SongID", System.Data.DbType.Int32, 0).Value = DataBaseSongID;
command.Parameters.Add("@Medley", System.Data.DbType.Int32, 0).Value = Medley;
command.Parameters.Add("@Duet", System.Data.DbType.Int32, 0).Value = Duet;
-
+
SQLiteDataReader reader = null;
try
{
@@ -174,13 +251,13 @@ namespace Vocaluxe.Base
Score.Add(score);
}
-
+
reader.Close();
- reader.Dispose();
+ reader.Dispose();
}
-
+
}
-
+
command.Dispose();
connection.Close();
@@ -194,9 +271,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 +328,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
@@ -256,14 +363,140 @@ namespace Vocaluxe.Base
reader.Close();
reader.Dispose();
}
-
+
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))
+ {
+ CreateOrConvert(OldDBFilePath);
+ CreateOrConvert(_HighscoreFilePath);
+ ImportData(OldDBFilePath, _HighscoreFilePath);
+
+ File.Delete(OldDBFilePath);
+ }
+ else
+ {
+ File.Copy(OldDBFilePath, _HighscoreFilePath);
+ 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
@@ -292,12 +525,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
{
@@ -335,10 +568,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();
@@ -348,61 +581,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
@@ -495,7 +682,7 @@ namespace Vocaluxe.Base
command.Parameters.Add("@id", System.Data.DbType.Int32, 0).Value = data.id;
command.ExecuteNonQuery();
}
-
+
//Delete old tables after conversion
command.CommandText = "DROP TABLE US_Scores;";
command.ExecuteNonQuery();
@@ -520,11 +707,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;
@@ -541,7 +729,7 @@ namespace Vocaluxe.Base
command.CommandText = "PRAGMA table_info(US_Scores);";
reader = command.ExecuteReader();
-
+
bool dateExists = false;
@@ -558,12 +746,12 @@ namespace Vocaluxe.Base
}
}
}
-
+
reader.Close();
//This is a USDX 1.01 DB
- if(!dateExists)
+ if (!dateExists)
command.CommandText = "INSERT INTO Scores (SongID, PlayerName, Score, LineNr, Date, Medley, Duet, Difficulty) SELECT SongID, Player, Score, '0', '0', '0', '0', Difficulty from US_Scores";
else // This is a CMD 1.01 DB
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";
@@ -577,11 +765,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
{
@@ -590,11 +778,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);
@@ -605,9 +793,9 @@ namespace Vocaluxe.Base
data.id = Sqlite3.sqlite3_column_int(Stmt, 0);
- byte[] bytes = Sqlite3.sqlite3_column_rawbytes(Stmt, 1);
+ byte[] bytes = Sqlite3.sqlite3_column_rawbytes(Stmt, 1);
data.str1 = UTF8.GetString(Encoding.Convert(CP1252, UTF8, bytes));
-
+
bytes = Sqlite3.sqlite3_column_rawbytes(Stmt, 2);
data.str2 = UTF8.GetString(Encoding.Convert(CP1252, UTF8, bytes));
@@ -617,7 +805,7 @@ namespace Vocaluxe.Base
}
Stmt = new Sqlite3.Vdbe();
-
+
if (!dateExists)
res = Sqlite3.sqlite3_prepare_v2(OldDB, "SELECT rowid, Player FROM US_Scores", -1, ref Stmt, 0);
else
@@ -625,11 +813,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);
@@ -645,7 +833,7 @@ namespace Vocaluxe.Base
if (dateExists)
data.ticks = UnixTimeToTicks(Sqlite3.sqlite3_column_int(Stmt, 2));
-
+
scores.Add(data);
}
Sqlite3.sqlite3_finalize(Stmt);
@@ -678,14 +866,14 @@ namespace Vocaluxe.Base
command.Parameters.Add("@id", System.Data.DbType.Int32, 0).Value = data.id;
command.ExecuteNonQuery();
}
-
+
//Delete old tables after conversion
command.CommandText = "DROP TABLE US_Scores;";
command.ExecuteNonQuery();
command.CommandText = "DROP TABLE US_Songs;";
command.ExecuteNonQuery();
-
+
reader.Dispose();
command.Dispose();
connection.Close();
@@ -693,6 +881,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
@@ -784,7 +1037,7 @@ namespace Vocaluxe.Base
return false;
}
-
+
int w = MaxSize;
int h = MaxSize;
@@ -801,7 +1054,7 @@ namespace Vocaluxe.Base
byte[] data = new byte[w * h * 4];
BitmapData bmp_data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
- Marshal.Copy(bmp_data.Scan0, data, 0, w*h*4);
+ Marshal.Copy(bmp_data.Scan0, data, 0, w * h * 4);
bmp.UnlockBits(bmp_data);
bmp.Dispose();
@@ -947,6 +1200,273 @@ namespace Vocaluxe.Base
}
#endregion Cover
+ #region CreditsRessources
+ public static bool GetCreditsRessource(string FileName, ref STexture tex)
+ {
+ bool result = false;
+
+ SQLiteConnection connection = new SQLiteConnection();
+ connection.ConnectionString = "Data Source=" + _CreditsRessourcesFilePath;
+ SQLiteCommand command;
+ try
+ {
+ connection.Open();
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ command = new SQLiteCommand(connection);
+
+ command.CommandText = "SELECT id, width, height FROM Images WHERE [Path] = @path";
+ command.Parameters.Add("@path", System.Data.DbType.String, 0).Value = FileName;
+
+ SQLiteDataReader reader = null;
+ try
+ {
+ reader = command.ExecuteReader();
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+
+ if (reader != null && reader.HasRows)
+ {
+ reader.Read();
+ int id = reader.GetInt32(0);
+ int w = reader.GetInt32(1);
+ int h = reader.GetInt32(2);
+ reader.Close();
+
+ command.CommandText = "SELECT Data FROM ImageData WHERE ImageID = " + id.ToString();
+ try
+ {
+ reader = command.ExecuteReader();
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+
+ if (reader.HasRows)
+ {
+ result = true;
+ reader.Read();
+ byte[] data = GetBytes(reader);
+ tex = CDraw.AddTexture(w, h, ref data);
+ }
+ }
+
+ if (reader != null)
+ {
+ reader.Close();
+ reader.Dispose();
+ }
+ command.Dispose();
+ connection.Close();
+ connection.Dispose();
+
+ return result;
+ }
+
+ //If you want to add an image to db, call this method!
+ private static bool AddImageToCreditsDB(String ImagePath)
+ {
+ bool result = false;
+ STexture tex;
+
+ if (File.Exists(ImagePath))
+ {
+
+ SQLiteConnection connection = new SQLiteConnection();
+ connection.ConnectionString = "Data Source=" + _CreditsRessourcesFilePath;
+ SQLiteCommand command;
+ try
+ {
+ connection.Open();
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+ command = new SQLiteCommand(connection);
+
+ SQLiteDataReader reader = null;
+
+ if (reader != null)
+ reader.Close();
+
+ Bitmap origin;
+ try
+ {
+ origin = new Bitmap(ImagePath);
+ }
+ catch (Exception)
+ {
+ CLog.LogError("Error loading Texture: " + ImagePath);
+ tex = new STexture(-1);
+
+ if (reader != null)
+ {
+ reader.Close();
+ reader.Dispose();
+ }
+ command.Dispose();
+ connection.Close();
+ connection.Dispose();
+
+ return false;
+ }
+
+ int w = origin.Width;
+ int h = origin.Height;
+
+ Bitmap bmp = new Bitmap(w, h);
+ Graphics g = Graphics.FromImage(bmp);
+ g.DrawImage(origin, new Rectangle(0, 0, w, h));
+ g.Dispose();
+ tex = CDraw.AddTexture(bmp);
+ byte[] data = new byte[w * h * 4];
+
+ BitmapData bmp_data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+ Marshal.Copy(bmp_data.Scan0, data, 0, w * h * 4);
+ bmp.UnlockBits(bmp_data);
+ bmp.Dispose();
+
+ command.CommandText = "INSERT INTO Images (Path, width, height) " +
+ "VALUES (@path, " + w.ToString() + ", " + h.ToString() + ")";
+ command.Parameters.Add("@path", System.Data.DbType.String, 0).Value = Path.GetFileName(ImagePath);
+ command.ExecuteNonQuery();
+
+ command.CommandText = "SELECT id FROM Images WHERE [Path] = @path";
+ command.Parameters.Add("@path", System.Data.DbType.String, 0).Value = Path.GetFileName(ImagePath);
+ reader = null;
+ try
+ {
+ reader = command.ExecuteReader();
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+
+ if (reader != null)
+ {
+ reader.Read();
+ int id = reader.GetInt32(0);
+ reader.Close();
+ command.CommandText = "INSERT INTO ImageData (ImageID, Data) " +
+ "VALUES ('" + id.ToString() + "', @data)";
+ command.Parameters.Add("@data", System.Data.DbType.Binary, 20).Value = data;
+ command.ExecuteReader();
+ result = true;
+ }
+ }
+
+ return result;
+ }
+
+ private static bool InitCreditsRessourcesDB()
+ {
+ SQLiteConnection connection = new SQLiteConnection();
+ connection.ConnectionString = "Data Source=" + _CreditsRessourcesFilePath;
+ SQLiteCommand command;
+
+ try
+ {
+ connection.Open();
+ }
+ catch (Exception)
+ {
+ return false;
+ }
+
+ command = new SQLiteCommand(connection);
+ command.CommandText = "SELECT Value FROM Version";
+
+ SQLiteDataReader reader = null;
+
+ try
+ {
+ reader = command.ExecuteReader();
+ }
+ catch (Exception)
+ {
+ ;
+ }
+
+ if (reader == null)
+ {
+ // Log error
+ CLog.LogError("Can't find Credits-DB!");
+ }
+ else if (reader.FieldCount == 0)
+ {
+ // Log error
+ CLog.LogError("Can't find Credits-DB! Field-Count = 0");
+ }
+ else
+ {
+ reader.Read();
+
+ if (reader.GetInt32(0) < CSettings.iDatabaseHighscoreVersion)
+ {
+ // update database
+ }
+ }
+
+ if (reader != null)
+ {
+ reader.Close();
+ reader.Dispose();
+ }
+
+ command.Dispose();
+
+ connection.Close();
+ connection.Dispose();
+
+ return true;
+ }
+
+ private static void CreateCreditsRessourcesDB()
+ {
+ SQLiteConnection connection = new SQLiteConnection();
+ connection.ConnectionString = "Data Source=" + _CreditsRessourcesFilePath;
+ 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.iDatabaseCreditsRessourcesVersion.ToString() + ")";
+ command.ExecuteNonQuery();
+
+ command.CommandText = "CREATE TABLE IF NOT EXISTS Images ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
+ "Path TEXT NOT NULL, width INTEGER NOT NULL, height INTEGER NOT NULL);";
+ command.ExecuteNonQuery();
+
+ command.CommandText = "CREATE TABLE IF NOT EXISTS ImageData ( id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
+ "ImageID INTEGER NOT NULL, Data BLOB NOT NULL);";
+ command.ExecuteNonQuery();
+
+ command.Dispose();
+ connection.Close();
+ connection.Dispose();
+ }
+ #endregion CreditsRessources
+
private static byte[] GetBytes(SQLiteDataReader reader)
{
const int CHUNK_SIZE = 2 * 1024;
@@ -973,4 +1493,4 @@ namespace Vocaluxe.Base
return t70.Ticks;
}
}
-}
+}
\ No newline at end of file
diff --git a/Vocaluxe/Base/CDraw.cs b/Vocaluxe/Base/CDraw.cs
index 5c1129dd..6b00f4b9 100644
--- a/Vocaluxe/Base/CDraw.cs
+++ b/Vocaluxe/Base/CDraw.cs
@@ -332,6 +332,7 @@ namespace Vocaluxe.Base
{
#region private vars
private string _TextureName;
+ private STexture _Texture;
private SRectF _Rect;
private float _Size;
private SColorF _Color;
@@ -346,7 +347,7 @@ namespace Vocaluxe.Base
private float _Vsize; //size changing speed: period [s]
private float _LastTime;
private EParticeType _Type;
-
+
private Stopwatch _Timer;
#endregion private vars
@@ -399,6 +400,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;
@@ -416,6 +418,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()
@@ -566,7 +591,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));
}
}
@@ -574,6 +602,7 @@ namespace Vocaluxe.Base
{
private List _Stars;
private string _TextureName;
+ private STexture _Texture;
private int _MaxNumber;
private SRectF _Area;
private SColorF _Color;
@@ -592,12 +621,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;
@@ -695,10 +745,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);
}
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;
diff --git a/Vocaluxe/Base/CSettings.cs b/Vocaluxe/Base/CSettings.cs
index 24ffda63..2f751e83 100644
--- a/Vocaluxe/Base/CSettings.cs
+++ b/Vocaluxe/Base/CSettings.cs
@@ -47,10 +47,11 @@ namespace Vocaluxe.Base
public const int iVersionSub = 0; // steps
public const ERevision VersionRevision = ERevision.Beta;
- public const int iBuild = 53; // Increase on every published version! Never Reset!
+ public const int iBuild = 54; // Increase on every published version! Never Reset!
public const int iDatabaseHighscoreVersion = 1;
public const int iDatabaseCoverVersion = 1;
+ public const int iDatabaseCreditsRessourcesVersion = 1;
public static int iRenderW = 1280;
@@ -69,8 +70,10 @@ 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 sFileCreditsRessourcesDB = "CreditsRessourcesDB.sqlite";
public const string sFilePerformanceLog = "Performance.log";
public const string sFileErrorLog = "Error.log";
public const string sFileBenchmarkLog = "Benchmark.log";
diff --git a/Vocaluxe/Base/CSound.cs b/Vocaluxe/Base/CSound.cs
index b201e6fb..2a2f9d0f 100644
--- a/Vocaluxe/Base/CSound.cs
+++ b/Vocaluxe/Base/CSound.cs
@@ -501,7 +501,7 @@ namespace Vocaluxe.Base
long ticks = _Timer.ElapsedTicks;
float dt = _Timer.ElapsedMilliseconds / 1000f;
- if (nanosecPerTick > 0L)
+ if (Stopwatch.IsHighResolution)
dt = (float)(ticks * nanosecPerTick / 1000000000.0);
return _SetValue + dt;
@@ -581,7 +581,7 @@ namespace Vocaluxe.Base
long ticks = _STimer.ElapsedTicks;
float dt = _STimer.ElapsedMilliseconds / 1000f;
- if (nanosecPerTick > 0L)
+ if (Stopwatch.IsHighResolution)
dt = (float)(ticks * nanosecPerTick / 1000000000.0);
return _CurrentTime + dt;
@@ -617,9 +617,9 @@ namespace Vocaluxe.Base
long ticks = _STimer.ElapsedTicks;
float dt = _STimer.ElapsedMilliseconds / 1000f;
- if (nanosecPerTick > 0L)
+ if (Stopwatch.IsHighResolution)
dt = (float)(ticks * nanosecPerTick / 1000000000.0);
-
+
float Ts = 0f;
if (dt > 0)
Ts = 1 / (_T / dt + 1);
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
diff --git a/Vocaluxe/Lib/Song/CSong.cs b/Vocaluxe/Lib/Song/CSong.cs
index bfb8e7b2..37147e7c 100644
--- a/Vocaluxe/Lib/Song/CSong.cs
+++ b/Vocaluxe/Lib/Song/CSong.cs
@@ -242,6 +242,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))
@@ -288,6 +293,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);
diff --git a/Vocaluxe/Lib/Sound/CPortAudioPlay.cs b/Vocaluxe/Lib/Sound/CPortAudioPlay.cs
index d39c6942..dc23bc91 100644
--- a/Vocaluxe/Lib/Sound/CPortAudioPlay.cs
+++ b/Vocaluxe/Lib/Sound/CPortAudioPlay.cs
@@ -620,7 +620,7 @@ namespace Vocaluxe.Lib.Sound
IntPtr.Zero,
ref outputParams,
format.SamplesPerSecond,
- 0,//CConfig.PortAudioBufferSize,
+ (uint)CConfig.AudioBufferSize,
PortAudio.PaStreamFlags.paNoFlag,
_paStreamCallback,
data));
@@ -677,6 +677,21 @@ namespace Vocaluxe.Lib.Sound
{
if (EventDecode.WaitOne(10))
{
+ lock (MutexSyncSignals)
+ {
+ if (_SetSkip)
+ {
+ _skip = true;
+ EventDecode.Set();
+ _waiting = true;
+ }
+
+ _SetSkip = false;
+
+ _Start = _SetStart;
+ _Loop = _SetLoop;
+ }
+
if (_skip)
{
DoSkip();
@@ -689,25 +704,6 @@ namespace Vocaluxe.Lib.Sound
Update();
}
}
-
- if (!_terminated)
- {
- lock (MutexSyncSignals)
- {
- if (_SetSkip)
- {
- _skip = true;
- EventDecode.Set();
- _waiting = true;
- }
-
- _SetSkip = false;
-
- _Start = _SetStart;
- _Loop = _SetLoop;
- }
- }
-
}
DoFree();
@@ -844,10 +840,10 @@ namespace Vocaluxe.Lib.Sound
else
_waiting = true;
- float latency = buf.Length / _BytesPerSecond;
+ float latency = buf.Length / _BytesPerSecond + CConfig.AudioLatency/1000f;
float time = _TimeCode - _data.BytesNotRead / _BytesPerSecond - latency;
- _CurrentTime = _SyncTimer.Update(time);
+ _CurrentTime = time; // _SyncTimer.Update(time);
}
try
@@ -856,7 +852,7 @@ namespace Vocaluxe.Lib.Sound
}
catch (Exception e)
{
- Console.WriteLine(e.ToString());
+ CLog.LogError("Error PortAudio.StreamCallback: " + e.Message);
}
return PortAudio.PaStreamCallbackResult.paContinue;
diff --git a/Vocaluxe/Lib/Sound/CPortAudioRecord.cs b/Vocaluxe/Lib/Sound/CPortAudioRecord.cs
index 04096ab9..87bff1ab 100644
--- a/Vocaluxe/Lib/Sound/CPortAudioRecord.cs
+++ b/Vocaluxe/Lib/Sound/CPortAudioRecord.cs
@@ -245,6 +245,9 @@ namespace Vocaluxe.Lib.Sound
if (!_initialized)
return null;
+ if (_Devices.Count == 0)
+ return null;
+
return _Devices.ToArray();
}
diff --git a/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs b/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs
index e6031786..b8c38f49 100644
--- a/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs
+++ b/Vocaluxe/Lib/Video/CVideoDecoderFFmpeg.cs
@@ -214,33 +214,34 @@ namespace Vocaluxe.Lib.Video
class Decoder
{
- private IntPtr _instance = IntPtr.Zero;
- private IntPtr _videodecoder = IntPtr.Zero;
- private IntPtr _package = IntPtr.Zero;
- private Stopwatch _Timer = new Stopwatch();
- private CLOSEPROC _Closeproc;
- private int _StreamID;
- private string _FileName;
+ private IntPtr _instance = IntPtr.Zero; // acinerella instance
+ private IntPtr _videodecoder = IntPtr.Zero; // acinerella video decoder instance
+
+ private Stopwatch _LoopTimer = new Stopwatch();
+ private CLOSEPROC _Closeproc; // delegate for stream closing
+ private int _StreamID; // stream ID for stream closing
+ private string _FileName; // current video file name
- private FileStream _fs;
- private TAc_read_callback _rc;
- private TAc_seek_callback _sc;
+ private FileStream _fs; // video file stream
+ private TAc_read_callback _rc; // read callback for acinerella
+ private TAc_seek_callback _sc; // seek callback for acinerella
private bool _FileOpened = false;
- private float _VideoTimeBase = 0f;
- private float _VideoTime = 0f;
- private float _ActualVideoTime = 0f;
- private bool _waiting = false;
- private bool _skip = false;
+ private float _VideoTimeBase = 0f; // frame time
+ private float _VideoDecoderTime = 0f; // time of last decoded frame
+ private float _CurrentVideoTime = 0f; // current video position
+ private bool _BufferFull = false; // buffer is full, waiting for free frame slot
+
+ private bool _skip = false; // do skip
private float _Time = 0f;
private float _Gap = 0f;
private float _Start = 0f;
private bool _Loop = false;
private float _Duration = 0f;
- private float _VideoSkipTime = 0f;
- private float _NegativeSkipTime = 0f;
- private float _SkipTime = 0f;
+ private float _VideoSkipTime = 0f; // = VideoGap
+ private float _SkipTime = 0f; // = Start + VideoGap
+
private bool _Paused = false;
private bool _NoMoreFrames = false;
private bool _Finished = false;
@@ -260,7 +261,6 @@ namespace Vocaluxe.Lib.Video
AutoResetEvent EventDecode = new AutoResetEvent(false);
SFrameBuffer[] _FrameBuffer = new SFrameBuffer[5];
Object MutexFramebuffer = new Object();
- Object MutexFrame = new Object();
Object MutexSyncSignals = new Object();
public Decoder()
@@ -293,15 +293,16 @@ namespace Vocaluxe.Lib.Video
get { return _Paused; }
set
{
- _Paused = value;
lock (MutexSyncSignals)
{
+ _Paused = value;
if (_Paused)
- _Timer.Stop();
+ {
+ _LoopTimer.Stop();
+ }
else
{
- _Timer.Start();
- EventDecode.Set();
+ _LoopTimer.Start();
}
}
}
@@ -330,7 +331,7 @@ namespace Vocaluxe.Lib.Video
return false;
_FileName = FileName;
- _thread.Priority = ThreadPriority.Highest;
+ _thread.Priority = ThreadPriority.Normal;
_thread.Name = Path.GetFileName(FileName);
_thread.Start();
return true;
@@ -348,12 +349,12 @@ namespace Vocaluxe.Lib.Video
{
lock (MutexSyncSignals)
{
- _SetTime += _Timer.ElapsedMilliseconds / 1000f;
+ _SetTime += _LoopTimer.ElapsedMilliseconds / 1000f;
VideoTime = _SetTime;
- _Timer.Stop();
- _Timer.Reset();
- _Timer.Start();
+ _LoopTimer.Stop();
+ _LoopTimer.Reset();
+ _LoopTimer.Start();
}
@@ -362,12 +363,12 @@ namespace Vocaluxe.Lib.Video
return true;
}
- if (_Time - _SetTime >= 0 || _SetTime > Time)
+ if (_SetTime != Time)
{
lock (MutexSyncSignals)
{
_SetTime = Time;
- VideoTime = _VideoTime;
+ VideoTime = _CurrentVideoTime;
}
UploadNewFrame(ref frame);
EventDecode.Set();
@@ -394,17 +395,15 @@ namespace Vocaluxe.Lib.Video
#region Threading
private void DoSkip()
{
- lock (MutexSyncSignals)
- {
- _VideoSkipTime = _Gap;
- _NegativeSkipTime = _Start + _Gap;
- _SkipTime = _Start + _Gap;
- _BeforeLoop = false;
- }
+ string extension = Path.GetExtension(_FileName); //just a workaround for the mkv-search-bug in ffmpeg
- if (_SkipTime > 0)
+ _VideoSkipTime = _Gap;
+ _SkipTime = _Start + _Gap;
+ _BeforeLoop = false;
+
+ if (_SkipTime > 0 && extension != ".mkv")
{
- _VideoTime = _SkipTime;
+ _VideoDecoderTime = _SkipTime;
try
{
CAcinerella.ac_seek(_videodecoder, -1, (Int64)(_SkipTime * 1000f));
@@ -417,10 +416,11 @@ namespace Vocaluxe.Lib.Video
}
else
{
- _VideoTime = 0f;
+ _VideoDecoderTime = 0f;
try
{
- CAcinerella.ac_seek(_videodecoder, -1, (Int64)0);
+ if (extension != ".mkv")
+ CAcinerella.ac_seek(_videodecoder, -1, (Int64)0);
}
catch (Exception e)
{
@@ -428,7 +428,10 @@ namespace Vocaluxe.Lib.Video
}
}
- _ActualVideoTime = _VideoTime;
+ lock (MutexSyncSignals)
+ {
+ _CurrentVideoTime = _VideoDecoderTime;
+ }
lock (MutexFramebuffer)
{
@@ -439,46 +442,41 @@ namespace Vocaluxe.Lib.Video
}
}
- _waiting = false;
+ _BufferFull = false;
+ _skip = false;
+ EventDecode.Set();
}
private void Execute()
{
DoOpen();
-
+ EventDecode.Set();
+
while (!_terminated)
{
- if (EventDecode.WaitOne(1) || !_waiting)
- {
- if (_skip)
- {
- DoSkip();
- _skip = false;
- }
-
- if (!_waiting)
- {
- DoDecode();
- }
-
- if (_waiting)
- Copy();
- }
- if (!_terminated)
+ if (EventDecode.WaitOne(10))
{
lock (MutexSyncSignals)
{
_Time = _SetTime;
if (_SetSkip)
_skip = true;
-
+
_SetSkip = false;
_Gap = _SetGap;
_Start = _SetStart;
_Loop = _SetLoop;
}
+
+ if (_skip)
+ DoSkip();
+
+ if (!_BufferFull)
+ DoDecode();
+
+ if (_BufferFull)
+ Copy();
}
-
}
DoFree();
@@ -544,7 +542,7 @@ namespace Vocaluxe.Lib.Video
if (Videodecoder.stream_info.video_info.frames_per_second > 0)
_VideoTimeBase = 1f / (float)Videodecoder.stream_info.video_info.frames_per_second;
- _VideoTime = 0f;
+ _VideoDecoderTime = 0f;
_Time = 0f;
for (int i = 0; i < _FrameBuffer.Length; i++)
@@ -563,14 +561,14 @@ namespace Vocaluxe.Lib.Video
if (!_FileOpened)
return;
- if (_Paused || _NoMoreFrames)
+ if (_Paused || _NoMoreFrames || _BufferFull)
return;
- if ((_NegativeSkipTime < 0f) && (_Time + _NegativeSkipTime >= 0f))
- _NegativeSkipTime = 0f;
+ if ((_SkipTime < 0f) && (_Time + _SkipTime >= 0f))
+ _SkipTime = 0f;
float myTime = _Time + _VideoSkipTime;
- float TimeDifference = myTime - _VideoTime;
+ float TimeDifference = myTime - _VideoDecoderTime;
bool DropFrame = false;
if (TimeDifference >= (FRAMEDROPCOUNT - 1) * _VideoTimeBase)
@@ -595,17 +593,13 @@ namespace Vocaluxe.Lib.Video
if (!_BeforeLoop && (!DropFrame || FrameFinished != 0))
{
- lock (MutexFrame)
+ try
{
- try
- {
- FrameFinished = CAcinerella.ac_get_frame(_instance, _videodecoder);
- }
- catch (Exception)
- {
- CLog.LogError("Error AcGetFrame " + _FileName);
- }
-
+ FrameFinished = CAcinerella.ac_get_frame(_instance, _videodecoder);
+ }
+ catch (Exception)
+ {
+ CLog.LogError("Error AcGetFrame " + _FileName);
}
}
@@ -637,7 +631,6 @@ namespace Vocaluxe.Lib.Video
lock (MutexSyncSignals)
{
- _ActualVideoTime = 0f;
_Start = 0f;
_Gap = 0f;
_SetTime = 0f;
@@ -658,6 +651,7 @@ namespace Vocaluxe.Lib.Video
private void Copy()
{
int num = -1;
+
lock (MutexFramebuffer)
{
for (int i = 0; i < _FrameBuffer.Length; i++)
@@ -670,29 +664,38 @@ namespace Vocaluxe.Lib.Video
}
if (num == -1)
- _waiting = true;
+ {
+ _BufferFull = true;
+ EventDecode.Reset();
+ }
else
{
+ TAc_decoder Videodecoder = (TAc_decoder)Marshal.PtrToStructure(_videodecoder, typeof(TAc_decoder));
- lock (MutexFrame)
+ _VideoDecoderTime = (float)Videodecoder.timecode;
+ _FrameBuffer[num].time = _VideoDecoderTime;
+
+ if (Videodecoder.buffer != IntPtr.Zero)
{
- TAc_decoder Videodecoder = (TAc_decoder)Marshal.PtrToStructure(_videodecoder, typeof(TAc_decoder));
+ Marshal.Copy(Videodecoder.buffer, _FrameBuffer[num].data, 0, _Width * _Height * 4);
- _FrameBuffer[num].time = _VideoTime;
- _VideoTime = (float)Videodecoder.timecode;
-
- if (Videodecoder.buffer != IntPtr.Zero)
- {
- Marshal.Copy(Videodecoder.buffer, _FrameBuffer[num].data, 0, _Width * _Height * 4);
-
- _FrameBuffer[num].displayed = false;
- }
+ _FrameBuffer[num].displayed = false;
}
-
- _waiting = false;
+ int numfull = 0;
+ for (int i = 0; i < _FrameBuffer.Length; i++)
+ {
+ if (!_FrameBuffer[i].displayed)
+ numfull++;
+ }
+
+ if (numfull < _FrameBuffer.Length)
+ _BufferFull = false;
}
}
+
+ if (!_BufferFull)
+ EventDecode.Set();
}
private void UploadNewFrame(ref STexture frame)
@@ -715,8 +718,13 @@ namespace Vocaluxe.Lib.Video
{
CDraw.UpdateTexture(ref frame, ref _FrameBuffer[num].data);
}
- _ActualVideoTime = _FrameBuffer[num].time;
+
+ lock (MutexSyncSignals)
+ {
+ _CurrentVideoTime = _FrameBuffer[num].time;
+ }
_Finished = false;
+ EventDecode.Set();
}
else
{
@@ -724,7 +732,6 @@ namespace Vocaluxe.Lib.Video
_Finished = true;
}
}
- EventDecode.Set();
}
private int FindFrame()
@@ -736,27 +743,28 @@ namespace Vocaluxe.Lib.Video
{
float td = _SetTime + _VideoSkipTime - _FrameBuffer[i].time;
+ if (td > _VideoTimeBase * 2 || td < -1f * _VideoTimeBase * (_FrameBuffer.Length + 1))
+ {
+ _FrameBuffer[i].displayed = true;
+ }
+
if (!_FrameBuffer[i].displayed && (td < diff) && (td > _VideoTimeBase))
{
diff = Math.Abs(_FrameBuffer[i].time - _SetTime - _VideoSkipTime);
Result = i;
}
-
- if (td > _VideoTimeBase * 2)
- _FrameBuffer[i].displayed = true;
}
if (Result != -1)
+ {
_FrameBuffer[Result].displayed = true;
+ }
return Result;
}
private void DoFree()
{
- if (_package != IntPtr.Zero)
- CAcinerella.ac_free_package(_package);
-
if (_videodecoder != IntPtr.Zero)
CAcinerella.ac_free_decoder(_videodecoder);
diff --git a/Vocaluxe/Menu/CGraphics.cs b/Vocaluxe/Menu/CGraphics.cs
index 91908275..d64691f1 100644
--- a/Vocaluxe/Menu/CGraphics.cs
+++ b/Vocaluxe/Menu/CGraphics.cs
@@ -31,6 +31,8 @@ namespace Vocaluxe.Menu
ScreenNames = 14,
+ ScreenCredits = 15,
+
ScreenNull = -1
}
@@ -212,6 +214,7 @@ namespace Vocaluxe.Menu
{
// Add Screens, must be the same order as in EScreens!
CLog.StartBenchmark(1, "Build Screen List");
+
_Screens.Add(new CScreenTest());
_Screens.Add(new CScreenLoad());
_Screens.Add(new CScreenMain());
@@ -227,8 +230,10 @@ namespace Vocaluxe.Menu
_Screens.Add(new CScreenOptionsVideo());
_Screens.Add(new CScreenOptionsTheme());
_Screens.Add(new CScreenNames());
+ _Screens.Add(new CScreenCredits());
_PopupScreens.Add(new CPopupScreenPlayerControl());
+
CLog.StopBenchmark(1, "Build Screen List");
_CurrentScreen = EScreens.ScreenLoad;
@@ -255,9 +260,12 @@ namespace Vocaluxe.Menu
for (int i = 0; i < _Screens.Count; i++)
{
- CLog.StartBenchmark(1, "Load Theme " + Enum.GetNames(typeof(EScreens))[i]);
- _Screens[i].LoadTheme();
- CLog.StopBenchmark(1, "Load Theme " + Enum.GetNames(typeof(EScreens))[i]);
+ if (Enum.GetNames(typeof(EScreens))[i] != Enum.GetName(typeof(EScreens), (int)EScreens.ScreenCredits))
+ {
+ CLog.StartBenchmark(1, "Load Theme " + Enum.GetNames(typeof(EScreens))[i]);
+ _Screens[i].LoadTheme();
+ CLog.StopBenchmark(1, "Load Theme " + Enum.GetNames(typeof(EScreens))[i]);
+ }
}
for (int i = 0; i < _PopupScreens.Count; i++)
@@ -271,7 +279,10 @@ namespace Vocaluxe.Menu
ReloadCursor();
for (int i = 0; i < _Screens.Count; i++)
{
- _Screens[i].ReloadTheme();
+ if (Enum.GetNames(typeof(EScreens))[i] != Enum.GetName(typeof(EScreens), (int)EScreens.ScreenCredits))
+ {
+ _Screens[i].ReloadTheme();
+ }
}
for (int i = 0; i < _PopupScreens.Count; i++)
@@ -285,7 +296,10 @@ namespace Vocaluxe.Menu
ReloadCursor();
for (int i = 0; i < _Screens.Count; i++)
{
- _Screens[i].ReloadTextures();
+ if (Enum.GetNames(typeof(EScreens))[i] != Enum.GetName(typeof(EScreens), (int)EScreens.ScreenCredits))
+ {
+ _Screens[i].ReloadTextures();
+ }
}
for (int i = 0; i < _PopupScreens.Count; i++)
@@ -299,7 +313,10 @@ namespace Vocaluxe.Menu
CTheme.SaveTheme();
for (int i = 0; i < _Screens.Count; i++)
{
- _Screens[i].SaveTheme();
+ if (Enum.GetNames(typeof(EScreens))[i] != Enum.GetName(typeof(EScreens), (int)EScreens.ScreenCredits))
+ {
+ _Screens[i].SaveTheme();
+ }
}
for (int i = 0; i < _PopupScreens.Count; i++)
diff --git a/Vocaluxe/Menu/CLyric.cs b/Vocaluxe/Menu/CLyric.cs
index 24651cc3..8a70e0ab 100644
--- a/Vocaluxe/Menu/CLyric.cs
+++ b/Vocaluxe/Menu/CLyric.cs
@@ -15,7 +15,8 @@ namespace Vocaluxe.Menu
{
Fill,
Jump,
- Slide
+ Slide,
+ Zoom
}
struct SNote
@@ -23,6 +24,7 @@ namespace Vocaluxe.Menu
public string Text;
public int StartBeat;
public int EndBeat;
+ public int Duration;
public ENoteType Type;
}
@@ -205,6 +207,7 @@ namespace Vocaluxe.Menu
n.Text = note.Text;
n.StartBeat = note.StartBeat;
n.EndBeat = note.EndBeat;
+ n.Duration = note.Duration;
n.Type = note.NoteType;
_Text.Text = note.Text;
@@ -229,6 +232,7 @@ namespace Vocaluxe.Menu
return _X - _width / 2;
}
+ #region draw
public void Draw(float ActualBeat)
{
if (Visible || CSettings.GameState == EGameState.EditTheme)
@@ -236,12 +240,17 @@ namespace Vocaluxe.Menu
switch (_Style)
{
case ELyricStyle.Fill:
+ DrawFill(ActualBeat);
break;
case ELyricStyle.Jump:
+ DrawJump(ActualBeat);
break;
case ELyricStyle.Slide:
DrawSlide(ActualBeat);
break;
+ case ELyricStyle.Zoom:
+ DrawZoom(ActualBeat);
+ break;
default:
DrawSlide(ActualBeat);
break;
@@ -257,6 +266,8 @@ namespace Vocaluxe.Menu
{
_Text.X = x;
_Text.Style = EStyle.Bold;
+ _Text.Text = note.Text;
+ RectangleF rect = CDraw.GetTextBounds(_Text);
if (note.Type == ENoteType.Freestyle)
_Text.Style = EStyle.BoldItalic;
@@ -266,7 +277,7 @@ namespace Vocaluxe.Menu
if (CurrentBeat <= note.EndBeat)
{
_Text.Color = ColorProcessed;
- _Text.Text = note.Text;
+
float diff = note.EndBeat - note.StartBeat;
if (diff == 0)
@@ -280,23 +291,202 @@ namespace Vocaluxe.Menu
}
else
{
- _Text.Color = ColorProcessed;
- _Text.Text = note.Text;
+ _Text.Color = ColorProcessed;
_Text.Draw();
}
}
else
{
- _Text.Color = Color;
- _Text.Text = note.Text;
+ _Text.Color = Color;
_Text.Draw();
}
- RectangleF rect = CDraw.GetTextBounds(_Text);
+
x += rect.Width;
}
}
+ private void DrawZoom(float CurrentBeat)
+ {
+ float x = _X - _width / 2; // most left position
+
+ //find last active note
+ int last_note = -1;
+ for (int i = 0; i < _Notes.Count; i++)
+ {
+ if (CurrentBeat >= _Notes[i].StartBeat)
+ last_note = i;
+ }
+
+ int zoom_note = -1;
+ float zoomx = 0f;
+
+ int current_note = -1;
+ foreach (SNote note in _Notes)
+ {
+ current_note++;
+
+ _Text.X = x;
+ _Text.Style = EStyle.Bold;
+ _Text.Text = note.Text;
+ RectangleF rect = CDraw.GetTextBounds(_Text);
+
+ if (note.Type == ENoteType.Freestyle)
+ _Text.Style = EStyle.BoldItalic;
+
+ if (CurrentBeat >= note.StartBeat)
+ {
+ if (CurrentBeat <= note.EndBeat)
+ {
+ zoom_note = current_note;
+ zoomx = _Text.X;
+ }
+ else
+ {
+ // already passed
+ if (current_note == last_note)
+ _Text.Color = ColorProcessed;
+ else
+ _Text.Color = Color;
+
+ _Text.Draw();
+ }
+
+ }
+ else
+ {
+ // not passed
+ _Text.Color = Color;
+ _Text.Draw();
+ }
+
+ x += rect.Width;
+ }
+
+ if (zoom_note > -1)
+ {
+ if (_Notes[zoom_note].Duration == 0)
+ return;
+
+ _Text.X = zoomx;
+ _Text.Text = _Notes[zoom_note].Text;
+ _Text.Color = ColorProcessed;
+ _Text.Style = EStyle.Bold;
+
+ if (_Notes[zoom_note].Type == ENoteType.Freestyle)
+ _Text.Style = EStyle.BoldItalic;
+
+ RectangleF rect = CDraw.GetTextBounds(_Text);
+
+ float diff = _Notes[zoom_note].EndBeat - _Notes[zoom_note].StartBeat;
+
+ float p = (CurrentBeat - _Notes[zoom_note].StartBeat) / _Notes[zoom_note].Duration;
+ if (p > 1f)
+ p = 1f;
+
+ p = 1f - p;
+
+ float ty = _Text.Y;
+ float tx = _Text.X;
+ float th = _Text.Height;
+ float tz = _Text.Z;
+
+ _Text.Height += _Text.Height * p * 0.4f;
+ RectangleF rectz = CDraw.GetTextBounds(_Text);
+ _Text.X -= (rectz.Width - rect.Width) / 2f;
+ _Text.Y -= (rectz.Height - rect.Height) / 2f;
+ _Text.Z -= 0.1f;
+
+ _Text.Draw();
+
+ _Text.Y = ty;
+ _Text.X = tx;
+ _Text.Height = th;
+ _Text.Z = tz;
+ }
+ }
+
+ private void DrawFill(float CurrentBeat)
+ {
+ float x = _X - _width / 2; // most left position
+
+ foreach (SNote note in _Notes)
+ {
+ _Text.X = x;
+ _Text.Style = EStyle.Bold;
+ _Text.Text = note.Text;
+ RectangleF rect = CDraw.GetTextBounds(_Text);
+
+ if (note.Type == ENoteType.Freestyle)
+ _Text.Style = EStyle.BoldItalic;
+
+ if (CurrentBeat >= note.StartBeat)
+ {
+ _Text.Color = ColorProcessed;
+ _Text.Draw();
+ }
+ else
+ {
+ // not passed
+ _Text.Color = Color;
+ _Text.Draw();
+ }
+
+ x += rect.Width;
+ }
+ }
+
+ private void DrawJump(float CurrentBeat)
+ {
+ float x = _X - _width / 2; // most left position
+
+ foreach (SNote note in _Notes)
+ {
+ _Text.X = x;
+ _Text.Style = EStyle.Bold;
+ _Text.Text = note.Text;
+ RectangleF rect = CDraw.GetTextBounds(_Text);
+
+ if (note.Type == ENoteType.Freestyle)
+ _Text.Style = EStyle.BoldItalic;
+
+ if (CurrentBeat >= note.StartBeat)
+ {
+ if (CurrentBeat <= note.EndBeat)
+ {
+ _Text.Color = ColorProcessed;
+
+ float diff = note.EndBeat - note.StartBeat;
+ if (diff == 0)
+ _Text.Draw();
+ else
+ {
+ float y = _Text.Y;
+ _Text.Y -= _Text.Height * 0.1f;
+ _Text.Draw();
+ _Text.Y = y;
+ }
+ }
+ else
+ {
+ // already passed
+ _Text.Color = Color;
+ _Text.Draw();
+ }
+
+ }
+ else
+ {
+ // not passed
+ _Text.Color = Color;
+ _Text.Draw();
+ }
+
+ x += rect.Width;
+ }
+ }
+ #endregion draw
+
public void UnloadTextures()
{
}
diff --git a/Vocaluxe/Program.cs b/Vocaluxe/Program.cs
index 2239d6ff..32cde09c 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();
@@ -192,6 +192,8 @@ namespace Vocaluxe
class SplashScreen : Form
{
+ Bitmap logo;
+
public SplashScreen()
{
string path = Path.Combine(Environment.CurrentDirectory, Path.Combine(CSettings.sFolderGraphics, CSettings.sLogo));
@@ -199,9 +201,8 @@ namespace Vocaluxe
{
try
{
- Bitmap logo = new Bitmap(path);
+ logo = new Bitmap(path);
this.ClientSize = new Size(logo.Width, logo.Height);
- this.BackgroundImage = logo;
}
catch (Exception e)
{
@@ -226,11 +227,27 @@ 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)
+ {
+ if (logo == null)
+ return;
+
+ Graphics g = e.Graphics;
+ g.DrawImage(logo, new Rectangle(0, 0, this.Width, this.Height));
+ }
}
}
diff --git a/Vocaluxe/Screens/CScreenCredits.cs b/Vocaluxe/Screens/CScreenCredits.cs
new file mode 100644
index 00000000..278b4720
--- /dev/null
+++ b/Vocaluxe/Screens/CScreenCredits.cs
@@ -0,0 +1,367 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+using System.Windows.Forms;
+
+using Vocaluxe.Base;
+using Vocaluxe.Lib.Draw;
+using Vocaluxe.Menu;
+
+enum EDirection
+{
+ Left,
+ Right,
+ Up
+}
+
+class CCreditName
+{
+ public CStatic image;
+ public CParticleEffect particle;
+ public SRectF particleRect;
+ public EDirection direction;
+ public float StartTimeUp;
+ public bool active;
+}
+
+namespace Vocaluxe.Screens
+{
+ class CScreenCredits :CMenu
+ {
+ // Version number for theme files. Increment it, if you've changed something on the theme files!
+ const int ScreenVersion = 1;
+
+
+ private CStatic logo;
+ private CParticleEffect starsRed;
+ private CParticleEffect starsBlue;
+ private List _CreditNames;
+
+ private Stopwatch LogoTimer;
+ private Stopwatch CreditsTimer;
+
+ public CScreenCredits()
+ {
+ Init();
+ }
+
+ protected override void Init()
+ {
+ base.Init();
+
+ _ThemeName = "ScreenCredits";
+ _ScreenVersion = ScreenVersion;
+
+ LogoTimer = new Stopwatch();
+ CreditsTimer = new Stopwatch();
+ }
+
+ public override bool HandleInput(KeyEvent KeyEvent)
+ {
+ if (KeyEvent.KeyPressed && !Char.IsControl(KeyEvent.Unicode))
+ {
+
+ }
+ else
+ {
+ switch (KeyEvent.Key)
+ {
+ case Keys.Escape:
+ case Keys.Back:
+ CGraphics.FadeTo(EScreens.ScreenMain);
+ break;
+
+ case Keys.Enter:
+ CGraphics.FadeTo(EScreens.ScreenMain);
+ break;
+ }
+ }
+
+ return true;
+ }
+
+ public override bool HandleMouse(MouseEvent MouseEvent)
+ {
+ if (MouseEvent.LB && IsMouseOver(MouseEvent))
+ {
+
+ }
+
+ if (MouseEvent.LB)
+ {
+ CGraphics.FadeTo(EScreens.ScreenMain);
+ }
+
+ if (MouseEvent.RB)
+ {
+ CGraphics.FadeTo(EScreens.ScreenMain);
+ }
+ return true;
+ }
+
+ public override bool UpdateGame()
+ {
+ if (!animation())
+ {
+ CGraphics.FadeTo(EScreens.ScreenMain);
+ }
+ return true;
+ }
+
+ public override void OnShow()
+ {
+ STexture tex = new STexture();
+ STexture particleTex = new STexture();
+
+ //Vocaluxe-Logo
+ CDataBase.GetCreditsRessource("Logo_voc.png", ref tex);
+ logo = new CStatic(tex, new SColorF(1, 1, 1, 1), new SRectF((CSettings.iRenderW - tex.width)/2, -270 , tex.width, tex.height, -2));
+
+ //Little stars for logo
+ CDataBase.GetCreditsRessource("PerfectNoteStar.png", ref particleTex);
+ int numstars = (int)(logo.Rect.W * 0.25f /2f);
+ starsRed = new CParticleEffect(numstars, new SColorF(1, 0, 0, 1), new SRectF(logo.Rect.X, logo.Rect.Y, logo.Rect.W, logo.Rect.H, -1), particleTex, 35, EParticeType.Star);
+ starsBlue = new CParticleEffect(numstars, new SColorF(0.149f, 0.415f, 0.819f, 1), new SRectF(logo.Rect.X, logo.Rect.Y, logo.Rect.W, logo.Rect.H, -1), particleTex, 35, EParticeType.Star);
+
+ //Credit names
+ _CreditNames = new List();
+
+ CCreditName CreditEntry = new CCreditName();
+
+ //brunzel
+ CDataBase.GetCreditsRessource("brunzel.png", ref tex);
+ CCreditName CreditEntryBrunzel = new CCreditName();
+ CreditEntryBrunzel.image = new CStatic(tex, new SColorF(1,1,1,1), new SRectF(-450, 580, 400, 120, -4));
+ CreditEntryBrunzel.particleRect = new SRectF(CreditEntryBrunzel.image.Rect.X + 342, CreditEntryBrunzel.image.Rect.Y + 4, 30, 30, -5);
+ CreditEntryBrunzel.particle = new CParticleEffect(8, new SColorF(1, 0, 0, 1), CreditEntryBrunzel.particleRect, particleTex, 35, EParticeType.Star);
+ CreditEntryBrunzel.active = true;
+ CreditEntryBrunzel.direction = EDirection.Left;
+ _CreditNames.Add(CreditEntryBrunzel);
+
+ //Darkice
+ CDataBase.GetCreditsRessource("Darkice.png", ref tex);
+ CCreditName CreditEntryDarkice = new CCreditName();
+ CreditEntryDarkice.image = new CStatic(tex, new SColorF(1, 1, 1, 1), new SRectF(CSettings.iRenderW, 580, 400, 120, -4));
+ CreditEntryDarkice.particleRect = new SRectF(CreditEntryDarkice.image.Rect.X + 242, CreditEntryDarkice.image.Rect.Y + 23, 30, 30, -5);
+ CreditEntryDarkice.particle = new CParticleEffect(8, new SColorF(0.149f, 0.415f ,0.819f, 1), CreditEntryDarkice.particleRect, particleTex, 35, EParticeType.Star);
+ CreditEntryDarkice.active = true;
+ CreditEntryDarkice.direction = EDirection.Right;
+ _CreditNames.Add(CreditEntryDarkice);
+
+ //flokuep
+ CDataBase.GetCreditsRessource("flokuep.png", ref tex);
+ CCreditName CreditEntryFlokuep = new CCreditName();
+ CreditEntryFlokuep.image = new CStatic(tex, new SColorF(1, 1, 1, 1), new SRectF(-450, 580, 400, 120, -4));
+ CreditEntryFlokuep.particleRect = new SRectF(CreditEntryFlokuep.image.Rect.X + 141, CreditEntryFlokuep.image.Rect.Y-2, 30, 30, -5);
+ CreditEntryFlokuep.particle = new CParticleEffect(8, new SColorF(1, 0, 0, 1), CreditEntryFlokuep.particleRect, particleTex, 35, EParticeType.Star);
+ CreditEntryFlokuep.active = true;
+ CreditEntryFlokuep.direction = EDirection.Left;
+ _CreditNames.Add(CreditEntryFlokuep);
+
+ //bohning
+ CDataBase.GetCreditsRessource("bohning.png", ref tex);
+ CCreditName CreditEntryBohning = new CCreditName();
+ CreditEntryBohning.image = new CStatic(tex, new SColorF(1, 1, 1, 1), new SRectF(CSettings.iRenderW, 580, 350, 110, -4));
+ CreditEntryBohning.particleRect = new SRectF(CreditEntryBohning.image.Rect.X + 172, CreditEntryBohning.image.Rect.Y + 16, 10, 10, -5);
+ CreditEntryBohning.particle = new CParticleEffect(4, new SColorF(0.149f, 0.415f ,0.819f, 1), CreditEntryBohning.particleRect, particleTex, 25, EParticeType.Star);
+ CreditEntryBohning.active = true;
+ CreditEntryBohning.direction = EDirection.Right;
+ _CreditNames.Add(CreditEntryBohning);
+
+ //mesand
+ CDataBase.GetCreditsRessource("mesand.png", ref tex);
+ CCreditName CreditEntryMesand = new CCreditName();
+ CreditEntryMesand.image = new CStatic(tex, new SColorF(1, 1, 1, 1), new SRectF(-450, 580, 350, 110, -4));
+ CreditEntryMesand.particleRect = new SRectF(CreditEntryMesand.image.Rect.X + 240, CreditEntryMesand.image.Rect.Y - 2, 10, 10, -5);
+ CreditEntryMesand.particle = new CParticleEffect(4, new SColorF(1, 0, 0, 1), CreditEntryMesand.particleRect, particleTex, 25, EParticeType.Star);
+ CreditEntryMesand.active = true;
+ CreditEntryMesand.direction = EDirection.Left;
+ _CreditNames.Add(CreditEntryMesand);
+
+ //babene03
+ CDataBase.GetCreditsRessource("babene03.png", ref tex);
+ CCreditName CreditEntryBabene03 = new CCreditName();
+ CreditEntryBabene03.image = new CStatic(tex, new SColorF(1, 1, 1, 1), new SRectF(CSettings.iRenderW, 580, 350, 110, -4));
+ CreditEntryBabene03.particleRect = new SRectF(CreditEntryBabene03.image.Rect.X + 7, CreditEntryBabene03.image.Rect.Y + 4, 10, 10, -5);
+ CreditEntryBabene03.particle = new CParticleEffect(4, new SColorF(0.149f, 0.415f ,0.819f, 1), CreditEntryBabene03.particleRect, particleTex, 25, EParticeType.Star);
+ CreditEntryBabene03.active = true;
+ CreditEntryBabene03.direction = EDirection.Right;
+ _CreditNames.Add(CreditEntryBabene03);
+
+ //pantero
+ CDataBase.GetCreditsRessource("pantero.png", ref tex);
+ CCreditName CreditEntrypantero = new CCreditName();
+ CreditEntrypantero.image = new CStatic(tex, new SColorF(1, 1, 1, 1), new SRectF(-450, 580, 350, 110, -4));
+ CreditEntrypantero.particleRect = new SRectF(CreditEntrypantero.image.Rect.X + 140, CreditEntrypantero.image.Rect.Y + 15, 10, 10, -5);
+ CreditEntrypantero.particle = new CParticleEffect(4, new SColorF(1, 0, 0, 1), CreditEntrypantero.particleRect, particleTex, 25, EParticeType.Star);
+ CreditEntrypantero.active = true;
+ CreditEntrypantero.direction = EDirection.Left;
+ _CreditNames.Add(CreditEntrypantero);
+
+ //Pinky007
+ CDataBase.GetCreditsRessource("Pinky007.png", ref tex);
+ CCreditName CreditEntryPinky007 = new CCreditName();
+ CreditEntryPinky007.image = new CStatic(tex, new SColorF(1, 1, 1, 1), new SRectF(CSettings.iRenderW, 580, 350, 110, -4));
+ CreditEntryPinky007.particleRect = new SRectF(CreditEntryPinky007.image.Rect.X + 42, CreditEntryPinky007.image.Rect.Y + 15, 10, 10, -5);
+ CreditEntryPinky007.particle = new CParticleEffect(4, new SColorF(0.149f, 0.415f ,0.819f, 1), CreditEntryPinky007.particleRect, particleTex, 25, EParticeType.Star);
+ CreditEntryPinky007.active = true;
+ CreditEntryPinky007.direction = EDirection.Right;
+ _CreditNames.Add(CreditEntryPinky007);
+
+
+ //CreditEntry.image = new CStatic(tex, new SColorF(1, 1, 1, 1), new SRectF(0, 0, 350, 110, -4));
+
+ }
+
+ public override void OnShowFinish()
+ {
+ base.OnShowFinish();
+
+ LogoTimer.Start();
+ }
+
+ public override bool Draw()
+ {
+ base.Draw();
+
+ //Draw background
+ CDraw.DrawColor(new SColorF(0, 0.18f, 0.474f, 1), new SRectF(0, 0, CSettings.iRenderW, CSettings.iRenderH, 0));
+
+ //Draw stars
+ starsBlue.Update();
+ starsBlue.Draw();
+ starsRed.Update();
+ starsRed.Draw();
+
+ logo.Draw();
+
+ //Draw credit-entries
+ for (int i = 0; i < _CreditNames.Count; i++)
+ {
+ if (_CreditNames[i].active)
+ {
+ _CreditNames[i].image.Draw();
+ _CreditNames[i].particle.Update();
+ _CreditNames[i].particle.Draw();
+ }
+ }
+ return true;
+ }
+
+ private bool animation()
+ {
+ bool active = false;
+ if (LogoTimer.IsRunning)
+ {
+ active = true;
+
+ logo.Rect.Y = -270 + (270f / 3000f) * LogoTimer.ElapsedMilliseconds;
+ SRectF rect = new SRectF(logo.Rect.X, logo.Rect.Y, logo.Rect.W, logo.Rect.H, -1);
+ starsRed.Area = rect;
+ starsBlue.Area = rect;
+ if (LogoTimer.ElapsedMilliseconds >= 2000 && !CreditsTimer.IsRunning)
+ {
+ CreditsTimer.Start();
+ }
+ if (LogoTimer.ElapsedMilliseconds >= 3000)
+ {
+ LogoTimer.Stop();
+ LogoTimer.Reset();
+ }
+ }
+
+ if (CreditsTimer.IsRunning)
+ {
+ active = true;
+
+ for (int i = 0; i < _CreditNames.Count; i++)
+ {
+ if (_CreditNames[i].active)
+ {
+ switch (_CreditNames[i].direction)
+ {
+ case EDirection.Left:
+ if (i * 4000f <= CreditsTimer.ElapsedMilliseconds)
+ {
+ float xOld = _CreditNames[i].image.Rect.X;
+ _CreditNames[i].image.Rect.X = -450 + (((CSettings.iRenderW - _CreditNames[i].image.Rect.W) / 2)/3000f) * (CreditsTimer.ElapsedMilliseconds-(i*4000f));
+ _CreditNames[i].particleRect.X += (_CreditNames[i].image.Rect.X - xOld);
+ _CreditNames[i].particle.Area = _CreditNames[i].particleRect;
+
+ //Check if name is in middle of screen and should go up
+ if (_CreditNames[i].image.Rect.X >= (CSettings.iRenderW - _CreditNames[i].image.Rect.W) / 2)
+ {
+ _CreditNames[i].direction = EDirection.Up;
+ _CreditNames[i].StartTimeUp = CreditsTimer.ElapsedMilliseconds;
+ }
+
+ }
+ break;
+
+ case EDirection.Right:
+ if (i * 4000f <= CreditsTimer.ElapsedMilliseconds)
+ {
+ float xOld = _CreditNames[i].image.Rect.X;
+ _CreditNames[i].image.Rect.X = CSettings.iRenderW - (((CSettings.iRenderW - _CreditNames[i].image.Rect.W) / 2) / 3000f) * (CreditsTimer.ElapsedMilliseconds - (i * 4000f));
+ _CreditNames[i].particleRect.X -= (xOld - _CreditNames[i].image.Rect.X);
+ _CreditNames[i].particle.Area = _CreditNames[i].particleRect;
+
+ //Check if name is in middle of screen and should go up
+ if (_CreditNames[i].image.Rect.X <= (CSettings.iRenderW - _CreditNames[i].image.Rect.W) / 2 )
+ {
+ _CreditNames[i].direction = EDirection.Up;
+ _CreditNames[i].StartTimeUp = CreditsTimer.ElapsedMilliseconds;
+ }
+
+ }
+ break;
+
+ case EDirection.Up:
+ float yOld = _CreditNames[i].image.Rect.Y;
+ _CreditNames[i].image.Rect.Y = 580 - (430f / 3000f) * (CreditsTimer.ElapsedMilliseconds - _CreditNames[i].StartTimeUp);
+ _CreditNames[i].particleRect.Y -= (yOld - _CreditNames[i].image.Rect.Y);
+ _CreditNames[i].particle.Area = _CreditNames[i].particleRect;
+
+ //Fade names out
+ if (_CreditNames[i].image.Rect.Y <= 350f)
+ {
+ //Catch some bad alpha-values
+ float alpha = ((250 - _CreditNames[i].image.Rect.Y) / 20);
+ if(alpha > 1)
+ {
+ alpha = 1;
+ }
+ else if(alpha < 0)
+ {
+ alpha = 0;
+ }
+ _CreditNames[i].image.Alpha = 1 - alpha;
+ }
+
+ //Set name inactive
+ if (_CreditNames[i].image.Rect.Y <= 150f)
+ {
+ _CreditNames[i].active = false;
+ //Check, if last name is set to false
+ if (i == _CreditNames.Count - 1)
+ {
+ //Will later fade to Main-Screen
+ active = false;
+
+ //Stop and reset timer for next time
+ CreditsTimer.Stop();
+ CreditsTimer.Reset();
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ return active;
+ }
+ }
+}
diff --git a/Vocaluxe/Screens/CScreenMain.cs b/Vocaluxe/Screens/CScreenMain.cs
index 99c5e824..703c313a 100644
--- a/Vocaluxe/Screens/CScreenMain.cs
+++ b/Vocaluxe/Screens/CScreenMain.cs
@@ -65,6 +65,10 @@ namespace Vocaluxe.Screens
CGraphics.FadeTo(EScreens.ScreenSong);
break;
+ case Keys.C:
+ CGraphics.FadeTo(EScreens.ScreenCredits);
+ break;
+
case Keys.Enter:
if (Buttons[htButtons(ButtonSing)].Selected)
CGraphics.FadeTo(EScreens.ScreenSong);
diff --git a/Vocaluxe/Screens/CScreenOptionsSound.cs b/Vocaluxe/Screens/CScreenOptionsSound.cs
index a3fd049e..2e8207f7 100644
--- a/Vocaluxe/Screens/CScreenOptionsSound.cs
+++ b/Vocaluxe/Screens/CScreenOptionsSound.cs
@@ -12,7 +12,7 @@ namespace Vocaluxe.Screens
class CScreenOptionsSound : CMenu
{
// Version number for theme files. Increment it, if you've changed something on the theme files!
- const int ScreenVersion = 1;
+ const int ScreenVersion = 2;
private const string SelectSlideBackgroundMusic = "SelectSlideBackgroundMusic";
private const string SelectSlideBackgroundMusicVolume = "SelectSlideBackgroundMusicVolume";
diff --git a/Vocaluxe/Screens/CScreenSing.cs b/Vocaluxe/Screens/CScreenSing.cs
index 7616d49c..bf38ac6b 100644
--- a/Vocaluxe/Screens/CScreenSing.cs
+++ b/Vocaluxe/Screens/CScreenSing.cs
@@ -382,16 +382,16 @@ namespace Vocaluxe.Screens
}
break;
}
-
- Lyrics[htLyrics(LyricMain)].Draw(CGame.Beat);
Lyrics[htLyrics(LyricSub)].Draw(-100);
+ Lyrics[htLyrics(LyricMain)].Draw(CGame.Beat);
- Lyrics[htLyrics(LyricMainDuet)].Draw(CGame.Beat);
Lyrics[htLyrics(LyricSubDuet)].Draw(-100);
+ Lyrics[htLyrics(LyricMainDuet)].Draw(CGame.Beat);
- Lyrics[htLyrics(LyricMainTop)].Draw(CGame.Beat);
Lyrics[htLyrics(LyricSubTop)].Draw(-100);
+ Lyrics[htLyrics(LyricMainTop)].Draw(CGame.Beat);
+
for (int i = 0; i < CGame.NumPlayer; i++)
{
@@ -582,7 +582,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++)
{
@@ -851,6 +852,20 @@ namespace Vocaluxe.Screens
lines[i] = Song.Notes.GetLines(i);
CLine[] line = lines[i].Line;
+ // 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)
+ {
+ CurrentLineSub = j;
+ }
+ }
+ }
+
+ // find current line for lyric main fading
int CurrentLine = 0;
for (int j = 0; j < line.Length; j++)
{
@@ -864,9 +879,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)
{
@@ -876,20 +893,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;
}
@@ -897,14 +923,18 @@ 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;
}
// sub
- if (CurrentLine < line.Length - 2)
+ if (CurrentLineSub < line.Length - 2)
{
- float diff = CGame.GetTimeFromBeats(line[CurrentLine + 1].FirstBeat, Song.BPM) - CurrentTime;
+ float diff = 0f;
+ diff = CGame.GetTimeFromBeats(line[CurrentLineSub + 1].FirstBeat, Song.BPM) - CurrentTime;
+
if (diff > dt)
{
Alpha[i * 2 + 1] = 1f - (diff - dt) / rt;
diff --git a/Vocaluxe/Vocaluxe.csproj b/Vocaluxe/Vocaluxe.csproj
index a62154d3..6f08fdce 100644
--- a/Vocaluxe/Vocaluxe.csproj
+++ b/Vocaluxe/Vocaluxe.csproj
@@ -188,6 +188,7 @@
Form
+