Updated credit screen (#722)

* Updated Credit Screen

* Logo for Credits Screen

* Updated Credit Screen

* Add credits logo, remove CreditRessources

* Remove CreditRessources

* Remove CreditRessources

* Remove CreditRessources

* Remove CreditRessources

* Updated Credit Screen

---------

Co-authored-by: Florian Ostertag <flokuep@users.noreply.github.com>
This commit is contained in:
GRaff844andFlorian Ostertag authored and GitHub committed 2024-11-12 19:28:16 +01:00
1 parent 9fb74d0eec
commit 27faa81985
7 files changed
+203 -776

No files matched your search

Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

+3 -20
View File
@@ -1,4 +1,4 @@
#region license #region license
// This file is part of Vocaluxe. // This file is part of Vocaluxe.
// //
// Vocaluxe is free software: you can redistribute it and/or modify // Vocaluxe is free software: you can redistribute it and/or modify
@@ -29,13 +29,11 @@ namespace Vocaluxe.Base
{ {
private static CHighscoreDB _HighscoreDB; private static CHighscoreDB _HighscoreDB;
private static CCoverDB _CoverDB; private static CCoverDB _CoverDB;
private static CResourceDB _ResourceDB;
public static bool Init() public static bool Init()
{ {
_HighscoreDB = new CHighscoreDB(CConfig.FileHighscoreDB); _HighscoreDB = new CHighscoreDB(CConfig.FileHighscoreDB);
_CoverDB = new CCoverDB(Path.Combine(CSettings.DataFolder, CSettings.FileNameCoverDB)); _CoverDB = new CCoverDB(Path.Combine(CSettings.DataFolder, CSettings.FileNameCoverDB));
_ResourceDB = new CResourceDB(Path.Combine(CSettings.ProgramFolder, CSettings.FileNameCreditsRessourcesDB));
if (!_HighscoreDB.Init()) if (!_HighscoreDB.Init())
{ {
@@ -46,12 +44,7 @@ namespace Vocaluxe.Base
{ {
CLog.Fatal("Error initializing Cover-DB"); CLog.Fatal("Error initializing Cover-DB");
return false; return false;
} }
if (!_ResourceDB.Init())
{
CLog.Fatal("Error initializing Credits-DB");
return false;
}
return true; return true;
} }
@@ -67,11 +60,6 @@ namespace Vocaluxe.Base
_CoverDB.Close(); _CoverDB.Close();
_CoverDB = null; _CoverDB = null;
} }
if (_ResourceDB != null)
{
_ResourceDB.Close();
_ResourceDB = null;
}
} }
public static bool GetDataBaseSongInfos(string artist, string title, out int numPlayed, out DateTime dateAdded, out int highscoreID) public static bool GetDataBaseSongInfos(string artist, string title, out int numPlayed, out DateTime dateAdded, out int highscoreID)
@@ -112,10 +100,5 @@ namespace Vocaluxe.Base
if (_CoverDB != null) if (_CoverDB != null)
_CoverDB.CommitCovers(); _CoverDB.CommitCovers();
} }
public static bool GetCreditsRessource(string fileName, ref CTextureRef tex)
{
return _ResourceDB != null && _ResourceDB.GetCreditsRessource(fileName, ref tex);
}
} }
} }
+1 -1
View File
@@ -108,10 +108,10 @@ namespace Vocaluxe.Base
public const string FileNameIcon = "Vocaluxe.ico"; public const string FileNameIcon = "Vocaluxe.ico";
public const string FileNameLogo = "Logo.png"; public const string FileNameLogo = "Logo.png";
public const string FileNameFonts = "Fonts.xml"; public const string FileNameFonts = "Fonts.xml";
public const string FileNameCreditsLogo = "CreditsLogo.png";
public const string FileNameOldHighscoreDB = "Ultrastar.db"; public const string FileNameOldHighscoreDB = "Ultrastar.db";
public const string FileNameCoverDB = "CoverDB.sqlite"; public const string FileNameCoverDB = "CoverDB.sqlite";
public const string FileNameCreditsRessourcesDB = "CreditsRessourcesDB.sqlite";
public const string FileNameMainLog = "Vocaluxe.log"; public const string FileNameMainLog = "Vocaluxe.log";
public const string FileNameSongLog = "Song.log"; public const string FileNameSongLog = "Song.log";
-258
View File
@@ -1,258 +0,0 @@
#region license
// This file is part of Vocaluxe.
//
// Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.InteropServices;
using Vocaluxe.Base;
using VocaluxeLib.Draw;
using VocaluxeLib.Log;
#if WIN
using System.Data.SQLite;
#else
using Mono.Data.Sqlite;
using SQLiteCommand = Mono.Data.Sqlite.SqliteCommand;
using SQLiteConnection = Mono.Data.Sqlite.SqliteConnection;
using SQLiteDataReader = Mono.Data.Sqlite.SqliteDataReader;
using SQLiteTransaction = Mono.Data.Sqlite.SqliteTransaction;
#endif
namespace Vocaluxe.Lib.Database
{
public class CResourceDB : CDatabaseBase
{
#if DEBUG
private readonly string[] _FilesV1 = new string[]
{
"Logo_voc.png", "PerfectNoteStar.png", "redDot.png", "blueDot.png", "brunzel.png", "Darkice.png", "flokuep.png", "flamefire.png", "bohning.png", "mesand.png",
"babene03.png", "lukeIam.png"
};
#endif
public CResourceDB(string filePath) : base(filePath) {}
public override bool Init()
{
if (!base.Init())
return false;
if (_Version < 0)
{
CLog.Error("Can't find Ressource-DB!");
return false;
}
if (_Version < CSettings.DatabaseCreditsRessourcesVersion)
{
#if DEBUG
return _CreateDB() && _UpdateV1();
#else
CLog.Error("Upgrading Ressource-DB not possible");
return false;
#endif
}
return true;
}
public bool GetCreditsRessource(string fileName, ref CTextureRef tex)
{
if (_Connection == null)
return false;
bool result = false;
using (var command = new SQLiteCommand(_Connection))
{
command.CommandText = "SELECT id, width, height FROM Images WHERE [Path] = @path";
command.Parameters.Add("@path", DbType.String, 0).Value = fileName;
SQLiteDataReader reader = command.ExecuteReader();
if (reader != null && reader.HasRows)
{
reader.Read();
int id = reader.GetInt32(0);
int w = reader.GetInt32(1);
int h = reader.GetInt32(2);
reader.Close();
command.CommandText = "SELECT Data FROM ImageData WHERE ImageID = @id";
command.Parameters.Add("@id", DbType.Int32).Value = id;
reader = command.ExecuteReader();
if (reader.HasRows)
{
result = true;
reader.Read();
byte[] data = _GetBytes(reader);
tex = CDraw.AddTexture(w, h, data);
}
}
if (reader != null)
reader.Dispose();
}
return result;
}
#if DEBUG
//Update from V0 (empty) to V1
private bool _UpdateV1()
{
if (_Connection == null || _Version >= 1)
return false;
using (SQLiteTransaction transaction = _Connection.BeginTransaction())
{
try
{
foreach (string file in _FilesV1)
{
string filePath = Path.Combine(CSettings.ProgramFolder, file);
if (!_AddImageToCreditsDB(filePath, transaction))
{
transaction.Rollback();
return false;
}
}
using (SQLiteCommand command = new SQLiteCommand(_Connection))
{
command.Transaction = transaction;
command.CommandText = "Update Version SET Value=@Value)";
command.Parameters.Add("@Value", DbType.Int32).Value = 1;
command.ExecuteNonQuery();
}
transaction.Commit();
}
catch (Exception)
{
transaction.Rollback();
return false;
}
}
return true;
}
//If you want to add an image to db, call this method!
private bool _AddImageToCreditsDB(string imagePath, SQLiteTransaction transaction)
{
if (_Connection == null || !File.Exists(imagePath))
return false;
Bitmap origin;
try
{
origin = new Bitmap(imagePath);
}
catch (Exception)
{
CLog.Error("Error loading image: " + imagePath);
return false;
}
try
{
int w = origin.Width;
int h = origin.Height;
byte[] data = new byte[w * h * 4];
BitmapData bmpData = origin.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(bmpData.Scan0, data, 0, w * h * 4);
origin.UnlockBits(bmpData);
using (SQLiteCommand command = new SQLiteCommand(_Connection))
{
command.Transaction = transaction;
command.CommandText = "INSERT INTO Images (Path, width, height) VALUES (@path, @w, @h)";
command.Parameters.Add("@path", DbType.String).Value = Path.GetFileName(imagePath);
command.Parameters.Add("@w", DbType.Int32).Value = w;
command.Parameters.Add("@h", DbType.Int32).Value = h;
command.ExecuteNonQuery();
}
int id = -1;
using (SQLiteCommand command = new SQLiteCommand(_Connection))
{
command.Transaction = transaction;
command.CommandText = "SELECT id FROM Images WHERE [Path] = @path";
command.Parameters.Add("@path", DbType.String, 0).Value = Path.GetFileName(imagePath);
using (SQLiteDataReader reader = command.ExecuteReader())
{
if (reader != null)
{
reader.Read();
id = reader.GetInt32(0);
}
}
}
if (id < 0)
return false;
using (SQLiteCommand command = new SQLiteCommand(_Connection))
{
command.Transaction = transaction;
command.CommandText = "INSERT INTO ImageData (ImageID, Data) VALUES (@id, @data)";
command.Parameters.Add("@id", DbType.Int32).Value = id;
command.Parameters.Add("@data", DbType.Binary).Value = data;
command.ExecuteNonQuery();
return true;
}
}
catch (Exception)
{
return false;
}
finally
{
origin.Dispose();
}
}
private bool _CreateDB()
{
if (_Connection == null)
return false;
try
{
using (SQLiteCommand command = new SQLiteCommand(_Connection))
{
command.CommandText = "CREATE TABLE IF NOT EXISTS Version (Value INTEGER NOT NULL);";
command.ExecuteNonQuery();
command.CommandText = "INSERT INTO Version (Value) VALUES(0)";
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();
}
}
catch (Exception e)
{
CLog.Error("Error creating Ressource DB " + e);
return false;
}
return true;
}
#endif
}
}
+198 -495
View File
@@ -1,16 +1,16 @@
#region license #region license
// This file is part of Vocaluxe. // This file is part of Vocaluxe.
// //
// Vocaluxe is free software: you can redistribute it and/or modify // Vocaluxe is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by // it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or // the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version. // (at your option) any later version.
// //
// Vocaluxe is distributed in the hope that it will be useful, // Vocaluxe is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>. // along with Vocaluxe. If not, see <http://www.gnu.org/licenses/>.
#endregion #endregion
@@ -19,6 +19,8 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Windows.Forms; using System.Windows.Forms;
using System.Drawing;
using System.IO;
using Vocaluxe.Base; using Vocaluxe.Base;
using Vocaluxe.Base.Fonts; using Vocaluxe.Base.Fonts;
using VocaluxeLib; using VocaluxeLib;
@@ -28,152 +30,6 @@ using VocaluxeLib.Menu;
namespace Vocaluxe.Screens namespace Vocaluxe.Screens
{ {
enum EDirection
{
Left,
Right,
Up
}
class CCreditTranslation
{
private readonly string _Language;
private readonly List<CText> _Texts;
public float StartTime;
public float Y
{
get { return _Texts[0].Y; }
set
{
float diff = value - _Texts[0].Y;
foreach (CText t in _Texts)
t.Y += diff;
}
}
public float Alpha
{
get { return _Texts[0].Alpha; }
set
{
foreach (CText t in _Texts)
t.Alpha = value;
}
}
public bool Visible
{
set
{
foreach (CText t in _Texts)
t.Visible = value;
}
}
public float LastY
{
get
{
int lastText = _Texts.Count - 1;
return _Texts[lastText].Y + _Texts[lastText].H;
}
}
public CCreditTranslation(string language, List<CText> texts)
{
_Language = language;
_Texts = texts;
}
public void Reset()
{
StartTime = -1;
Alpha = 1f;
Visible = true;
_Texts[0].Y = CSettings.RenderH + 1;
float y = CSettings.RenderH + 1;
foreach (CText t in _Texts)
{
y += 25;
t.Y = y;
}
}
}
class CCreditName
{
private readonly CStatic _Image;
private readonly CStatic _ImgDot;
private readonly CParticleEffect _Particle;
private readonly int _ParticleOffsetX;
private readonly int _ParticleOffsetY;
public EDirection Direction;
public float StartTimeUp;
public CCreditName(CStatic image, CStatic imgDot, CParticleEffect particle, int particleOffsetX, int particleOffsetY)
{
_Image = image;
_ImgDot = imgDot;
_Particle = particle;
_ParticleOffsetX = (int)Math.Round(particleOffsetX * image.Rect.W / image.Texture.OrigSize.Width - particle.Rect.W / 2);
_ParticleOffsetY = (int)Math.Round(particleOffsetY * image.Rect.H / image.Texture.OrigSize.Height - particle.Rect.H / 2);
Visible = true;
}
public float X
{
get { return _Image.X; }
set
{
_Image.X = value;
_ImgDot.X = value + _ParticleOffsetX;
_Particle.X = value + _ParticleOffsetX;
}
}
public float Y
{
get { return _Image.Rect.Y; }
set
{
_Image.Y = value;
_ImgDot.Y = value + _ParticleOffsetY;
_Particle.Y = value + _ParticleOffsetY;
}
}
public float W
{
get { return _Image.Rect.W; }
}
public float H
{
get { return _Image.Rect.H; }
}
public float Alpha
{
get { return _Image.Alpha; }
set
{
_Image.Alpha = value;
_ImgDot.Alpha = value;
}
}
public bool Visible
{
set
{
_Image.Visible = value;
_ImgDot.Visible = value;
_Particle.Visible = value;
}
get { return _Image.Visible; }
}
}
public class CScreenCredits : CMenu public class CScreenCredits : CMenu
{ {
// Version number for theme files. Increment it, if you've changed something on the theme files! // Version number for theme files. Increment it, if you've changed something on the theme files!
@@ -183,184 +39,178 @@ namespace Vocaluxe.Screens
} }
private CStatic _Logo; private CStatic _Logo;
private CParticleEffect _StarsRed;
private CParticleEffect _StarsBlue; private Stopwatch _ScrollTimer;
private List<CCreditName> _CreditNames;
private List<CCreditTranslation> _Translations; private List<dynamic> _ScrollingElements;
private int _NumTranslationTexts; private Dictionary<dynamic, float> _ElementStartYPositions;
private float _previousElapsedMilliseconds;
private Stopwatch _LogoTimer;
private Stopwatch _CreditsTimer;
private Stopwatch _TranslationsTimer;
private Stopwatch _TextTimer;
private List<string[]> _Paragraphs;
private List<CText> _ParagraphTexts;
private CTextureRef _TexLogo; private CTextureRef _TexLogo;
private CTextureRef _TexPerfectNoteStar;
private CTextureRef _TexRedDot;
private CTextureRef _TexBlueDot;
private CTextureRef _TexNameBrunzel;
private CTextureRef _TexNameDarkice;
private CTextureRef _TexNameFlokuep;
private CTextureRef _TexNameFlamefire;
private CTextureRef _TexNameLukeIam;
private CTextureRef _TexNameMesand;
private CTextureRef _TexNameBohning;
private CTextureRef _TexNameBabene03;
private SThemeBackground _BGTheme;
public override EMusicType CurrentMusicType public override EMusicType CurrentMusicType
{ {
get { return EMusicType.None; } get { return EMusicType.Background; }
} }
public override void Init() public override void Init()
{ {
base.Init(); base.Init();
_LogoTimer = new Stopwatch(); _ScrollTimer = new Stopwatch();
_CreditsTimer = new Stopwatch(); _ScrollingElements = new List<dynamic>();
_TranslationsTimer = new Stopwatch(); _ElementStartYPositions = new Dictionary<dynamic, float>();
_TextTimer = new Stopwatch();
//Text for last part of credits.
_ParagraphTexts = new List<CText>();
_Paragraphs = new List<string[]>();
string paragraph = "Inspired by the achievements of UltraStar Deluxe and its variants and pursuing the goal of making " +
"a good thing even better, we ended up rewriting the game from scratch. And a new implementation in a new " +
"programming language called for a new name - and VOCALUXE [ˈvoʊˈkəˈlʌks] it is!";
string[] words = paragraph.Split(new char[] {' '});
_Paragraphs.Add(words);
paragraph = "This first public version has already implemented many of the original features and it is fully " +
"compatible with all the song files in your existing song collection. The code design allows a much faster " +
"implementation of new features, thus the roadmap for the next few stable releases is packed and we expect much " +
"shorter release cycles than ever before. And, of course, our and your ideas may be the features of tomorrow.";
words = paragraph.Split(new char[] {' '});
_Paragraphs.Add(words);
paragraph = "We appreciate the feedback in the beta release phase and are, of course, always open for bug reports, " +
"suggestions for improvements and ideas for new features. We would also like to thank the translators who make " +
"Vocaluxe an international experience from the very beginning and all those diligent song makers out there - " +
"there's something for everyone in the huge collection of available songs! Last but not least, thanks to " +
"Kosal Sen's Philly Sans type used in the Vocaluxe Logo.";
words = paragraph.Split(new char[] {' '});
_Paragraphs.Add(words);
paragraph = "Go ahead and grab your mics, crank up your stereo, warm up your voice and get ready to sing to the best " +
"of your abilities!";
words = paragraph.Split(new char[] {' '});
_Paragraphs.Add(words);
_BGTheme.Type = EBackgroundTypes.Color;
_BGTheme.Color = new SThemeColor {Name = null, R = 0, G = 0.18f, B = 0.474f, A = 1};
} }
public override void LoadTheme(string xmlPath) public override void LoadTheme(string xmlPath)
{ {
// Vocaluxe-Logo
bool ressourceOK = true; bool ressourceOK = true;
//Vocaluxe-Logo string path = Path.Combine(CSettings.ProgramFolder, CSettings.FolderNameGraphics, CSettings.FileNameCreditsLogo);
ressourceOK &= CDataBase.GetCreditsRessource("Logo_voc.png", ref _TexLogo);
//Little stars for logo if (File.Exists(path))
ressourceOK &= CDataBase.GetCreditsRessource("PerfectNoteStar.png", ref _TexPerfectNoteStar);
ressourceOK &= CDataBase.GetCreditsRessource("redDot.png", ref _TexRedDot);
ressourceOK &= CDataBase.GetCreditsRessource("blueDot.png", ref _TexBlueDot);
ressourceOK &= CDataBase.GetCreditsRessource("brunzel.png", ref _TexNameBrunzel);
ressourceOK &= CDataBase.GetCreditsRessource("Darkice.png", ref _TexNameDarkice);
ressourceOK &= CDataBase.GetCreditsRessource("flokuep.png", ref _TexNameFlokuep);
ressourceOK &= CDataBase.GetCreditsRessource("flamefire.png", ref _TexNameFlamefire);
ressourceOK &= CDataBase.GetCreditsRessource("lukeIam.png", ref _TexNameLukeIam);
ressourceOK &= CDataBase.GetCreditsRessource("bohning.png", ref _TexNameBohning);
ressourceOK &= CDataBase.GetCreditsRessource("mesand.png", ref _TexNameMesand);
ressourceOK &= CDataBase.GetCreditsRessource("babene03.png", ref _TexNameBabene03);
if (!ressourceOK)
CLog.Fatal("Could not load all ressources!");
//Prepare Text
int lastY = 280;
foreach (string[] paragraph in _Paragraphs)
{ {
string line = ""; _TexLogo = CDraw.AddTexture(path);
for (int e = 0; e < paragraph.Length; e++) ressourceOK &= _TexLogo != null;
{ }
if (paragraph[e] == null) else
continue; {
string newLine = " " + paragraph[e]; ressourceOK = false;
CText text = GetNewText(75, lastY, -2, 25, -1, EAlignment.Left, EStyle.Bold, "Outline", new SColorF(1, 1, 1, 1), line); }
text.Visible = false; if (!ressourceOK)
if (CFonts.GetTextBounds(text).Width < (CSettings.RenderW - 220)) {
{ CLog.Fatal("Could not load all resources!");
line += newLine;
//Check if all words are used
if ((e + 1) == paragraph.Length)
{
text.Text = line;
_ParagraphTexts.Add(text);
line = "";
lastY += 40;
}
}
else
{
_ParagraphTexts.Add(text);
line = newLine;
lastY += 27;
}
_AddText(text);
}
} }
// Initialize background theme
SThemeBackground _BGTheme = new SThemeBackground
{
Type = EBackgroundTypes.Color,
Color = new SThemeColor { Name = "Black", R = 0f, G = 0f, B = 0f, A = 1f }
};
// Create and add background
CBackground bg = new CBackground(_BGTheme, -1); CBackground bg = new CBackground(_BGTheme, -1);
bg.LoadSkin(); bg.LoadSkin();
_AddBackground(bg); _AddBackground(bg);
//Vocaluxe-Logo // Position Y for the first scrolling element
float scrollY = CSettings.RenderH - 1f;
// Create logo
_Logo = GetNewStatic(_TexLogo, new SColorF(1, 1, 1, 1), _Logo = GetNewStatic(_TexLogo, new SColorF(1, 1, 1, 1),
new SRectF((float)(CSettings.RenderW - _TexLogo.OrigSize.Width) / 2, -270, _TexLogo.OrigSize.Width, _TexLogo.OrigSize.Height, -2)); new SRectF((float)(CSettings.RenderW - _TexLogo.OrigSize.Width) / 2, scrollY, _TexLogo.OrigSize.Width, _TexLogo.OrigSize.Height, -2));
_Logo.Visible = false;
_AddStatic(_Logo); _AddStatic(_Logo);
_ScrollingElements.Add(_Logo);
_ElementStartYPositions[_Logo] = scrollY;
//Little stars for logo scrollY += _Logo.Rect.H + 20f; // Update scrollY after logo
var numstars = (int)(_Logo.Rect.W * 0.25f / 2f);
var partRect = new SRectF(_Logo.Rect.X, _Logo.Rect.Y, _Logo.Rect.W, _Logo.Rect.H, -1);
_StarsRed = _GetStarParticles(numstars, true, partRect, true);
_StarsBlue = _GetStarParticles(numstars, false, partRect, true);
_AddParticleEffect(_StarsRed);
_AddParticleEffect(_StarsBlue);
//Credit names // Helper variables for font sizes
_CreditNames = new List<CCreditName>(); int bigHeadlineSize = 45;
int headlineSize = 40;
int boldSize = 35;
int textSize = 30;
float paragraphSpacing = 30f; // Space between paragraphs
_AddNewCreditName(_TexNameBrunzel, 502, 29, true); // Helper method to add text with formatting
_AddNewCreditName(_TexNameDarkice, 360, 55, true); void AddText(string content, int size, EStyle style, float yOffset, EAlignment alignment = EAlignment.Center)
_AddNewCreditName(_TexNameFlokuep, 214, 14, true); {
_AddNewCreditName(_TexNameFlamefire, 496, 46, true); CText text = GetNewText(new CText(CSettings.RenderW / 2, scrollY + yOffset, -2f, size, -1, alignment, style, "Outline", new SColorF(1, 1, 1, 1), content));
_AddNewCreditName(_TexNameLukeIam, 411, 26, true); text.Visible = false;
_AddNewCreditName(_TexNameBohning, 383, 54, false); _ScrollingElements.Add(text);
_AddNewCreditName(_TexNameMesand, 525, 13, false); _AddText(text);
_AddNewCreditName(_TexNameBabene03, 33, 26, false); _ElementStartYPositions[text] = text.Y;
scrollY += size + yOffset;
}
_AddTranslations(); // Intro
AddText("12 Years Vocaluxe!", bigHeadlineSize, EStyle.Bold, 0);
scrollY += paragraphSpacing;
AddText("A heartfelt thank you to all the people who have contributed to making Vocaluxe a reality over the past 12 years.", textSize, EStyle.Normal, 0);
AddText("Your dedication, time, and open-source spirit have been incredible. Keep contributing or re-join and make the world sing!", textSize, EStyle.Normal, 0);
scrollY += paragraphSpacing * 3;
AddText("VOCALUXE Team (2011-today)", bigHeadlineSize, EStyle.Bold, 0);
scrollY += paragraphSpacing * 2;
// Production
AddText("PRODUCTION", headlineSize, EStyle.Bold, 0);
scrollY += paragraphSpacing;
AddText("Project Leader", boldSize, EStyle.Bold, 0);
AddText("Florian Ostertag (2013-today)", textSize, EStyle.Normal, 0);
scrollY += paragraphSpacing;
AddText("Project Management", boldSize, EStyle.Bold, 0);
AddText("Marwin (2023-today)", textSize, EStyle.Normal, 0);
scrollY += paragraphSpacing * 3;
// Design
AddText("DESIGN", headlineSize, EStyle.Bold, 0);
scrollY += paragraphSpacing;
AddText("Original Concept/Idea", boldSize, EStyle.Bold, 0);
AddText("Alexander Eckhart (2011-2015)", textSize, EStyle.Normal, 0);
scrollY += paragraphSpacing;
AddText("Party Mode Design", boldSize, EStyle.Bold, 0);
AddText("Alexander Eckhart (2011-2015)", textSize, EStyle.Normal, 0);
AddText("Florian Ostertag (2013-today)", textSize, EStyle.Normal, 0);
scrollY += paragraphSpacing * 3;
// Programming/Engineering
AddText("PROGRAMMING/ENGINEERING", headlineSize, EStyle.Bold, 0);
scrollY += paragraphSpacing;
AddText("Technical Director", boldSize, EStyle.Bold, 0);
AddText("Alexander Eckhart (2011-2015)", textSize, EStyle.Normal, 0);
scrollY += paragraphSpacing;
AddText("Software Engineer", boldSize, EStyle.Bold, 0);
AddText("Florian Ostertag (2013-today)", textSize, EStyle.Normal, 0);
AddText("LukeIam (2013-2019)", textSize, EStyle.Normal, 0);
AddText("Alexander Eckhart (2011-2015)", textSize, EStyle.Normal, 0);
AddText("Alexander Grund (2013-2015)", textSize, EStyle.Normal, 0);
AddText("Darkice", textSize, EStyle.Normal, 0);
scrollY += paragraphSpacing;
AddText("Programmer", boldSize, EStyle.Bold, 0);
AddText("Stefan1200 (2020-2022)", textSize, EStyle.Normal, 0);
AddText("Stephan Sundermann (2012-2014)", textSize, EStyle.Normal, 0);
AddText("GaryCXJk (2020-2021)", textSize, EStyle.Normal, 0);
AddText("Damien Laguerre (2024-today)", textSize, EStyle.Normal, 0);
scrollY += paragraphSpacing * 3;
// Art/Graphics
AddText("ART/GRAPHICS", headlineSize, EStyle.Bold, 0);
scrollY += paragraphSpacing;
AddText("UI Artist/Graphics", boldSize, EStyle.Bold, 0);
AddText("Marwin (2023-today)", textSize, EStyle.Normal, 0);
AddText("Jiiniasu (2016-2020)", textSize, EStyle.Normal, 0);
AddText("Markus Bohning (2012)", textSize, EStyle.Normal, 0);
AddText("Mesand (2012)", textSize, EStyle.Normal, 0);
AddText("Babene03 (2012)", textSize, EStyle.Normal, 0);
scrollY += paragraphSpacing;
AddText("Sound/Audio/Music Design", boldSize, EStyle.Bold, 0);
AddText("Marwin (2023-today)", textSize, EStyle.Normal, 0);
scrollY += paragraphSpacing;
AddText("Audio Producer", boldSize, EStyle.Bold, 0);
AddText("Ivymusic", textSize, EStyle.Normal, 0);
scrollY += paragraphSpacing * 3;
// Translation
AddText("TRANSLATION", headlineSize, EStyle.Bold, 0);
scrollY += paragraphSpacing;
AddText("Thanks to everyone translating Vocaluxe into different languages.", textSize, EStyle.Normal, 0);
scrollY += paragraphSpacing * 4;
// Website
AddText("www.vocaluxe.org", headlineSize, EStyle.Bold, 0);
AddText("www.open-music-games.org", headlineSize, EStyle.Bold, 0);
} }
public override void ReloadTheme(string xmlPath) {} public override void ReloadTheme(string xmlPath) { }
public override void SaveTheme() {} public override void SaveTheme() { }
public override void UnloadSkin() {} public override void UnloadSkin() { }
public override void ReloadSkin() {} public override void ReloadSkin() { }
public override bool HandleInput(SKeyEvent keyEvent) public override bool HandleInput(SKeyEvent keyEvent)
{ {
@@ -393,227 +243,80 @@ namespace Vocaluxe.Screens
return true; return true;
} }
private CParticleEffect _GetStarParticles(int numStars, bool isRed, SRectF rect, bool bigParticles)
{
SColorF partColor = isRed ? new SColorF(1, 0, 0, 1) : new SColorF(0.149f, 0.415f, 0.819f, 1);
int partSize = bigParticles ? 35 : 25;
return GetNewParticleEffect(numStars, partColor, rect, _TexPerfectNoteStar, partSize, EParticleType.Star);
}
private void _AddNewCreditName(CTextureRef texture, int particleOffsetX, int particleOffsetY, bool bigParticles)
{
bool isRed = _CreditNames.Count % 2 == 0;
int partRectSize = bigParticles ? 25 : 20;
int partCount = bigParticles ? 8 : 6;
CTextureRef texDot = isRed ? _TexRedDot : _TexBlueDot;
CStatic image = GetNewStatic(texture, new SColorF(1, 1, 1, 1), new SRectF(-1, -1, 400, 120, -4));
var particleRect = new SRectF(-1, -1, partRectSize, partRectSize, -6);
SRectF imgDotRect = particleRect;
imgDotRect.Z = -5;
CStatic imgDot = GetNewStatic(texDot, new SColorF(1, 1, 1, 1), imgDotRect);
CParticleEffect particle = _GetStarParticles(partCount, isRed, particleRect, bigParticles);
var credit = new CCreditName(image, imgDot, particle, particleOffsetX, particleOffsetY);
_CreditNames.Add(credit);
_AddStatic(image);
_AddStatic(imgDot);
_AddParticleEffect(particle);
}
private void _AddTranslations()
{
CCreditTranslation intro = _AddNewTranslation("A special thanks to all our translators", new List<string> { });
CCreditTranslation asturian = _AddNewTranslation("Asturian", new List<string> { "Puxarra" });
CCreditTranslation czech = _AddNewTranslation("Czech", new List<string> { "fri" });
CCreditTranslation dutch = _AddNewTranslation("Dutch", new List<string> { "thijsblaauw", "DeMarin" });
CCreditTranslation french = _AddNewTranslation("French", new List<string> { "pinky007", "javafrog" });
CCreditTranslation hungarian = _AddNewTranslation("Hungarian", new List<string> { "warez", "skyli" });
CCreditTranslation italian = _AddNewTranslation("Italian", new List<string> { "giuseppep", "LFactory", "yogotosleepnow" });
CCreditTranslation portugese = _AddNewTranslation("Portuguese", new List<string> { "2borG", "xventil" });
CCreditTranslation spanish = _AddNewTranslation("Spanish", new List<string> { "Pantero03", "RubenDjOn", "TeLiX", "karv" });
CCreditTranslation swedish = _AddNewTranslation("Swedish", new List<string> { "u28151", "Jiiniasu" });
CCreditTranslation turkish = _AddNewTranslation("Turkish", new List<string> { "spirax", "Swertyy" });
_Translations = new List<CCreditTranslation> { intro, asturian, czech, dutch, french, hungarian, italian, spanish, swedish, turkish };
}
private CCreditTranslation _AddNewTranslation(string language, List<string> translators)
{
List<CText> texts = new List<CText>();
CText text = GetNewText(new CText(CSettings.RenderW / 2, CSettings.RenderH + 1, -4f, 30, -1, EAlignment.Center, EStyle.Bold, "Outline", new SColorF(1, 1, 1, 1), language));
_AddText(text);
texts.Add(text);
_NumTranslationTexts++;
float y = texts[0].Y;
foreach (string t in translators)
{
y += 30;
text = GetNewText(new CText(CSettings.RenderW / 2, y, -4f, 27, -1, EAlignment.Center, EStyle.Normal, "Outline", new SColorF(1, 1, 1, 1), t));
_AddText(text);
texts.Add(text);
_NumTranslationTexts++;
}
CCreditTranslation cct = new CCreditTranslation(language, texts);
return cct;
}
public override void OnShow() public override void OnShow()
{ {
base.OnShow(); base.OnShow();
foreach (CText text in _ParagraphTexts) // Reset positions
text.Visible = false; foreach (dynamic element in _ScrollingElements)
bool isRight = true;
foreach (CCreditName name in _CreditNames)
{ {
name.Visible = true; if (_ElementStartYPositions.TryGetValue(element, out float startY))
name.Direction = isRight ? EDirection.Right : EDirection.Left; {
name.X = -name.W; if (element is CText text)
name.Y = 580; {
name.Alpha = 1; text.Y = startY;
isRight = !isRight; }
else if (element == _Logo)
{
_Logo.Y = startY;
}
}
} }
_Logo.Y = -270;
_StarsRed.Y = _Logo.Y;
_StarsBlue.Y = _Logo.Y;
foreach (CCreditTranslation translation in _Translations)
translation.Reset();
_TextTimer.Reset(); // Set all elements to visible immediately
_LogoTimer.Reset(); foreach (dynamic element in _ScrollingElements)
_CreditsTimer.Reset(); {
_TranslationsTimer.Reset(); element.Visible = true;
} }
public override void OnShowFinish() // Start the scroll timer immediately
{ _ScrollTimer.Reset();
base.OnShowFinish(); _ScrollTimer.Start();
_previousElapsedMilliseconds = 0;
_LogoTimer.Start();
} }
private bool _Animation() private bool _Animation()
{ {
bool active = false; if (!_ScrollTimer.IsRunning)
if (_LogoTimer.IsRunning) return false;
float deltaTime = (_ScrollTimer.ElapsedMilliseconds - _previousElapsedMilliseconds) / 1000f; // Convert milliseconds to seconds
_previousElapsedMilliseconds = _ScrollTimer.ElapsedMilliseconds;
float scrollSpeed = 60f;
foreach (dynamic element in _ScrollingElements)
{ {
active = true; if (element is CText text)
_Logo.Y = -270 + (270f / 3000f) * _LogoTimer.ElapsedMilliseconds;
_StarsRed.Y = _Logo.Y;
_StarsBlue.Y = _Logo.Y;
if (_LogoTimer.ElapsedMilliseconds >= 2000 && !_CreditsTimer.IsRunning)
_CreditsTimer.Start();
if (_LogoTimer.ElapsedMilliseconds >= 3000)
_LogoTimer.Stop();
}
if (_CreditsTimer.IsRunning)
{
active = true;
for (int i = 0; i < _CreditNames.Count; i++)
{ {
if (!_CreditNames[i].Visible) text.Y -= scrollSpeed * deltaTime;
continue; }
switch (_CreditNames[i].Direction) else if (element == _Logo)
{ {
case EDirection.Right: _Logo.Y -= scrollSpeed * deltaTime;
if (i * 4000f <= _CreditsTimer.ElapsedMilliseconds)
{
_CreditNames[i].X = -450 + (((CSettings.RenderW - _CreditNames[i].W) / 2) / 3000f) * (_CreditsTimer.ElapsedMilliseconds - (i * 4000f));
//Check if name is in middle of screen and should go up
if (_CreditNames[i].X >= (CSettings.RenderW - _CreditNames[i].W) / 2)
{
_CreditNames[i].Direction = EDirection.Up;
_CreditNames[i].StartTimeUp = _CreditsTimer.ElapsedMilliseconds;
}
}
break;
case EDirection.Left:
if (i * 4000f <= _CreditsTimer.ElapsedMilliseconds)
{
_CreditNames[i].X = CSettings.RenderW -
(((CSettings.RenderW - _CreditNames[i].W) / 2) / 3000f) * (_CreditsTimer.ElapsedMilliseconds - (i * 4000f));
//Check if name is in middle of screen and should go up
if (_CreditNames[i].X <= (CSettings.RenderW - _CreditNames[i].W) / 2)
{
_CreditNames[i].Direction = EDirection.Up;
_CreditNames[i].StartTimeUp = _CreditsTimer.ElapsedMilliseconds;
}
}
break;
case EDirection.Up:
_CreditNames[i].Y = 580 - (430f / 3000f) * (_CreditsTimer.ElapsedMilliseconds - _CreditNames[i].StartTimeUp);
//Set name inactive
if (_CreditNames[i].Y <= 160f)
{
_CreditNames[i].Visible = false;
//Check, if last name is shown
if (i == _CreditNames.Count - 1)
{
_CreditsTimer.Stop();
_TranslationsTimer.Start();
}
}
else if (_CreditNames[i].Y <= 360f)
{
//Fade names out
float alpha = ((360 - _CreditNames[i].Y) / 200).Clamp(0, 1);
_CreditNames[i].Alpha = 1 - alpha;
}
break;
}
} }
} }
if (_TranslationsTimer.IsRunning)
// Check if the last element has scrolled off the top
dynamic lastElement = _ScrollingElements[_ScrollingElements.Count - 1];
float elementBottomY = 0;
if (lastElement is CText lastText)
{ {
active = true; elementBottomY = lastText.Y + lastText.H;
}
for (int i = 0; i < _Translations.Count; i++) else if (lastElement == _Logo)
{ {
if (i * 1500f < _TranslationsTimer.ElapsedMilliseconds) elementBottomY = _Logo.Y + _Logo.Rect.H;
{
if (_Translations[i].StartTime == -1)
_Translations[i].StartTime = _TranslationsTimer.ElapsedMilliseconds;
float newY = 720f - (520f / 5000f) * (_TranslationsTimer.ElapsedMilliseconds - _Translations[i].StartTime);
_Translations[i].Y = newY;
}
if (_Translations[i].Y <= 160f)
{
_Translations[i].Visible = false;
if (i == _Translations.Count - 1)
{
_TranslationsTimer.Stop();
_TextTimer.Start();
foreach (CText text in _ParagraphTexts)
text.Visible = true;
}
}
if (_Translations[i].Y <= 360f)
{
//Fade out
float alpha = ((360 - _Translations[i].Y) / 200).Clamp(0,1);
_Translations[i].Alpha = 1 - alpha;
}
}
} }
if (_TextTimer.IsRunning)
active = _TextTimer.ElapsedMilliseconds <= 10000;
return active; if (elementBottomY < 0)
{
_ScrollTimer.Stop();
return false;
}
return true;
} }
} }
} }
+1 -2
View File
@@ -198,7 +198,6 @@
<Compile Include="Lib\Database\CCoverDB.cs" /> <Compile Include="Lib\Database\CCoverDB.cs" />
<Compile Include="Lib\Database\CDatabaseBase.cs" /> <Compile Include="Lib\Database\CDatabaseBase.cs" />
<Compile Include="Lib\Database\CHighscoreDB.cs" /> <Compile Include="Lib\Database\CHighscoreDB.cs" />
<Compile Include="Lib\Database\CResourceDB.cs" />
<Compile Include="Lib\Draw\CDrawBase.cs" /> <Compile Include="Lib\Draw\CDrawBase.cs" />
<Compile Include="Lib\Draw\CDrawBaseWindows.cs" /> <Compile Include="Lib\Draw\CDrawBaseWindows.cs" />
<Compile Include="Lib\Draw\CTextureBase.cs" /> <Compile Include="Lib\Draw\CTextureBase.cs" />
@@ -589,4 +588,4 @@
<Import Project="..\packages\vocaluxe.dependencies.sqlite.1.0.1\build\vocaluxe.dependencies.sqlite.targets" Condition="Exists('..\packages\vocaluxe.dependencies.sqlite.1.0.1\build\vocaluxe.dependencies.sqlite.targets')" /> <Import Project="..\packages\vocaluxe.dependencies.sqlite.1.0.1\build\vocaluxe.dependencies.sqlite.targets" Condition="Exists('..\packages\vocaluxe.dependencies.sqlite.1.0.1\build\vocaluxe.dependencies.sqlite.targets')" />
<Import Project="..\packages\vocaluxe.dependencies.gstreamer.1.0.3\build\vocaluxe.dependencies.gstreamer.targets" Condition="'$(Configuration)' != 'ReleaseLinux' AND '$(Configuration)' != 'DebugLinux' AND Exists('..\packages\vocaluxe.dependencies.gstreamer.1.0.3\build\vocaluxe.dependencies.gstreamer.targets')" /> <Import Project="..\packages\vocaluxe.dependencies.gstreamer.1.0.3\build\vocaluxe.dependencies.gstreamer.targets" Condition="'$(Configuration)' != 'ReleaseLinux' AND '$(Configuration)' != 'DebugLinux' AND Exists('..\packages\vocaluxe.dependencies.gstreamer.1.0.3\build\vocaluxe.dependencies.gstreamer.targets')" />
<Import Project="..\packages\vocaluxe.dependencies.portaudiosharp.1.0.3\build\vocaluxe.dependencies.portaudiosharp.targets" Condition="Exists('..\packages\vocaluxe.dependencies.portaudiosharp.1.0.3\build\vocaluxe.dependencies.portaudiosharp.targets')" /> <Import Project="..\packages\vocaluxe.dependencies.portaudiosharp.1.0.3\build\vocaluxe.dependencies.portaudiosharp.targets" Condition="Exists('..\packages\vocaluxe.dependencies.portaudiosharp.1.0.3\build\vocaluxe.dependencies.portaudiosharp.targets')" />
</Project> </Project>