aboutsummaryrefslogtreecommitdiffstats
path: root/Game
diff options
context:
space:
mode:
Diffstat (limited to 'Game')
-rw-r--r--Game/Code/Classes/UDataBase.pas131
-rw-r--r--Game/Code/Classes/UGraphic.pas36
-rw-r--r--Game/Code/Classes/UThemes.pas33
-rw-r--r--Game/Code/Menu/UMenuText.pas6
-rw-r--r--Game/Code/Screens/UScreenMain.pas6
-rw-r--r--Game/Code/Screens/UScreenPartyOptions.pas9
-rw-r--r--Game/Code/Screens/UScreenStatDetail.pas254
-rw-r--r--Game/Code/Screens/UScreenStatMain.pas229
-rw-r--r--Game/Code/UltraStar.dpr4
9 files changed, 680 insertions, 28 deletions
diff --git a/Game/Code/Classes/UDataBase.pas b/Game/Code/Classes/UDataBase.pas
index 1ebc18db..0e5a4a3f 100644
--- a/Game/Code/Classes/UDataBase.pas
+++ b/Game/Code/Classes/UDataBase.pas
@@ -8,6 +8,26 @@ uses USongs, SQLiteTable3;
//DataBaseSystem - Class including all DB Methods
//--------------------
type
+ TStatResult = record
+ Case Typ: Byte of
+ 0: (Singer: ShortString;
+ Score: Word;
+ Difficulty: Byte;
+ SongArtist: ShortString;
+ SongTitle: ShortString);
+
+ 1: (Player: ShortString;
+ AverageScore: Word);
+
+ 2: (Artist: ShortString;
+ Title: ShortString;
+ TimesSung: Word);
+
+ 3: (ArtistName: ShortString;
+ TimesSungtot: Word);
+ end;
+ AStatResult = Array of TStatResult;
+
TDataBaseSystem = class
private
ScoreDB: TSqliteDatabase;
@@ -15,12 +35,17 @@ type
public
+ property Filename: String read sFilename;
+
Destructor Free;
Procedure Init(const Filename: string);
procedure ReadScore(var Song: TSong);
procedure AddScore(var Song: TSong; Level: integer; Name: string; Score: integer);
procedure WriteScore(var Song: TSong);
+
+ Function GetStats(var Stats: AStatResult; const Typ, Count: Byte; const Page: Cardinal; const Reversed: Boolean): Boolean;
+ Function GetTotalEntrys(const Typ: Byte): Cardinal;
end;
var
@@ -160,4 +185,110 @@ begin
end;
end;
+//--------------------
+//GetStats - Write some Stats to Array, Returns True if Chossen Page has Entrys
+//Case Typ of
+//0 - Best Scores
+//1 - Best Singers
+//2 - Most sung Songs
+//3 - Most popular Band
+//--------------------
+Function TDataBaseSystem.GetStats(var Stats: AStatResult; const Typ, Count: Byte; const Page: Cardinal; const Reversed: Boolean): Boolean;
+var
+ Query: String;
+ TableData: TSqliteTable;
+begin
+ Result := False;
+
+ if (Length(Stats) < Count) then
+ Exit;
+
+ {Todo:
+ Add Prevention that only Players with more than 5 Scores are Selected at Typ 2}
+
+ //Create Query
+ Case Typ of
+ 0: Query := 'SELECT `Player` , `Difficulty` , `Score` , `Artist` , `Title` FROM `US_Scores` INNER JOIN `US_Songs` ON (`SongID` = `ID`) ORDER BY `Score`';
+ 1: Query := 'SELECT `Player` , (Sum(`Score`) / COUNT(`Score`)) FROM `US_Scores` GROUP BY `Player` ORDER BY (Sum(`Score`) / COUNT(`Score`))';
+ 2: Query := 'SELECT `Artist` , `Title` , `TimesPlayed` FROM `US_Songs` ORDER BY `TimesPlayed`';
+ 3: Query := 'SELECT `Artist` , Sum(`TimesPlayed`) FROM `US_Songs` GROUP BY `Artist` ORDER BY Sum(`TimesPlayed`)';
+ end;
+
+ //Add Order Direction
+ If Reversed then
+ Query := Query + ' ASC'
+ else
+ Query := Query + ' DESC';
+
+ //Add Limit
+ Query := Query + ' LIMIT ' + InttoStr(Count * Page) + ', ' + InttoStr(Count) + ';';
+
+ //Execute Query
+ //try
+ TableData := ScoreDB.GetTable(Query);
+ {except
+ exit;
+ end;}
+
+ //if Result empty -> Exit
+ if (TableData.RowCount < 1) then
+ exit;
+
+ //Copy Result to Stats Array
+ while not TableData.Eof do
+ begin
+ Stats[TableData.Row].Typ := Typ;
+
+ Case Typ of
+ 0:begin
+ Stats[TableData.Row].Singer := TableData.Fields[0];
+
+ Stats[TableData.Row].Difficulty := StrtoIntDef(TableData.Fields[1], 0);
+
+ Stats[TableData.Row].Score := StrtoIntDef(TableData.Fields[2], 0){TableData.FieldAsInteger(2)};
+ Stats[TableData.Row].SongArtist := TableData.Fields[3];
+ Stats[TableData.Row].SongTitle := TableData.Fields[4];
+ end;
+
+ 1:begin
+ Stats[TableData.Row].Player := TableData.Fields[0];
+ Stats[TableData.Row].AverageScore := TableData.FieldAsInteger(1);
+ end;
+
+ 2:begin
+ Stats[TableData.Row].Artist := TableData.Fields[0];
+ Stats[TableData.Row].Title := TableData.Fields[1];
+ Stats[TableData.Row].TimesSung := StrtoIntDef(TableData.Fields[2], 0);
+ end;
+
+ 3:begin
+ Stats[TableData.Row].ArtistName := TableData.Fields[0];
+ Stats[TableData.Row].TimesSungtot := StrtoIntDef(TableData.Fields[1], 0);
+ end;
+
+ end;
+
+ TableData.Next;
+ end;
+
+ Result := True;
+end;
+
+//--------------------
+//GetTotalEntrys - Get Total Num of entrys for a Stats Query
+//--------------------
+Function TDataBaseSystem.GetTotalEntrys(const Typ: Byte): Cardinal;
+var Query: String;
+begin
+ //Create Query
+ Case Typ of
+ 0: Query := 'SELECT COUNT(`SongID`) FROM `US_Scores`;';
+ 1: Query := 'SELECT COUNT(DISTINCT `Player`) FROM `US_Scores`;';
+ 2: Query := 'SELECT COUNT(`ID`) FROM `US_Songs`;';
+ 3: Query := 'SELECT COUNT(DISTINCT `Artist`) FROM `US_Songs`;';
+ end;
+
+ Result := ScoreDB.GetTableValue(Query);
+end;
+
end.
diff --git a/Game/Code/Classes/UGraphic.pas b/Game/Code/Classes/UGraphic.pas
index b909e49f..342efe3c 100644
--- a/Game/Code/Classes/UGraphic.pas
+++ b/Game/Code/Classes/UGraphic.pas
@@ -7,7 +7,8 @@ uses
UScreenOptionsGraphics, UScreenOptionsSound, UScreenOptionsLyrics, UScreenOptionsThemes, UScreenOptionsRecord, UScreenOptionsAdvanced,
UScreenSong, UScreenSing, UScreenScore, UScreenTop5, UScreenEditSub,
UScreenEdit, UScreenEditConvert, UScreenEditHeader, UScreenOpen, UThemes, USkins, UScreenSongMenu, UScreenSongJumpto,
- {Party Screens} UScreenSingModi, UScreenPartyNewRound, UScreenPartyScore, UScreenPartyOptions, UScreenPartyWin, UScreenPartyPlayer;
+ {Party Screens} UScreenSingModi, UScreenPartyNewRound, UScreenPartyScore, UScreenPartyOptions, UScreenPartyWin, UScreenPartyPlayer,
+ {Stats Screens} UScreenStatMain, UScreenStatDetail;
type
TRecR = record
@@ -62,6 +63,10 @@ var
ScreenPartyOptions: TScreenPartyOptions;
ScreenPartyPlayer: TScreenPartyPlayer;
+ //StatsScreens
+ ScreenStatMain: TScreenStatMain;
+ ScreenStatDetail: TScreenStatDetail;
+
Tex_Left: array[0..6] of TTexture;
Tex_Mid: array[0..6] of TTexture;
@@ -221,20 +226,27 @@ var
Icon: TIcon;
Res: TResourceStream;
ISurface: PSDL_Surface;
+ Pixel: PByteArray;
begin
Log.LogStatus('LoadOpenGL', 'Initialize3D');
Log.BenchmarkStart(2);
LoadOpenGL;
- {//Load Icon
+ Log.LogStatus('SDL_Init', 'Initialize3D');
+ if ( SDL_Init(SDL_INIT_VIDEO or SDL_INIT_AUDIO)= -1 ) then begin
+ Log.LogError('SDL_Init Failed', 'Initialize3D');
+ exit;
+ end;
+
+ { //Load Icon
Res := TResourceStream.CreateFromID(HInstance, 3, RT_ICON);
Icon := TIcon.Create;
Icon.LoadFromStream(Res);
Res.Free;
-
+ Icon.
//Create icon Surface
- SDL_CreateRGBSurface (
+ SDL_CreateRGBSurfaceFrom (
SDL_SWSURFACE,
Icon.Width,
Icon.Height,
@@ -243,18 +255,12 @@ begin
32 or 16,
8 or 4,
2 or 1);
- SDL_BlitSurface( //}
-
+ //SDL_BlitSurface(
- SDL_WM_SetIcon(SDL_LoadBMP('us.ico'), 0); //}
- Log.LogStatus('SDL_Init', 'Initialize3D');
- if ( SDL_Init(SDL_INIT_VIDEO or SDL_INIT_AUDIO)= -1 ) then begin
- Log.LogError('SDL_Init Failed', 'Initialize3D');
- exit;
- end;
+ SDL_WM_SetIcon(SDL_LoadBMP('DEFAULT_WINDOW_ICON'), 0); //}
- SDL_WM_SetCaption(PChar(Title), 'WM_DEFAULT');
+ SDL_WM_SetCaption(PChar(Title), nil);
InitializeScreen;
@@ -433,6 +439,10 @@ begin
Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyOptions', 3); Log.BenchmarkStart(3);
ScreenPartyPlayer := TScreenPartyPlayer.Create;
Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyPlayer', 3); Log.BenchmarkStart(3);
+ ScreenStatMain := TScreenStatMain.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Main', 3); Log.BenchmarkStart(3);
+ ScreenStatDetail := TScreenStatDetail.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Detail', 3); Log.BenchmarkStart(3);
end;
end.
diff --git a/Game/Code/Classes/UThemes.pas b/Game/Code/Classes/UThemes.pas
index 5aca1401..4f4ab2b9 100644
--- a/Game/Code/Classes/UThemes.pas
+++ b/Game/Code/Classes/UThemes.pas
@@ -570,10 +570,15 @@ type
ButtonPrev: TThemeButton;
ButtonReverse: TThemeButton;
ButtonExit: TThemeButton;
-
- Description: array[0..3] of string;
+
TextDescription: TThemeText;
+ TextPage: TThemeText;
TextList: AThemeText;
+
+ Description: array[0..3] of string;
+ DescriptionR: array[0..3] of string;
+ FormatStr: array[0..3] of string;
+ PageStr: String;
end;
//Playlist Translations
@@ -620,6 +625,8 @@ type
Playlist: TThemePlaylist;
+ ILevel: array[0..2] of String;
+
constructor Create(FileName: string); overload; // Initialize theme system
constructor Create(FileName: string; Color: integer); overload; // Initialize theme system with color
function LoadTheme(FileName: string; sColor: integer): boolean; // Load some theme settings from file
@@ -1242,15 +1249,35 @@ begin
ThemeLoadButton(StatDetail.ButtonExit, 'StatDetailButtonExit');
ThemeLoadText (StatDetail.TextDescription, 'StatDetailTextDescription');
+ ThemeLoadText (StatDetail.TextPage, 'StatDetailTextPage');
ThemeLoadTexts(StatDetail.TextList, 'StatDetailTextList');
+ //Translate Texts
StatDetail.Description[0] := Language.Translate('STAT_DESC_SCORES');
StatDetail.Description[1] := Language.Translate('STAT_DESC_SINGERS');
StatDetail.Description[2] := Language.Translate('STAT_DESC_SONGS');
StatDetail.Description[3] := Language.Translate('STAT_DESC_BANDS');
+ StatDetail.DescriptionR[0] := Language.Translate('STAT_DESC_SCORES_REVERSED');
+ StatDetail.DescriptionR[1] := Language.Translate('STAT_DESC_SINGERS_REVERSED');
+ StatDetail.DescriptionR[2] := Language.Translate('STAT_DESC_SONGS_REVERSED');
+ StatDetail.DescriptionR[3] := Language.Translate('STAT_DESC_BANDS_REVERSED');
+
+ StatDetail.FormatStr[0] := Language.Translate('STAT_FORMAT_SCORES');
+ StatDetail.FormatStr[1] := Language.Translate('STAT_FORMAT_SINGERS');
+ StatDetail.FormatStr[2] := Language.Translate('STAT_FORMAT_SONGS');
+ StatDetail.FormatStr[3] := Language.Translate('STAT_FORMAT_BANDS');
+
+ StatDetail.PageStr := Language.Translate('STAT_PAGE');
+
//Playlist Translations
- Playlist.CatText := Language.Translate('PLAYLIST_CATTEXT')
+ Playlist.CatText := Language.Translate('PLAYLIST_CATTEXT');
+
+ //Level Translations
+ //Fill ILevel
+ ILevel[0] := Language.Translate('SING_EASY');
+ ILevel[1] := Language.Translate('SING_MEDIUM');
+ ILevel[2] := Language.Translate('SING_HARD');
end;
ThemeIni.Free;
diff --git a/Game/Code/Menu/UMenuText.pas b/Game/Code/Menu/UMenuText.pas
index 55f84bf8..65034f1d 100644
--- a/Game/Code/Menu/UMenuText.pas
+++ b/Game/Code/Menu/UMenuText.pas
@@ -114,13 +114,13 @@ begin
end;
I := 0;
- // /n Hack
+ // \n Hack
While (I <= High(TextTiles)) do
begin
- LastPos := Pos ('/n', TextTiles[I]);
+ LastPos := Pos ('\n', TextTiles[I]);
if (LastPos = 0) then //No /n Tags -> Search in next Tile
Inc(I)
- else //Found /n Tag -> Create a Break
+ else //Found \n Tag -> Create a Break
begin
//Add a new Tile and move all Tiles behind actual Tile to the right
L := Length(TextTiles);
diff --git a/Game/Code/Screens/UScreenMain.pas b/Game/Code/Screens/UScreenMain.pas
index dd7f21c5..8d2d13b6 100644
--- a/Game/Code/Screens/UScreenMain.pas
+++ b/Game/Code/Screens/UScreenMain.pas
@@ -135,6 +135,12 @@ begin
end;
end;
+ SDLK_S:
+ begin
+ Music.PlayStart;
+ FadeTo(@ScreenStatMain);
+ end;
+
SDLK_RETURN:
begin
if (Interaction = 0) and (Length(Songs.Song) >= 1) then begin
diff --git a/Game/Code/Screens/UScreenPartyOptions.pas b/Game/Code/Screens/UScreenPartyOptions.pas
index 1fd4da8f..fd7b5107 100644
--- a/Game/Code/Screens/UScreenPartyOptions.pas
+++ b/Game/Code/Screens/UScreenPartyOptions.pas
@@ -31,7 +31,6 @@ type
end;
var
- ILevel: array[0..2] of String;
IPlaylist: array[0..2] of String;
IPlaylist2: array of String;
const
@@ -185,12 +184,6 @@ var
I: integer;
begin
inherited Create;
-
- //Fill ILevel
- ILevel[0] := Language.Translate('SING_EASY');
- ILevel[1] := Language.Translate('SING_MEDIUM');
- ILevel[2] := Language.Translate('SING_HARD');
-
//Fill IPlaylist
IPlaylist[0] := Language.Translate('PARTY_PLAYLIST_ALL');
IPlaylist[1] := Language.Translate('PARTY_PLAYLIST_CATEGORY');
@@ -210,7 +203,7 @@ begin
AddBackground(Theme.PartyOptions.Background.Tex);
- SelectLevel := AddSelectSlide (Theme.PartyOptions.SelectLevel, Ini.Difficulty, ILevel);
+ SelectLevel := AddSelectSlide (Theme.PartyOptions.SelectLevel, Ini.Difficulty, Theme.ILevel);
SelectPlayList := AddSelectSlide (Theme.PartyOptions.SelectPlayList, PlayList, IPlaylist);
SelectPlayList2 := AddSelectSlide (Theme.PartyOptions.SelectPlayList2, PlayList2, IPlaylist2);
SelectRounds := AddSelectSlide (Theme.PartyOptions.SelectRounds, Rounds, IRounds);
diff --git a/Game/Code/Screens/UScreenStatDetail.pas b/Game/Code/Screens/UScreenStatDetail.pas
new file mode 100644
index 00000000..dc4a0f1f
--- /dev/null
+++ b/Game/Code/Screens/UScreenStatDetail.pas
@@ -0,0 +1,254 @@
+unit UScreenStatDetail;
+
+interface
+
+uses
+ UMenu, SDL, SysUtils, UDisplay, UMusic, UIni, UThemes;
+
+type
+ TScreenStatDetail = class(TMenu)
+ public
+ Typ: Byte;
+ Page: CardinaL;
+ Count: Byte;
+ Reversed: Boolean;
+
+ TotEntrys: Cardinal;
+ TotPages: Cardinal;
+
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+
+ procedure SetTitle;
+ Procedure SetPage(NewPage: Cardinal);
+ end;
+
+implementation
+
+{Stat Screens:
+ 0 - Best Scores
+ 1 - Best Singers
+ 2 - Most sung Songs
+ 3 - Most popular Band
+}
+
+uses UGraphic, UDataBase, ULanguage, math, ULog;
+
+function TScreenStatDetail.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+ SDLK_ESCAPE:
+ begin
+ Music.PlayBack;
+ FadeTo(@ScreenStatMain);
+ end;
+ SDLK_RETURN:
+ begin
+ if Interaction = 0 then begin
+ //Next Page
+ SetPage(Page+1);
+ end;
+
+ if Interaction = 1 then begin
+ //Previous Page
+ if (Page > 0) then
+ SetPage(Page-1);
+ end;
+
+ if Interaction = 2 then begin
+ //Reverse Order
+ Reversed := not Reversed;
+ SetPage(Page);
+ end;
+
+ if Interaction = 3 then begin
+ Music.PlayBack;
+ FadeTo(@ScreenStatMain);
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ InteractPrev;
+ end;
+ SDLK_RIGHT:
+ begin
+ InteractNext;
+ end;
+ SDLK_UP:
+ begin
+ InteractPrev;
+ end;
+ SDLK_DOWN:
+ begin
+ InteractNext;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenStatDetail.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ AddBackground(Theme.StatDetail.Background.Tex);
+
+ AddButton(Theme.StatDetail.ButtonNext);
+ if (Length(Button[0].Text)=0) then
+ AddButtonText(14, 20, Language.Translate('STAT_NEXT'));
+
+ AddButton(Theme.StatDetail.ButtonPrev);
+ if (Length(Button[1].Text)=0) then
+ AddButtonText(14, 20, Language.Translate('STAT_PREV'));
+
+ AddButton(Theme.StatDetail.ButtonReverse);
+ if (Length(Button[2].Text)=0) then
+ AddButtonText(14, 20, Language.Translate('STAT_REVERSE'));
+
+ AddButton(Theme.StatDetail.ButtonExit);
+ if (Length(Button[3].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[7]);
+
+ for I := 0 to High(Theme.StatDetail.TextList) do
+ AddText(Theme.StatDetail.TextList[I]);
+
+ Count := Length(Theme.StatDetail.TextList);
+
+ AddText(Theme.StatDetail.TextDescription);
+ AddText(Theme.StatDetail.TextPage);
+
+ for I := 0 to High(Theme.StatDetail.Static) do
+ AddStatic(Theme.StatDetail.Static[I]);
+
+ for I := 0 to High(Theme.StatDetail.Text) do
+ AddText(Theme.StatDetail.Text[I]);
+
+
+
+ Interaction := 0;
+ Typ := 0;
+end;
+
+procedure TScreenStatDetail.onShow;
+begin
+ //Set Tot Entrys and PAges
+ TotEntrys := DataBase.GetTotalEntrys(Typ);
+ TotPages := Ceil(TotEntrys / Count);
+ //Show correct Title
+ SetTitle;
+ //Show First Page
+ Reversed := False;
+ SetPage(0);
+end;
+
+procedure TScreenStatDetail.SetTitle;
+begin
+ //Set Title
+ Case Reversed of
+ True: Text[Count].Text := Theme.StatDetail.DescriptionR[Typ];
+ False: Text[Count].Text := Theme.StatDetail.Description[Typ];
+ end;
+end;
+
+Procedure TScreenStatDetail.SetPage(NewPage: Cardinal);
+var
+ Result: AStatResult;
+ I: Integer;
+ FormatStr: String;
+ PerPage: Byte;
+begin
+ SetLength(Result, Count);
+ if (Database.GetStats(Result, Typ, Count, NewPage, Reversed)) then
+ begin
+ Page := NewPage;
+
+ FormatStr := Theme.StatDetail.FormatStr[Typ];
+
+ //refresh Texts
+ For I := 0 to Count-1 do
+ begin
+ try
+ case Typ of
+ 0:begin //Best Scores
+ //Set Texts
+ if (Result[I].Score>0) then
+ Text[I].Text := Format(FormatStr, [Result[I].Singer,
+ Result[I].Score,
+ Theme.ILevel[Result[I].Difficulty],
+ Result[I].SongArtist,
+ Result[I].SongTitle])
+ else
+ Text[I].Text := '';
+ end;
+
+ 1:begin //Best Singers
+ //Set Texts
+ if (Result[I].AverageScore>0) then
+ Text[I].Text := Format(FormatStr, [Result[I].Player,
+ Result[I].AverageScore])
+ else
+ Text[I].Text := '';
+ end;
+
+ 2:begin //Popular Songs
+ //Set Texts
+ if (Result[I].Artist<>'') then
+ Text[I].Text := Format(FormatStr, [Result[I].Artist,
+ Result[I].Title,
+ Result[I].TimesSung])
+ else
+ Text[I].Text := '';
+ end;
+
+ 3:begin //Popular Bands
+ //Set Texts
+ if (Result[I].ArtistName<>'') then
+ Text[I].Text := Format(FormatStr, [Result[I].ArtistName,
+ Result[I].TimesSungtot])
+ else
+ Text[I].Text := '';
+ end;
+ end;
+ except
+ on E: EConvertError do
+ Log.LogError('Error Parsing FormatString in UScreenStatDetail: ' + E.Message);
+ end;
+ end;
+
+ if (Page + 1 = TotPages) AND (TotEntrys Mod Count <> 0) then
+ PerPage := (TotEntrys Mod Count)
+ else
+ PerPage := Count;
+
+ Text[Count+1].Text := Format(Theme.StatDetail.PageStr, [Page + 1,
+ TotPages,
+ PerPage,
+ TotEntrys]);
+
+ //Show correct Title
+ SetTitle;
+
+ end;
+
+end;
+
+
+procedure TScreenStatDetail.SetAnimationProgress(Progress: real);
+var I: Integer;
+begin
+ For I := 0 to high(Button) do
+ Button[I].Texture.ScaleW := Progress;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenStatMain.pas b/Game/Code/Screens/UScreenStatMain.pas
new file mode 100644
index 00000000..337ed745
--- /dev/null
+++ b/Game/Code/Screens/UScreenStatMain.pas
@@ -0,0 +1,229 @@
+unit UScreenStatMain;
+
+interface
+
+uses
+ UMenu, SDL, SysUtils, UDisplay, UMusic, UIni, UThemes;
+
+type
+ TScreenStatMain = class(TMenu)
+ private
+ //Some Stat Value that don't need to be calculated 2 times
+ SongswithVid: Cardinal;
+ public
+ TextOverview: integer;
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+
+ procedure SetOverview;
+ end;
+
+implementation
+
+uses UGraphic, UDataBase, USongs, ULanguage, windows, ULog;
+
+function TScreenStatMain.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+ SDLK_ESCAPE:
+ begin
+ Ini.Save;
+ Music.PlayBack;
+ FadeTo(@ScreenMain);
+ end;
+ SDLK_RETURN:
+ begin
+ //Exit Button Pressed
+ if Interaction = 4 then begin
+ Music.PlayBack;
+ FadeTo(@ScreenMain);
+ end
+ else //One of the Stats Buttons Pressed
+ begin
+ Music.PlayBack;
+ ScreenStatDetail.Typ := Interaction;
+ FadeTo(@ScreenStatDetail);
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ InteractPrev;
+ end;
+ SDLK_RIGHT:
+ begin
+ InteractNext;
+ end;
+ SDLK_UP:
+ begin
+ InteractPrev;
+ end;
+ SDLK_DOWN:
+ begin
+ InteractNext;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenStatMain.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ AddBackground(Theme.StatMain.Background.Tex);
+
+ AddButton(Theme.StatMain.ButtonScores);
+ if (Length(Button[0].Text)=0) then
+ AddButtonText(14, 20, Theme.StatDetail.Description[0]);
+
+ AddButton(Theme.StatMain.ButtonSingers);
+ if (Length(Button[1].Text)=0) then
+ AddButtonText(14, 20, Theme.StatDetail.Description[1]);
+
+ AddButton(Theme.StatMain.ButtonSongs);
+ if (Length(Button[2].Text)=0) then
+ AddButtonText(14, 20, Theme.StatDetail.Description[2]);
+
+ AddButton(Theme.StatMain.ButtonBands);
+ if (Length(Button[3].Text)=0) then
+ AddButtonText(14, 20, Theme.StatDetail.Description[3]);
+
+ AddButton(Theme.StatMain.ButtonExit);
+ if (Length(Button[4].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[4]);
+
+ TextOverview := AddText(Theme.StatMain.TextOverview);
+
+ for I := 0 to High(Theme.StatMain.Static) do
+ AddStatic(Theme.StatMain.Static[I]);
+
+ for I := 0 to High(Theme.StatMain.Text) do
+ AddText(Theme.StatMain.Text[I]);
+
+ Interaction := 0;
+
+ SongswithVid := 0;
+ For I := 0 to high(Songs.Song) do
+ if (Songs.Song[I].Video <> '') AND FileExists(Songs.Song[I].Path + Songs.Song[I].Video) then
+ Inc(SongswithVid);
+end;
+
+procedure TScreenStatMain.onShow;
+begin
+ //Set Overview Text:
+ SetOverview;
+end;
+
+procedure TScreenStatMain.SetOverview;
+var
+ Overview, Formatstr: String;
+ I: Integer;
+ //Some Vars to Save Attributes to
+ A1, A2, A3: Integer;
+ A4, A5: String;
+ Result1, Result2: AStatResult;
+ ResetTime: TSystemTime;
+ function GetFileCreation(Filename: String): TSystemTime;
+ var
+ FindData: TWin32FindData;
+ Handle: THandle;
+ begin
+ Handle := FindFirstFile(PChar(Filename), FindData);
+ if Handle <> INVALID_HANDLE_VALUE then
+ begin
+ FileTimeToSystemTime(FindData.ftCreationTime, Result);
+ Windows.FindClose(Handle);
+ end;
+ end;
+begin
+ //Song Overview
+
+ //Introduction
+ Formatstr := Language.Translate ('STAT_OVERVIEW_INTRO');
+ {Format:
+ %0:d Ultrastar Version
+ %1:d Day of Reset (A1)
+ %2:d Month of Reset (A2)
+ %3:d Year of Reset (A3)}
+
+ ResetTime := GetFileCreation(Database.Filename);
+
+ A1 := ResetTime.wDay;
+ A2 := ResetTime.wMonth;
+ A3 := ResetTime.wYear;
+ try
+ Overview := Format(Formatstr, [Language.Translate('US_VERSION'), A1, A2, A3]);
+ except
+ on E: EConvertError do
+ Log.LogError('Error Parsing FormatString "STAT_OVERVIEW_INTRO": ' + E.Message);
+ end;
+
+ Formatstr := Language.Translate ('STAT_OVERVIEW_SONG');
+ {Format:
+ %0:d Count Songs (A1)
+ %1:d Count of Sung Songs (A2)
+ %2:d Count of UnSung Songs
+ %3:d Count of Songs with Video (A3)
+ %4:s Name of the most popular Song}
+ A1 := Length(CatSongs.Song);
+ A2 := Database.GetTotalEntrys(2);
+
+ A3 := SongswithVid;
+
+ SetLength(Result1, 1);
+ Database.GetStats(Result1, 2, 1, 0, False);
+ A4 := Result1[0].Artist;
+ A5 := Result1[0].Title;
+
+ try
+ Overview := Overview + '\n \n' + Format(Formatstr, [A1, A2, A1-A2, A3, A4, A5]);
+ except
+ on E: EConvertError do
+ Log.LogError('Error Parsing FormatString "STAT_OVERVIEW_SONG": ' + E.Message);
+ end;
+
+ //Player Overview
+ Formatstr := Language.Translate ('STAT_OVERVIEW_PLAYER');
+ {Format:
+ %0:d Count Players (A1)
+ %1:s Best Player (Result)
+ %2:d Best Players Score
+ %3:s Best Score Player (Result2)
+ %4:d Best Score}
+ A1 := Database.GetTotalEntrys(1);
+
+ SetLength(Result1, 1);
+ Database.GetStats(Result1, 1, 1, 0, False);
+
+ SetLength(Result2, 1);
+ Database.GetStats(Result2, 0, 1, 0, False);
+
+ try
+ Overview := Overview + '\n \n' + Format(Formatstr, [A1, Result1[0].Player, Result1[0].AverageScore, Result2[0].Singer, Result2[0].Score]);
+ except
+ on E: EConvertError do
+ Log.LogError('Error Parsing FormatString "STAT_OVERVIEW_PLAYER": ' + E.Message);
+ end;
+
+ Text[0].Text := Overview;
+end;
+
+
+procedure TScreenStatMain.SetAnimationProgress(Progress: real);
+var I: Integer;
+begin
+ For I := 0 to high(Button) do
+ Button[I].Texture.ScaleW := Progress;
+end;
+
+end. \ No newline at end of file
diff --git a/Game/Code/UltraStar.dpr b/Game/Code/UltraStar.dpr
index fc1fa8a2..d5418e04 100644
--- a/Game/Code/UltraStar.dpr
+++ b/Game/Code/UltraStar.dpr
@@ -78,6 +78,8 @@ uses
UScreenTop5 in 'Screens\UScreenTop5.pas',
UScreenSongMenu in 'Screens\UScreenSongMenu.pas',
UScreenSongJumpto in 'Screens\UScreenSongJumpto.pas',
+ UScreenStatMain in 'Screens\UScreenStatMain.pas',
+ UScreenStatDetail in 'Screens\UScreenStatDetail.pas',
//------------------------------
//Includes - Screens PartyMode
@@ -103,7 +105,7 @@ uses
const
- Version = 'UltraStar Deluxe V 0.95 Beta';
+ Version = 'UltraStar Deluxe V 0.96 Beta';
var
WndTitle: string;