aboutsummaryrefslogtreecommitdiffstats
path: root/Game/Code/Screens
diff options
context:
space:
mode:
authortobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c>2008-06-08 15:33:48 +0000
committertobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c>2008-06-08 15:33:48 +0000
commit46bb010ca7c5eb04551c030105f9999ca80e472f (patch)
tree3cb6a6bdd7e4e62623c6a83b5d22c1c0dfad73e8 /Game/Code/Screens
parentf4425b4558b7fd86de874035f81ea290c987e96d (diff)
downloadusdx-46bb010ca7c5eb04551c030105f9999ca80e472f.tar.gz
usdx-46bb010ca7c5eb04551c030105f9999ca80e472f.tar.xz
usdx-46bb010ca7c5eb04551c030105f9999ca80e472f.zip
- set svn:eol-style to native
- removed some svn:executable properties from non-executable files git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1144 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to '')
-rw-r--r--Game/Code/Screens/UScreenEdit.pas242
-rw-r--r--Game/Code/Screens/UScreenEditHeader.pas760
-rw-r--r--Game/Code/Screens/UScreenName.pas486
-rw-r--r--Game/Code/Screens/UScreenOpen.pas346
-rw-r--r--Game/Code/Screens/UScreenOptionsGraphics.pas214
-rw-r--r--Game/Code/Screens/UScreenOptionsLyrics.pas204
-rw-r--r--Game/Code/Screens/UScreenOptionsRecord.pas1512
-rw-r--r--Game/Code/Screens/UScreenPartyPlayer.pas6
-rw-r--r--Game/Code/Screens/UScreenPartyScore.pas604
-rw-r--r--Game/Code/Screens/UScreenPopup.pas504
-rw-r--r--Game/Code/Screens/UScreenScore.pas1674
-rw-r--r--Game/Code/Screens/UScreenSing.pas2878
-rw-r--r--Game/Code/Screens/UScreenSingModi.pas10
-rw-r--r--Game/Code/Screens/UScreenSong.pas4260
-rw-r--r--Game/Code/Screens/UScreenStatDetail.pas514
-rw-r--r--Game/Code/Screens/UScreenWelcome.pas244
16 files changed, 7229 insertions, 7229 deletions
diff --git a/Game/Code/Screens/UScreenEdit.pas b/Game/Code/Screens/UScreenEdit.pas
index 492191ee..bf664eb1 100644
--- a/Game/Code/Screens/UScreenEdit.pas
+++ b/Game/Code/Screens/UScreenEdit.pas
@@ -1,121 +1,121 @@
-unit UScreenEdit;
-
-interface
-
-{$I switches.inc}
-
-uses UMenu, SDL, UThemes;
-
-type
- TScreenEdit = class(TMenu)
- public
-{ Tex_Background: TTexture;
- FadeOut: boolean;
- Path: string;
- FileName: string;}
- constructor Create; override;
- procedure onShow; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
-{ function Draw: boolean; override;
- procedure Finish;}
- end;
-
-implementation
-
-uses UGraphic, UMusic, USkins, SysUtils;
-
-function TScreenEdit.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenMain);
-// Result := false;
- end;
- SDLK_RETURN:
- begin
- if Interaction = 0 then
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- FadeTo(@ScreenEditConvert);
- end;
-// if Interaction = 1 then begin
-// Music.PlayStart;
-// FadeTo(@ScreenEditHeader);
-// end;
-
- if Interaction = 1 then
- begin
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenMain);
- end;
- end;
-
- SDLK_DOWN:
- begin
- InteractNext;
- end;
- SDLK_UP:
- begin
- InteractPrev;
- end;
- end;
- end;
-end;
-
-constructor TScreenEdit.Create;
-begin
- inherited Create;
- AddButton(400-200, 100 + 0*70, 400, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(10, 5, 0, 0, 0, 'Convert Midi to Txt');
-// Button[High(Button)].Text[0].Size := 11;
-
-// AddButton(400-200, 100 + 1*60, 400, 40, 'ButtonF');
-// AddButtonText(10, 5, 0, 0, 0, 'Edit Headers');
-
-// AddButton(400-200, 100 + 2*60, 400, 40, 'ButtonF');
-// AddButtonText(10, 5, 0, 0, 0, 'Set GAP');
-
- AddButton(400-200, 100 + 3*60, 400, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(10, 5, 0, 0, 0, 'Exit');
-
-end;
-
-procedure TScreenEdit.onShow;
-begin
- inherited;
-
-// Interaction := 0;
-end;
-
-(*function TScreenEdit.Draw: boolean;
-var
- Min: integer;
- Sec: integer;
- Tekst: string;
- Pet: integer;
- AktBeat: integer;
-begin
-end;
-
-procedure TScreenEdit.Finish;
-begin
-//
-end;*)
-
-end.
+unit UScreenEdit;
+
+interface
+
+{$I switches.inc}
+
+uses UMenu, SDL, UThemes;
+
+type
+ TScreenEdit = class(TMenu)
+ public
+{ Tex_Background: TTexture;
+ FadeOut: boolean;
+ Path: string;
+ FileName: string;}
+ constructor Create; override;
+ procedure onShow; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+{ function Draw: boolean; override;
+ procedure Finish;}
+ end;
+
+implementation
+
+uses UGraphic, UMusic, USkins, SysUtils;
+
+function TScreenEdit.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenMain);
+// Result := false;
+ end;
+ SDLK_RETURN:
+ begin
+ if Interaction = 0 then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ FadeTo(@ScreenEditConvert);
+ end;
+// if Interaction = 1 then begin
+// Music.PlayStart;
+// FadeTo(@ScreenEditHeader);
+// end;
+
+ if Interaction = 1 then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenMain);
+ end;
+ end;
+
+ SDLK_DOWN:
+ begin
+ InteractNext;
+ end;
+ SDLK_UP:
+ begin
+ InteractPrev;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenEdit.Create;
+begin
+ inherited Create;
+ AddButton(400-200, 100 + 0*70, 400, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(10, 5, 0, 0, 0, 'Convert Midi to Txt');
+// Button[High(Button)].Text[0].Size := 11;
+
+// AddButton(400-200, 100 + 1*60, 400, 40, 'ButtonF');
+// AddButtonText(10, 5, 0, 0, 0, 'Edit Headers');
+
+// AddButton(400-200, 100 + 2*60, 400, 40, 'ButtonF');
+// AddButtonText(10, 5, 0, 0, 0, 'Set GAP');
+
+ AddButton(400-200, 100 + 3*60, 400, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(10, 5, 0, 0, 0, 'Exit');
+
+end;
+
+procedure TScreenEdit.onShow;
+begin
+ inherited;
+
+// Interaction := 0;
+end;
+
+(*function TScreenEdit.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ Pet: integer;
+ AktBeat: integer;
+begin
+end;
+
+procedure TScreenEdit.Finish;
+begin
+//
+end;*)
+
+end.
diff --git a/Game/Code/Screens/UScreenEditHeader.pas b/Game/Code/Screens/UScreenEditHeader.pas
index 2bba36cd..28bf7682 100644
--- a/Game/Code/Screens/UScreenEditHeader.pas
+++ b/Game/Code/Screens/UScreenEditHeader.pas
@@ -1,380 +1,380 @@
-unit UScreenEditHeader;
-
-interface
-
-{$I switches.inc}
-
-uses UMenu,
- SDL,
- USongs,
- USong,
- UThemes;
-
-type
- TScreenEditHeader = class(TMenu)
- public
- CurrentSong: TSong;
- TextTitle: integer;
- TextArtist: integer;
- TextMp3: integer;
- TextBackground: integer;
- TextVideo: integer;
- TextVideoGAP: integer;
- TextRelative: integer;
- TextResolution: integer;
- TextNotesGAP: integer;
- TextStart: integer;
- TextGAP: integer;
- TextBPM: integer;
- StaticTitle: integer;
- StaticArtist: integer;
- StaticMp3: integer;
- StaticBackground: integer;
- StaticVideo: integer;
- StaticVideoGAP: integer;
- StaticRelative: integer;
- StaticResolution: integer;
- StaticNotesGAP: integer;
- StaticStart: integer;
- StaticGAP: integer;
- StaticBPM: integer;
- Sel: array[0..11] of boolean;
- procedure SetRoundButtons;
-
- constructor Create; override;
- procedure onShow; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
-{ function Draw: boolean; override;
- procedure Finish;}
- end;
-
-implementation
-
-uses UGraphic, UMusic, SysUtils, UFiles, USkins, UTexture;
-
-function TScreenEditHeader.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-var
- T: integer;
-begin
- Result := true;
- If (PressedDown) Then begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE :
- begin
-// Music.PlayBack;
-// FadeTo(@MainScreen);
- Result := false;
- end;
-
- SDLK_RETURN:
- begin
- if Interaction = 1 then begin
-// Save;
- end;
- end;
-
- SDLK_RIGHT:
- begin
- case Interaction of
- 0..0: InteractNext;
- 1: Interaction := 0;
- end;
- end;
-
- SDLK_LEFT:
- begin
- case Interaction of
- 0: Interaction := 1;
- 1..1: InteractPrev;
- end;
- end;
-
- SDLK_DOWN:
- begin
- case Interaction of
- 0..1: Interaction := 2;
- 2..12: InteractNext;
- 13: Interaction := 0;
- end;
- end;
-
- SDLK_UP:
- begin
- case Interaction of
- 0..1: Interaction := 13;
- 2: Interaction := 0;
- 3..13: InteractPrev;
- end;
- end;
-
- SDLK_BACKSPACE:
- begin
- T := Interaction - 2 + TextTitle;
- if (Interaction >= 2) and (Interaction <= 13) and (Length(Text[T].Text) >= 1) then begin
- Text[T].DeleteLastL;
- SetRoundButtons;
- end;
- end;
-
- end;
- case CharCode of
- #32..#255:
- begin
- if (Interaction >= 2) and (Interaction <= 13) then begin
- Text[Interaction - 2 + TextTitle].Text :=
- Text[Interaction - 2 + TextTitle].Text + CharCode;
- SetRoundButtons;
- end;
- end;
- end;
- end;
-end;
-
-constructor TScreenEditHeader.Create;
-begin
- inherited Create;
-
- AddButton(40, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(15, 5, 'Open');
-
- AddButton(160, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(20, 5, 'Save');
-
- AddBox(80, 60, 640, 550);
-
- AddText(160, 110 + 0*30, 0, 10, 0, 0, 0, 'Title:');
- AddText(160, 110 + 1*30, 0, 10, 0, 0, 0, 'Artist:');
- AddText(160, 110 + 2*30, 0, 10, 0, 0, 0, 'MP3:');
-
- AddText(160, 110 + 4*30, 0, 10, 0, 0, 0, 'Background:');
- AddText(160, 110 + 5*30, 0, 10, 0, 0, 0, 'Video:');
- AddText(160, 110 + 6*30, 0, 10, 0, 0, 0, 'VideoGAP:');
-
- AddText(160, 110 + 8*30, 0, 10, 0, 0, 0, 'Relative:');
- AddText(160, 110 + 9*30, 0, 10, 0, 0, 0, 'Resolution:');
- AddText(160, 110 + 10*30, 0, 10, 0, 0, 0, 'NotesGAP:');
-
- AddText(160, 110 + 12*30, 0, 10, 0, 0, 0, 'Start:');
- AddText(160, 110 + 13*30, 0, 10, 0, 0, 0, 'GAP:');
- AddText(160, 110 + 14*30, 0, 10, 0, 0, 0, 'BPM:');
-
- TextTitle := AddText(340, 110 + 0*30, 0, 10, 0, 0, 0, '');
- TextArtist := AddText(340, 110 + 1*30, 0, 10, 0, 0, 0, '');
- TextMp3 := AddText(340, 110 + 2*30, 0, 10, 0, 0, 0, '');
-
- TextBackground := AddText(340, 110 + 4*30, 0, 10, 0, 0, 0, '');
- TextVideo := AddText(340, 110 + 5*30, 0, 10, 0, 0, 0, '');
- TextVideoGAP := AddText(340, 110 + 6*30, 0, 10, 0, 0, 0, '');
-
- TextRelative := AddText(340, 110 + 8*30, 0, 10, 0, 0, 0, '');
- TextResolution := AddText(340, 110 + 9*30, 0, 10, 0, 0, 0, '');
- TextNotesGAP := AddText(340, 110 + 10*30, 0, 10, 0, 0, 0, '');
-
- TextStart := AddText(340, 110 + 12*30, 0, 10, 0, 0, 0, '');
- TextGAP := AddText(340, 110 + 13*30, 0, 10, 0, 0, 0, '');
- TextBPM := AddText(340, 110 + 14*30, 0, 10, 0, 0, 0, '');
-
- StaticTitle := AddStatic(130, 115 + 0*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticArtist := AddStatic(130, 115 + 1*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticMp3 := AddStatic(130, 115 + 2*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticBackground := AddStatic(130, 115 + 4*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticVideo := AddStatic(130, 115 + 5*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticVideoGAP := AddStatic(130, 115 + 6*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticRelative := AddStatic(130, 115 + 8*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticResolution := AddStatic(130, 115 + 9*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticNotesGAP := AddStatic(130, 115 + 10*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticStart := AddStatic(130, 115 + 12*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticGAP := AddStatic(130, 115 + 13*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
- StaticBPM := AddStatic(130, 115 + 14*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
-
- AddInteraction(iText, TextTitle);
- AddInteraction(iText, TextArtist);
- AddInteraction(iText, TextMp3);
- AddInteraction(iText, TextBackground);
- AddInteraction(iText, TextVideo);
- AddInteraction(iText, TextVideoGAP);
- AddInteraction(iText, TextRelative);
- AddInteraction(iText, TextResolution);
- AddInteraction(iText, TextNotesGAP);
- AddInteraction(iText, TextStart);
- AddInteraction(iText, TextGAP);
- AddInteraction(iText, TextBPM);
-end;
-
-procedure TScreenEditHeader.onShow;
-begin
- inherited;
-
-{ if FileExists(FileName) then begin // load file
- CurrentSong.FileName := FileName;
- SkanujPlik(CurrentSong);
-
- SetLength(TrueBoolStrs, 1);
- TrueBoolStrs[0] := 'yes';
- SetLength(FalseBoolStrs, 1);
- FalseBoolStrs[0] := 'no';
-
- Text[TextTitle].Text := CurrentSong.Title;
- Text[TextArtist].Text := CurrentSong.Artist;
- Text[TextMP3].Text := CurrentSong.Mp3;
- Text[TextBackground].Text := CurrentSong.Background;
- Text[TextVideo].Text := CurrentSong.Video;
- Text[TextVideoGAP].Text := FloatToStr(CurrentSong.VideoGAP);
- Text[TextRelative].Text := BoolToStr(CurrentSong.Relative, true);
- Text[TextResolution].Text := IntToStr(CurrentSong.Resolution);
- Text[TextNotesGAP].Text := IntToStr(CurrentSong.NotesGAP);
- Text[TextStart].Text := FloatToStr(CurrentSong.Start);
- Text[TextGAP].Text := FloatToStr(CurrentSong.GAP);
- Text[TextBPM].Text := FloatToStr(CurrentSong.BPM[0].BPM);
- SetRoundButtons;
- end;}
-
- Interaction := 0;
-end;
-
-(*function TScreenEdit.Draw: boolean;
-var
- Min: integer;
- Sec: integer;
- Tekst: string;
- Pet: integer;
- AktBeat: integer;
-begin
-{ glClearColor(1,1,1,1);
-
- // control music
- if PlaySentence then begin
- // stop the music
- if (Music.Position > PlayStopTime) then begin
- Music.Stop;
- PlaySentence := false;
- end;
-
- // click
- if (Click) and (PlaySentence) then begin
- AktBeat := Floor(CurrentSong.BPM[0].BPM * (Music.Position - CurrentSong.GAP / 1000) / 60);
- Text[TextDebug].Text := IntToStr(AktBeat);
- if AktBeat <> LastClick then begin
- for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
- if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then begin
- Music.PlayClick;
- LastClick := AktBeat;
- end;
- end;
- end; // click
- end; // if PlaySentence
-
- Text[TextSentence].Text := IntToStr(Czesci[0].Akt + 1) + ' / ' + IntToStr(Czesci[0].Ilosc);
- Text[TextNote].Text := IntToStr(AktNuta + 1) + ' / ' + IntToStr(Czesci[0].Czesc[Czesci[0].Akt].LengthNote);
-
- // Song info
- Text[TextBPM].Text := FloatToStr(CurrentSong.BPM[0].BPM / 4);
- Text[TextGAP].Text := FloatToStr(CurrentSong.GAP);
-
- // Note info
- Text[TextNStart].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
- Text[TextNDlugosc].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
- Text[TextNTon].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton);
- Text[TextNText].Text := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
-
- // draw static menu
- inherited Draw;
-
- // draw notes
- SingDrawNoteLines(20, 300, 780, 15);
- SingDrawBeatDelimeters(40, 300, 760, 0);
- SingDrawCzesc(40, 405, 760, 0);
-
- // draw text
- Lyric.Draw;}
-
-end;*)
-
-procedure TScreenEditHeader.SetRoundButtons;
-begin
- if Length(Text[TextTitle].Text) > 0 then Static[StaticTitle].Visible := true
- else Static[StaticTitle].Visible := false;
-
- if Length(Text[TextArtist].Text) > 0 then Static[StaticArtist].Visible := true
- else Static[StaticArtist].Visible := false;
-
- if Length(Text[TextMp3].Text) > 0 then Static[StaticMp3].Visible := true
- else Static[StaticMp3].Visible := false;
-
- if Length(Text[TextBackground].Text) > 0 then Static[StaticBackground].Visible := true
- else Static[StaticBackground].Visible := false;
-
- if Length(Text[TextVideo].Text) > 0 then Static[StaticVideo].Visible := true
- else Static[StaticVideo].Visible := false;
-
- try
- StrToFloat(Text[TextVideoGAP].Text);
- if StrToFloat(Text[TextVideoGAP].Text)<> 0 then Static[StaticVideoGAP].Visible := true
- else Static[StaticVideoGAP].Visible := false;
- except
- Static[StaticVideoGAP].Visible := false;
- end;
-
- if LowerCase(Text[TextRelative].Text) = 'yes' then Static[StaticRelative].Visible := true
- else Static[StaticRelative].Visible := false;
-
- try
- StrToInt(Text[TextResolution].Text);
- if (StrToInt(Text[TextResolution].Text) <> 0) and (StrToInt(Text[TextResolution].Text) >= 1)
- then Static[StaticResolution].Visible := true
- else Static[StaticResolution].Visible := false;
- except
- Static[StaticResolution].Visible := false;
- end;
-
- try
- StrToInt(Text[TextNotesGAP].Text);
- Static[StaticNotesGAP].Visible := true;
- except
- Static[StaticNotesGAP].Visible := false;
- end;
-
- // start
- try
- StrToFloat(Text[TextStart].Text);
- if (StrToFloat(Text[TextStart].Text) > 0) then Static[StaticStart].Visible := true
- else Static[StaticStart].Visible := false;
- except
- Static[StaticStart].Visible := false;
- end;
-
- // GAP
- try
- StrToFloat(Text[TextGAP].Text);
- Static[StaticGAP].Visible := true;
- except
- Static[StaticGAP].Visible := false;
- end;
-
- // BPM
- try
- StrToFloat(Text[TextBPM].Text);
- if (StrToFloat(Text[TextBPM].Text) > 0) then Static[StaticBPM].Visible := true
- else Static[StaticBPM].Visible := false;
- except
- Static[StaticBPM].Visible := false;
- end;
-
-end;
-
-(*procedure TScreenEdit.Finish;
-begin
-//
-end;*)
-
-end.
+unit UScreenEditHeader;
+
+interface
+
+{$I switches.inc}
+
+uses UMenu,
+ SDL,
+ USongs,
+ USong,
+ UThemes;
+
+type
+ TScreenEditHeader = class(TMenu)
+ public
+ CurrentSong: TSong;
+ TextTitle: integer;
+ TextArtist: integer;
+ TextMp3: integer;
+ TextBackground: integer;
+ TextVideo: integer;
+ TextVideoGAP: integer;
+ TextRelative: integer;
+ TextResolution: integer;
+ TextNotesGAP: integer;
+ TextStart: integer;
+ TextGAP: integer;
+ TextBPM: integer;
+ StaticTitle: integer;
+ StaticArtist: integer;
+ StaticMp3: integer;
+ StaticBackground: integer;
+ StaticVideo: integer;
+ StaticVideoGAP: integer;
+ StaticRelative: integer;
+ StaticResolution: integer;
+ StaticNotesGAP: integer;
+ StaticStart: integer;
+ StaticGAP: integer;
+ StaticBPM: integer;
+ Sel: array[0..11] of boolean;
+ procedure SetRoundButtons;
+
+ constructor Create; override;
+ procedure onShow; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+{ function Draw: boolean; override;
+ procedure Finish;}
+ end;
+
+implementation
+
+uses UGraphic, UMusic, SysUtils, UFiles, USkins, UTexture;
+
+function TScreenEditHeader.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+var
+ T: integer;
+begin
+ Result := true;
+ If (PressedDown) Then begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE :
+ begin
+// Music.PlayBack;
+// FadeTo(@MainScreen);
+ Result := false;
+ end;
+
+ SDLK_RETURN:
+ begin
+ if Interaction = 1 then begin
+// Save;
+ end;
+ end;
+
+ SDLK_RIGHT:
+ begin
+ case Interaction of
+ 0..0: InteractNext;
+ 1: Interaction := 0;
+ end;
+ end;
+
+ SDLK_LEFT:
+ begin
+ case Interaction of
+ 0: Interaction := 1;
+ 1..1: InteractPrev;
+ end;
+ end;
+
+ SDLK_DOWN:
+ begin
+ case Interaction of
+ 0..1: Interaction := 2;
+ 2..12: InteractNext;
+ 13: Interaction := 0;
+ end;
+ end;
+
+ SDLK_UP:
+ begin
+ case Interaction of
+ 0..1: Interaction := 13;
+ 2: Interaction := 0;
+ 3..13: InteractPrev;
+ end;
+ end;
+
+ SDLK_BACKSPACE:
+ begin
+ T := Interaction - 2 + TextTitle;
+ if (Interaction >= 2) and (Interaction <= 13) and (Length(Text[T].Text) >= 1) then begin
+ Text[T].DeleteLastL;
+ SetRoundButtons;
+ end;
+ end;
+
+ end;
+ case CharCode of
+ #32..#255:
+ begin
+ if (Interaction >= 2) and (Interaction <= 13) then begin
+ Text[Interaction - 2 + TextTitle].Text :=
+ Text[Interaction - 2 + TextTitle].Text + CharCode;
+ SetRoundButtons;
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenEditHeader.Create;
+begin
+ inherited Create;
+
+ AddButton(40, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(15, 5, 'Open');
+
+ AddButton(160, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(20, 5, 'Save');
+
+ AddBox(80, 60, 640, 550);
+
+ AddText(160, 110 + 0*30, 0, 10, 0, 0, 0, 'Title:');
+ AddText(160, 110 + 1*30, 0, 10, 0, 0, 0, 'Artist:');
+ AddText(160, 110 + 2*30, 0, 10, 0, 0, 0, 'MP3:');
+
+ AddText(160, 110 + 4*30, 0, 10, 0, 0, 0, 'Background:');
+ AddText(160, 110 + 5*30, 0, 10, 0, 0, 0, 'Video:');
+ AddText(160, 110 + 6*30, 0, 10, 0, 0, 0, 'VideoGAP:');
+
+ AddText(160, 110 + 8*30, 0, 10, 0, 0, 0, 'Relative:');
+ AddText(160, 110 + 9*30, 0, 10, 0, 0, 0, 'Resolution:');
+ AddText(160, 110 + 10*30, 0, 10, 0, 0, 0, 'NotesGAP:');
+
+ AddText(160, 110 + 12*30, 0, 10, 0, 0, 0, 'Start:');
+ AddText(160, 110 + 13*30, 0, 10, 0, 0, 0, 'GAP:');
+ AddText(160, 110 + 14*30, 0, 10, 0, 0, 0, 'BPM:');
+
+ TextTitle := AddText(340, 110 + 0*30, 0, 10, 0, 0, 0, '');
+ TextArtist := AddText(340, 110 + 1*30, 0, 10, 0, 0, 0, '');
+ TextMp3 := AddText(340, 110 + 2*30, 0, 10, 0, 0, 0, '');
+
+ TextBackground := AddText(340, 110 + 4*30, 0, 10, 0, 0, 0, '');
+ TextVideo := AddText(340, 110 + 5*30, 0, 10, 0, 0, 0, '');
+ TextVideoGAP := AddText(340, 110 + 6*30, 0, 10, 0, 0, 0, '');
+
+ TextRelative := AddText(340, 110 + 8*30, 0, 10, 0, 0, 0, '');
+ TextResolution := AddText(340, 110 + 9*30, 0, 10, 0, 0, 0, '');
+ TextNotesGAP := AddText(340, 110 + 10*30, 0, 10, 0, 0, 0, '');
+
+ TextStart := AddText(340, 110 + 12*30, 0, 10, 0, 0, 0, '');
+ TextGAP := AddText(340, 110 + 13*30, 0, 10, 0, 0, 0, '');
+ TextBPM := AddText(340, 110 + 14*30, 0, 10, 0, 0, 0, '');
+
+ StaticTitle := AddStatic(130, 115 + 0*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticArtist := AddStatic(130, 115 + 1*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticMp3 := AddStatic(130, 115 + 2*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticBackground := AddStatic(130, 115 + 4*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticVideo := AddStatic(130, 115 + 5*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticVideoGAP := AddStatic(130, 115 + 6*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticRelative := AddStatic(130, 115 + 8*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticResolution := AddStatic(130, 115 + 9*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticNotesGAP := AddStatic(130, 115 + 10*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticStart := AddStatic(130, 115 + 12*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticGAP := AddStatic(130, 115 + 13*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+ StaticBPM := AddStatic(130, 115 + 14*30, 20, 20, 1, 1, 1, 'RoundButton', TEXTURE_TYPE_TRANSPARENT, $FF00FF);
+
+ AddInteraction(iText, TextTitle);
+ AddInteraction(iText, TextArtist);
+ AddInteraction(iText, TextMp3);
+ AddInteraction(iText, TextBackground);
+ AddInteraction(iText, TextVideo);
+ AddInteraction(iText, TextVideoGAP);
+ AddInteraction(iText, TextRelative);
+ AddInteraction(iText, TextResolution);
+ AddInteraction(iText, TextNotesGAP);
+ AddInteraction(iText, TextStart);
+ AddInteraction(iText, TextGAP);
+ AddInteraction(iText, TextBPM);
+end;
+
+procedure TScreenEditHeader.onShow;
+begin
+ inherited;
+
+{ if FileExists(FileName) then begin // load file
+ CurrentSong.FileName := FileName;
+ SkanujPlik(CurrentSong);
+
+ SetLength(TrueBoolStrs, 1);
+ TrueBoolStrs[0] := 'yes';
+ SetLength(FalseBoolStrs, 1);
+ FalseBoolStrs[0] := 'no';
+
+ Text[TextTitle].Text := CurrentSong.Title;
+ Text[TextArtist].Text := CurrentSong.Artist;
+ Text[TextMP3].Text := CurrentSong.Mp3;
+ Text[TextBackground].Text := CurrentSong.Background;
+ Text[TextVideo].Text := CurrentSong.Video;
+ Text[TextVideoGAP].Text := FloatToStr(CurrentSong.VideoGAP);
+ Text[TextRelative].Text := BoolToStr(CurrentSong.Relative, true);
+ Text[TextResolution].Text := IntToStr(CurrentSong.Resolution);
+ Text[TextNotesGAP].Text := IntToStr(CurrentSong.NotesGAP);
+ Text[TextStart].Text := FloatToStr(CurrentSong.Start);
+ Text[TextGAP].Text := FloatToStr(CurrentSong.GAP);
+ Text[TextBPM].Text := FloatToStr(CurrentSong.BPM[0].BPM);
+ SetRoundButtons;
+ end;}
+
+ Interaction := 0;
+end;
+
+(*function TScreenEdit.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ Pet: integer;
+ AktBeat: integer;
+begin
+{ glClearColor(1,1,1,1);
+
+ // control music
+ if PlaySentence then begin
+ // stop the music
+ if (Music.Position > PlayStopTime) then begin
+ Music.Stop;
+ PlaySentence := false;
+ end;
+
+ // click
+ if (Click) and (PlaySentence) then begin
+ AktBeat := Floor(CurrentSong.BPM[0].BPM * (Music.Position - CurrentSong.GAP / 1000) / 60);
+ Text[TextDebug].Text := IntToStr(AktBeat);
+ if AktBeat <> LastClick then begin
+ for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
+ if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then begin
+ Music.PlayClick;
+ LastClick := AktBeat;
+ end;
+ end;
+ end; // click
+ end; // if PlaySentence
+
+ Text[TextSentence].Text := IntToStr(Czesci[0].Akt + 1) + ' / ' + IntToStr(Czesci[0].Ilosc);
+ Text[TextNote].Text := IntToStr(AktNuta + 1) + ' / ' + IntToStr(Czesci[0].Czesc[Czesci[0].Akt].LengthNote);
+
+ // Song info
+ Text[TextBPM].Text := FloatToStr(CurrentSong.BPM[0].BPM / 4);
+ Text[TextGAP].Text := FloatToStr(CurrentSong.GAP);
+
+ // Note info
+ Text[TextNStart].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
+ Text[TextNDlugosc].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
+ Text[TextNTon].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton);
+ Text[TextNText].Text := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
+
+ // draw static menu
+ inherited Draw;
+
+ // draw notes
+ SingDrawNoteLines(20, 300, 780, 15);
+ SingDrawBeatDelimeters(40, 300, 760, 0);
+ SingDrawCzesc(40, 405, 760, 0);
+
+ // draw text
+ Lyric.Draw;}
+
+end;*)
+
+procedure TScreenEditHeader.SetRoundButtons;
+begin
+ if Length(Text[TextTitle].Text) > 0 then Static[StaticTitle].Visible := true
+ else Static[StaticTitle].Visible := false;
+
+ if Length(Text[TextArtist].Text) > 0 then Static[StaticArtist].Visible := true
+ else Static[StaticArtist].Visible := false;
+
+ if Length(Text[TextMp3].Text) > 0 then Static[StaticMp3].Visible := true
+ else Static[StaticMp3].Visible := false;
+
+ if Length(Text[TextBackground].Text) > 0 then Static[StaticBackground].Visible := true
+ else Static[StaticBackground].Visible := false;
+
+ if Length(Text[TextVideo].Text) > 0 then Static[StaticVideo].Visible := true
+ else Static[StaticVideo].Visible := false;
+
+ try
+ StrToFloat(Text[TextVideoGAP].Text);
+ if StrToFloat(Text[TextVideoGAP].Text)<> 0 then Static[StaticVideoGAP].Visible := true
+ else Static[StaticVideoGAP].Visible := false;
+ except
+ Static[StaticVideoGAP].Visible := false;
+ end;
+
+ if LowerCase(Text[TextRelative].Text) = 'yes' then Static[StaticRelative].Visible := true
+ else Static[StaticRelative].Visible := false;
+
+ try
+ StrToInt(Text[TextResolution].Text);
+ if (StrToInt(Text[TextResolution].Text) <> 0) and (StrToInt(Text[TextResolution].Text) >= 1)
+ then Static[StaticResolution].Visible := true
+ else Static[StaticResolution].Visible := false;
+ except
+ Static[StaticResolution].Visible := false;
+ end;
+
+ try
+ StrToInt(Text[TextNotesGAP].Text);
+ Static[StaticNotesGAP].Visible := true;
+ except
+ Static[StaticNotesGAP].Visible := false;
+ end;
+
+ // start
+ try
+ StrToFloat(Text[TextStart].Text);
+ if (StrToFloat(Text[TextStart].Text) > 0) then Static[StaticStart].Visible := true
+ else Static[StaticStart].Visible := false;
+ except
+ Static[StaticStart].Visible := false;
+ end;
+
+ // GAP
+ try
+ StrToFloat(Text[TextGAP].Text);
+ Static[StaticGAP].Visible := true;
+ except
+ Static[StaticGAP].Visible := false;
+ end;
+
+ // BPM
+ try
+ StrToFloat(Text[TextBPM].Text);
+ if (StrToFloat(Text[TextBPM].Text) > 0) then Static[StaticBPM].Visible := true
+ else Static[StaticBPM].Visible := false;
+ except
+ Static[StaticBPM].Visible := false;
+ end;
+
+end;
+
+(*procedure TScreenEdit.Finish;
+begin
+//
+end;*)
+
+end.
diff --git a/Game/Code/Screens/UScreenName.pas b/Game/Code/Screens/UScreenName.pas
index 6a5ef4c5..f2d59f05 100644
--- a/Game/Code/Screens/UScreenName.pas
+++ b/Game/Code/Screens/UScreenName.pas
@@ -1,243 +1,243 @@
-unit UScreenName;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
-
-type
- TScreenName = class(TMenu)
- public
- Goto_SingScreen: Boolean; //If True then next Screen in SingScreen
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure SetAnimationProgress(Progress: real); override;
- end;
-
-implementation
-
-uses UGraphic, UMain, UIni, UTexture, UCommon;
-
-
-function TScreenName.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-var
- I: integer;
-SDL_ModState: Word;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
-
- SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
- + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT);
-
- // check normal keys
- if (IsAlphaNumericChar(CharCode) or
- {(CharCode in [' ','-','_','!',',','<','/','*','?','''','"']))} IsPunctuationChar(CharCode)) then
- begin
- Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + CharCode;
- Exit;
- end;
-
- // check special keys
- case PressedKey of
- // Templates for Names Mod
- SDLK_F1:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[0] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[0];
- end;
- SDLK_F2:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[1] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[1];
- end;
- SDLK_F3:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[2] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[2];
- end;
- SDLK_F4:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[3] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[3];
- end;
- SDLK_F5:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[4] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[4];
- end;
- SDLK_F6:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[5] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[5];
- end;
- SDLK_F7:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[6] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[6];
- end;
- SDLK_F8:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[7] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[7];
- end;
- SDLK_F9:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[8] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[8];
- end;
- SDLK_F10:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[9] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[9];
- end;
- SDLK_F11:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[10] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[10];
- end;
- SDLK_F12:
- if (SDL_ModState = KMOD_LALT) then
- begin
- Ini.NameTemplate[11] := Button[Interaction].Text[0].Text;
- end
- else
- begin
- Button[Interaction].Text[0].Text := Ini.NameTemplate[11];
- end;
-
-
- SDLK_BACKSPACE:
- begin
- Button[Interaction].Text[0].DeleteLastL;
- end;
-
- SDLK_ESCAPE :
- begin
- Ini.SaveNames;
- AudioPlayback.PlaySound(SoundLib.Back);
- if GoTo_SingScreen then
- FadeTo(@ScreenSong)
- else
- FadeTo(@ScreenMain);
- end;
-
- SDLK_RETURN:
- begin
- for I := 1 to 6 do
- Ini.Name[I-1] := Button[I-1].Text[0].Text;
- Ini.SaveNames;
- AudioPlayback.PlaySound(SoundLib.Start);
-
- if GoTo_SingScreen then
- FadeTo(@ScreenSing)
- else
- FadeTo(@ScreenLevel);
-
- GoTo_SingScreen := False;
- end;
-
- // Up and Down could be done at the same time,
- // but I don't want to declare variables inside
- // functions like this one, called so many times
- SDLK_DOWN: InteractNext;
- SDLK_UP: InteractPrev;
- SDLK_RIGHT: InteractNext;
- SDLK_LEFT: InteractPrev;
- end;
- end;
-end;
-
-constructor TScreenName.Create;
-var
- I: integer;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.Name);
-
-
- for I := 1 to 6 do
- AddButton(Theme.Name.ButtonPlayer[I]);
-
- Interaction := 0;
-end;
-
-procedure TScreenName.onShow;
-var
- I: integer;
-begin
- inherited;
-
- for I := 1 to 6 do
- Button[I-1].Text[0].Text := Ini.Name[I-1];
-
- for I := 1 to PlayersPlay do begin
- Button[I-1].Visible := true;
- Button[I-1].Selectable := true;
- end;
-
- for I := PlayersPlay+1 to 6 do begin
- Button[I-1].Visible := false;
- Button[I-1].Selectable := false;
- end;
-
-end;
-
-procedure TScreenName.SetAnimationProgress(Progress: real);
-var
- I: integer;
-begin
- for I := 1 to 6 do
- Button[I-1].Texture.ScaleW := Progress;
-end;
-
-end.
+unit UScreenName;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
+
+type
+ TScreenName = class(TMenu)
+ public
+ Goto_SingScreen: Boolean; //If True then next Screen in SingScreen
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic, UMain, UIni, UTexture, UCommon;
+
+
+function TScreenName.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+var
+ I: integer;
+SDL_ModState: Word;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+
+ SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT);
+
+ // check normal keys
+ if (IsAlphaNumericChar(CharCode) or
+ {(CharCode in [' ','-','_','!',',','<','/','*','?','''','"']))} IsPunctuationChar(CharCode)) then
+ begin
+ Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + CharCode;
+ Exit;
+ end;
+
+ // check special keys
+ case PressedKey of
+ // Templates for Names Mod
+ SDLK_F1:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[0] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[0];
+ end;
+ SDLK_F2:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[1] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[1];
+ end;
+ SDLK_F3:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[2] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[2];
+ end;
+ SDLK_F4:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[3] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[3];
+ end;
+ SDLK_F5:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[4] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[4];
+ end;
+ SDLK_F6:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[5] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[5];
+ end;
+ SDLK_F7:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[6] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[6];
+ end;
+ SDLK_F8:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[7] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[7];
+ end;
+ SDLK_F9:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[8] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[8];
+ end;
+ SDLK_F10:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[9] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[9];
+ end;
+ SDLK_F11:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[10] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[10];
+ end;
+ SDLK_F12:
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Ini.NameTemplate[11] := Button[Interaction].Text[0].Text;
+ end
+ else
+ begin
+ Button[Interaction].Text[0].Text := Ini.NameTemplate[11];
+ end;
+
+
+ SDLK_BACKSPACE:
+ begin
+ Button[Interaction].Text[0].DeleteLastL;
+ end;
+
+ SDLK_ESCAPE :
+ begin
+ Ini.SaveNames;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ if GoTo_SingScreen then
+ FadeTo(@ScreenSong)
+ else
+ FadeTo(@ScreenMain);
+ end;
+
+ SDLK_RETURN:
+ begin
+ for I := 1 to 6 do
+ Ini.Name[I-1] := Button[I-1].Text[0].Text;
+ Ini.SaveNames;
+ AudioPlayback.PlaySound(SoundLib.Start);
+
+ if GoTo_SingScreen then
+ FadeTo(@ScreenSing)
+ else
+ FadeTo(@ScreenLevel);
+
+ GoTo_SingScreen := False;
+ end;
+
+ // Up and Down could be done at the same time,
+ // but I don't want to declare variables inside
+ // functions like this one, called so many times
+ SDLK_DOWN: InteractNext;
+ SDLK_UP: InteractPrev;
+ SDLK_RIGHT: InteractNext;
+ SDLK_LEFT: InteractPrev;
+ end;
+ end;
+end;
+
+constructor TScreenName.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.Name);
+
+
+ for I := 1 to 6 do
+ AddButton(Theme.Name.ButtonPlayer[I]);
+
+ Interaction := 0;
+end;
+
+procedure TScreenName.onShow;
+var
+ I: integer;
+begin
+ inherited;
+
+ for I := 1 to 6 do
+ Button[I-1].Text[0].Text := Ini.Name[I-1];
+
+ for I := 1 to PlayersPlay do begin
+ Button[I-1].Visible := true;
+ Button[I-1].Selectable := true;
+ end;
+
+ for I := PlayersPlay+1 to 6 do begin
+ Button[I-1].Visible := false;
+ Button[I-1].Selectable := false;
+ end;
+
+end;
+
+procedure TScreenName.SetAnimationProgress(Progress: real);
+var
+ I: integer;
+begin
+ for I := 1 to 6 do
+ Button[I-1].Texture.ScaleW := Progress;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenOpen.pas b/Game/Code/Screens/UScreenOpen.pas
index 7dbe8743..186b9b47 100644
--- a/Game/Code/Screens/UScreenOpen.pas
+++ b/Game/Code/Screens/UScreenOpen.pas
@@ -1,173 +1,173 @@
-unit UScreenOpen;
-
-interface
-
-{$I switches.inc}
-
-uses UMenu, UMusic, SDL, SysUtils, UFiles, UTime, USongs, UIni, ULog, UTexture, UMenuText,
- ULyrics, Math, gl, UThemes;
-
-type
- TScreenOpen = class(TMenu)
- private
- TextF: array[0..1] of integer;
- TextN: integer;
- public
- Tex_Background: TTexture;
- FadeOut: boolean;
- Path: string;
- BackScreen: pointer;
- procedure AddBox(X, Y, W, H: real);
- constructor Create; override;
- procedure onShow; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
-// function Draw: boolean; override;
-// procedure Finish;
- end;
-
-implementation
-uses UGraphic, UDraw, UMain, USkins;
-
-function TScreenOpen.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
-
- if (PressedDown) then begin // Key Down
- // check normal keys
- case CharCode of
- '0'..'9', 'a'..'z', 'A'..'Z', ' ', '-', '.', ':', '\':
- begin
- if Interaction = 0 then begin
- Text[TextN].Text := Text[TextN].Text + CharCode;
- end;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_Q:
- begin
- Result := false;
- end;
- 8: // del
- begin
- if Interaction = 0 then
- begin
- Text[TextN].DeleteLastL;
- end;
- end;
-
-
- SDLK_ESCAPE :
- begin
- //Empty Filename and go to last Screen
- ConversionFileName := '';
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(BackScreen);
- end;
-
- SDLK_RETURN:
- begin
- if (Interaction = 2) then begin
- //Update Filename and go to last Screen
- ConversionFileName := Text[TextN].Text;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(BackScreen);
- end
- else if (Interaction = 1) then
- begin
- //Empty Filename and go to last Screen
- ConversionFileName := '';
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(BackScreen);
- end;
- end;
-
- SDLK_LEFT:
- begin
- InteractPrev;
- end;
-
- SDLK_RIGHT:
- begin
- InteractNext;
- end;
-
- SDLK_DOWN:
- begin
- end;
-
- SDLK_UP:
- begin
- end;
- end;
- end;
-end;
-
-procedure TScreenOpen.AddBox(X, Y, W, H: real);
-begin
- AddStatic(X, Y, W, H, 0, 0, 0, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
- AddStatic(X+2, Y+2, W-4, H-4, 1, 1, 1, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
-end;
-
-constructor TScreenOpen.Create;
-begin
- inherited Create;
-
- // linijka
-{ AddStatic(20, 10, 80, 30, 0, 0, 0, 'MainBar', 'JPG', TEXTURE_TYPE_COLORIZED);
- AddText(35, 17, 1, 6, 1, 1, 1, 'Linijka');
- TextSentence := AddText(120, 14, 1, 8, 0, 0, 0, '0 / 0');}
-
- // file list
-// AddBox(400, 100, 350, 450);
-
-// TextF[0] := AddText(430, 155, 0, 8, 0, 0, 0, 'a');
-// TextF[1] := AddText(430, 180, 0, 8, 0, 0, 0, 'a');
-
- // file name
- AddBox(20, 540, 500, 40);
- TextN := AddText(50, 548, 0, 8, 0, 0, 0, ConversionFileName);
- AddInteraction(iText, TextN);
-
- // buttons
- {AddButton(540, 540, 100, 40, Skin.SkinPath + Skin.ButtonF);
- AddButtonText(10, 5, 0, 0, 0, 'Cancel');
-
- AddButton(670, 540, 100, 40, Skin.SkinPath + Skin.ButtonF);
- AddButtonText(30, 5, 0, 0, 0, 'OK');}
- // buttons
- AddButton(540, 540, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(10, 5, 0, 0, 0, 'Cancel');
-
- AddButton(670, 540, 100, 40, Skin.GetTextureFileName('ButtonF'));
- AddButtonText(30, 5, 0, 0, 0, 'OK');
-
-
-end;
-
-procedure TScreenOpen.onShow;
-begin
- inherited;
-
- Interaction := 0;
-end;
-
-(*function TScreenEditSub.Draw: boolean;
-var
- Min: integer;
- Sec: integer;
- Tekst: string;
- Pet: integer;
- AktBeat: integer;
-begin
-
-end;
-
-procedure TScreenEditSub.Finish;
-begin
-//
-end;*)
-
-end.
-
+unit UScreenOpen;
+
+interface
+
+{$I switches.inc}
+
+uses UMenu, UMusic, SDL, SysUtils, UFiles, UTime, USongs, UIni, ULog, UTexture, UMenuText,
+ ULyrics, Math, gl, UThemes;
+
+type
+ TScreenOpen = class(TMenu)
+ private
+ TextF: array[0..1] of integer;
+ TextN: integer;
+ public
+ Tex_Background: TTexture;
+ FadeOut: boolean;
+ Path: string;
+ BackScreen: pointer;
+ procedure AddBox(X, Y, W, H: real);
+ constructor Create; override;
+ procedure onShow; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+// function Draw: boolean; override;
+// procedure Finish;
+ end;
+
+implementation
+uses UGraphic, UDraw, UMain, USkins;
+
+function TScreenOpen.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+
+ if (PressedDown) then begin // Key Down
+ // check normal keys
+ case CharCode of
+ '0'..'9', 'a'..'z', 'A'..'Z', ' ', '-', '.', ':', '\':
+ begin
+ if Interaction = 0 then begin
+ Text[TextN].Text := Text[TextN].Text + CharCode;
+ end;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+ 8: // del
+ begin
+ if Interaction = 0 then
+ begin
+ Text[TextN].DeleteLastL;
+ end;
+ end;
+
+
+ SDLK_ESCAPE :
+ begin
+ //Empty Filename and go to last Screen
+ ConversionFileName := '';
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(BackScreen);
+ end;
+
+ SDLK_RETURN:
+ begin
+ if (Interaction = 2) then begin
+ //Update Filename and go to last Screen
+ ConversionFileName := Text[TextN].Text;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(BackScreen);
+ end
+ else if (Interaction = 1) then
+ begin
+ //Empty Filename and go to last Screen
+ ConversionFileName := '';
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(BackScreen);
+ end;
+ end;
+
+ SDLK_LEFT:
+ begin
+ InteractPrev;
+ end;
+
+ SDLK_RIGHT:
+ begin
+ InteractNext;
+ end;
+
+ SDLK_DOWN:
+ begin
+ end;
+
+ SDLK_UP:
+ begin
+ end;
+ end;
+ end;
+end;
+
+procedure TScreenOpen.AddBox(X, Y, W, H: real);
+begin
+ AddStatic(X, Y, W, H, 0, 0, 0, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
+ AddStatic(X+2, Y+2, W-4, H-4, 1, 1, 1, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED);
+end;
+
+constructor TScreenOpen.Create;
+begin
+ inherited Create;
+
+ // linijka
+{ AddStatic(20, 10, 80, 30, 0, 0, 0, 'MainBar', 'JPG', TEXTURE_TYPE_COLORIZED);
+ AddText(35, 17, 1, 6, 1, 1, 1, 'Linijka');
+ TextSentence := AddText(120, 14, 1, 8, 0, 0, 0, '0 / 0');}
+
+ // file list
+// AddBox(400, 100, 350, 450);
+
+// TextF[0] := AddText(430, 155, 0, 8, 0, 0, 0, 'a');
+// TextF[1] := AddText(430, 180, 0, 8, 0, 0, 0, 'a');
+
+ // file name
+ AddBox(20, 540, 500, 40);
+ TextN := AddText(50, 548, 0, 8, 0, 0, 0, ConversionFileName);
+ AddInteraction(iText, TextN);
+
+ // buttons
+ {AddButton(540, 540, 100, 40, Skin.SkinPath + Skin.ButtonF);
+ AddButtonText(10, 5, 0, 0, 0, 'Cancel');
+
+ AddButton(670, 540, 100, 40, Skin.SkinPath + Skin.ButtonF);
+ AddButtonText(30, 5, 0, 0, 0, 'OK');}
+ // buttons
+ AddButton(540, 540, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(10, 5, 0, 0, 0, 'Cancel');
+
+ AddButton(670, 540, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(30, 5, 0, 0, 0, 'OK');
+
+
+end;
+
+procedure TScreenOpen.onShow;
+begin
+ inherited;
+
+ Interaction := 0;
+end;
+
+(*function TScreenEditSub.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ Pet: integer;
+ AktBeat: integer;
+begin
+
+end;
+
+procedure TScreenEditSub.Finish;
+begin
+//
+end;*)
+
+end.
+
diff --git a/Game/Code/Screens/UScreenOptionsGraphics.pas b/Game/Code/Screens/UScreenOptionsGraphics.pas
index 0a736a9d..d88753f2 100644
--- a/Game/Code/Screens/UScreenOptionsGraphics.pas
+++ b/Game/Code/Screens/UScreenOptionsGraphics.pas
@@ -1,107 +1,107 @@
-unit UScreenOptionsGraphics;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
-
-type
- TScreenOptionsGraphics = class(TMenu)
- public
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- end;
-
-implementation
-
-uses UGraphic, UMain, SysUtils;
-
-function TScreenOptionsGraphics.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- Ini.Save;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- SDLK_RETURN:
- begin
-{ if SelInteraction <= 1 then begin
- Restart := true;
- end;}
- if SelInteraction = 5 then begin
- Ini.Save;
- AudioPlayback.PlaySound(SoundLib.Back);
- Reinitialize3D();
- FadeTo(@ScreenOptions);
- end;
- end;
- SDLK_DOWN:
- InteractNext;
- SDLK_UP :
- InteractPrev;
- SDLK_RIGHT:
- begin
- if (SelInteraction >= 0) and (SelInteraction <= 4) then begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractInc;
- end;
- end;
- SDLK_LEFT:
- begin
- if (SelInteraction >= 0) and (SelInteraction <= 4) then begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractDec;
- end;
- end;
- end;
- end;
-end;
-
-constructor TScreenOptionsGraphics.Create;
-//var
-// I: integer; // Auto Removed, Unused Variable
-begin
- inherited Create;
-
- LoadFromTheme(Theme.OptionsGraphics);
-
- AddSelectSlide(Theme.OptionsGraphics.SelectSlideResolution, Ini.Resolution, IResolution);
- AddSelect(Theme.OptionsGraphics.SelectFullscreen, Ini.Fullscreen, IFullscreen);
- AddSelect(Theme.OptionsGraphics.SelectDepth, Ini.Depth, IDepth);
- AddSelect(Theme.OptionsGraphics.SelectOscilloscope, Ini.Oscilloscope, IOscilloscope);
- AddSelect(Theme.OptionsGraphics.SelectMovieSize, Ini.MovieSize, IMovieSize);
-
-
- AddButton(Theme.OptionsGraphics.ButtonExit);
- if (Length(Button[0].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[7]);
-
-end;
-
-procedure TScreenOptionsGraphics.onShow;
-begin
- inherited;
-
- Interaction := 0;
-end;
-
-end.
+unit UScreenOptionsGraphics;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
+
+type
+ TScreenOptionsGraphics = class(TMenu)
+ public
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ end;
+
+implementation
+
+uses UGraphic, UMain, SysUtils;
+
+function TScreenOptionsGraphics.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+{ if SelInteraction <= 1 then begin
+ Restart := true;
+ end;}
+ if SelInteraction = 5 then begin
+ Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ Reinitialize3D();
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 4) then begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractInc;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 4) then begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractDec;
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenOptionsGraphics.Create;
+//var
+// I: integer; // Auto Removed, Unused Variable
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.OptionsGraphics);
+
+ AddSelectSlide(Theme.OptionsGraphics.SelectSlideResolution, Ini.Resolution, IResolution);
+ AddSelect(Theme.OptionsGraphics.SelectFullscreen, Ini.Fullscreen, IFullscreen);
+ AddSelect(Theme.OptionsGraphics.SelectDepth, Ini.Depth, IDepth);
+ AddSelect(Theme.OptionsGraphics.SelectOscilloscope, Ini.Oscilloscope, IOscilloscope);
+ AddSelect(Theme.OptionsGraphics.SelectMovieSize, Ini.MovieSize, IMovieSize);
+
+
+ AddButton(Theme.OptionsGraphics.ButtonExit);
+ if (Length(Button[0].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[7]);
+
+end;
+
+procedure TScreenOptionsGraphics.onShow;
+begin
+ inherited;
+
+ Interaction := 0;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenOptionsLyrics.pas b/Game/Code/Screens/UScreenOptionsLyrics.pas
index a314f2f3..dec3b00c 100644
--- a/Game/Code/Screens/UScreenOptionsLyrics.pas
+++ b/Game/Code/Screens/UScreenOptionsLyrics.pas
@@ -1,102 +1,102 @@
-unit UScreenOptionsLyrics;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
-
-type
- TScreenOptionsLyrics = class(TMenu)
- public
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- end;
-
-implementation
-
-uses UGraphic, SysUtils;
-
-function TScreenOptionsLyrics.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- Ini.Save;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- SDLK_RETURN:
- begin
- if SelInteraction = 4 then begin
- Ini.Save;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- end;
- SDLK_DOWN:
- InteractNext;
- SDLK_UP :
- InteractPrev;
- SDLK_RIGHT:
- begin
- if (SelInteraction >= 0) and (SelInteraction <= 3) then begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractInc;
- end;
- end;
- SDLK_LEFT:
- begin
- if (SelInteraction >= 0) and (SelInteraction <= 3) then begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractDec;
- end;
- end;
- end;
- end;
-end;
-
-constructor TScreenOptionsLyrics.Create;
-//var
-// I: integer; // Auto Removed, Unused Variable
-begin
- inherited Create;
-
- LoadFromTheme(Theme.OptionsLyrics);
-
- AddSelect(Theme.OptionsLyrics.SelectLyricsFont, Ini.LyricsFont, ILyricsFont);
- AddSelectSlide(Theme.OptionsLyrics.SelectLyricsEffect, Ini.LyricsEffect, ILyricsEffect);
- AddSelect(Theme.OptionsLyrics.SelectSolmization, Ini.Solmization, ISolmization);
- AddSelect(Theme.OptionsLyrics.SelectNoteLines, Ini.NoteLines, INoteLines);
-
-
- AddButton(Theme.OptionsLyrics.ButtonExit);
- if (Length(Button[0].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[7]);
-
-end;
-
-procedure TScreenOptionsLyrics.onShow;
-begin
- inherited;
-
- Interaction := 0;
-end;
-
-end.
+unit UScreenOptionsLyrics;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UFiles, UIni, UThemes;
+
+type
+ TScreenOptionsLyrics = class(TMenu)
+ public
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ end;
+
+implementation
+
+uses UGraphic, SysUtils;
+
+function TScreenOptionsLyrics.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+ if SelInteraction = 4 then begin
+ Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 3) then begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractInc;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 3) then begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractDec;
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenOptionsLyrics.Create;
+//var
+// I: integer; // Auto Removed, Unused Variable
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.OptionsLyrics);
+
+ AddSelect(Theme.OptionsLyrics.SelectLyricsFont, Ini.LyricsFont, ILyricsFont);
+ AddSelectSlide(Theme.OptionsLyrics.SelectLyricsEffect, Ini.LyricsEffect, ILyricsEffect);
+ AddSelect(Theme.OptionsLyrics.SelectSolmization, Ini.Solmization, ISolmization);
+ AddSelect(Theme.OptionsLyrics.SelectNoteLines, Ini.NoteLines, INoteLines);
+
+
+ AddButton(Theme.OptionsLyrics.ButtonExit);
+ if (Length(Button[0].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[7]);
+
+end;
+
+procedure TScreenOptionsLyrics.onShow;
+begin
+ inherited;
+
+ Interaction := 0;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenOptionsRecord.pas b/Game/Code/Screens/UScreenOptionsRecord.pas
index 8db5ede9..0e6a6842 100644
--- a/Game/Code/Screens/UScreenOptionsRecord.pas
+++ b/Game/Code/Screens/UScreenOptionsRecord.pas
@@ -1,756 +1,756 @@
-unit UScreenOptionsRecord;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UThemes,
- UMusic,
- URecord,
- UMenu;
-
-type
- TDrawState = record
- ChannelIndex: integer;
- R, G, B: real; // mapped player color (normal)
- RD, GD, BD: real; // mapped player color (dark)
- end;
-
- TPeakInfo = record
- Volume: single;
- Time: cardinal;
- end;
-
- TScreenOptionsRecord = class(TMenu)
- private
- // max. count of input-channels determined for all devices
- MaxChannelCount: integer;
-
- // current input device
- CurrentDeviceIndex: integer;
- PreviewDeviceIndex: integer;
-
- // string arrays for select-slide options
- InputSourceNames: array of string;
- InputDeviceNames: array of string;
-
- // dynamic generated themes for channel select-sliders
- SelectSlideChannelTheme: array of TThemeSelectSlide;
-
- // indices for widget-updates
- SelectInputSourceID: integer;
- SelectSlideChannelID: array of integer;
- TextPitchID: array of integer;
-
- // interaction IDs
- ExitButtonIID: integer;
-
- // dummy data for non-available channels
- ChannelToPlayerMapDummy: integer;
-
- // preview channel-buffers
- PreviewChannel: array of TCaptureBuffer;
- ChannelPeak: array of TPeakInfo;
-
- // Device source volume
- SourceVolume: single;
- NextVolumePollTime: cardinal;
-
- procedure StartPreview;
- procedure StopPreview;
- procedure UpdateInputDevice;
- procedure ChangeVolume(VolumeChange: single);
- procedure DrawVolume(x, y, Width, Height: single);
- procedure DrawVUMeter(const State: TDrawState; x, y, Width, Height: single);
- procedure DrawPitch(const State: TDrawState; x, y, Width, Height: single);
- public
- constructor Create; override;
- function Draw: boolean; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure onHide; override;
- end;
-
-const
- PeakDecay = 0.2; // strength of peak-decay (reduction after one sec)
-
-const
- BarHeight = 11; // height of each bar (volume/vu-meter/pitch)
- BarUpperSpacing = 1; // spacing between a bar-area and the previous widget
- BarLowerSpacing = 3; // spacing between a bar-area and the next widget
- SourceBarsTotalHeight = BarHeight + BarUpperSpacing + BarLowerSpacing;
- ChannelBarsTotalHeight = 2*BarHeight + BarUpperSpacing + BarLowerSpacing;
-
-implementation
-
-uses
- SysUtils,
- Math,
- SDL,
- gl,
- UGraphic,
- UDraw,
- UMain,
- UMenuSelectSlide,
- UMenuText,
- UFiles,
- UDisplay,
- UIni,
- ULog;
-
-function TScreenOptionsRecord.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- '+':
- begin
- // FIXME: add a nice volume-slider instead
- // or at least provide visualization and acceleration if the user holds the key pressed.
- ChangeVolume(0.02);
- end;
- '-':
- begin
- // FIXME: add a nice volume-slider instead
- // or at least provide visualization and acceleration if the user holds the key pressed.
- ChangeVolume(-0.02);
- end;
- 'T':
- begin
- if ((SDL_GetModState() and KMOD_SHIFT) <> 0) then
- Ini.ThresholdIndex := (Ini.ThresholdIndex + Length(IThresholdVals) - 1) mod Length(IThresholdVals)
- else
- Ini.ThresholdIndex := (Ini.ThresholdIndex + 1) mod Length(IThresholdVals);
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE:
- begin
- Ini.Save;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- SDLK_RETURN:
- begin
- if (SelInteraction = ExitButtonIID) then
- begin
- Ini.Save;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenOptions);
- end;
- end;
- SDLK_DOWN:
- InteractNext;
- SDLK_UP :
- InteractPrev;
- SDLK_RIGHT:
- begin
- if (SelInteraction >= 0) and (SelInteraction < ExitButtonIID) then
- begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractInc;
- end;
- UpdateInputDevice;
- end;
- SDLK_LEFT:
- begin
- if (SelInteraction >= 0) and (SelInteraction < ExitButtonIID) then
- begin
- AudioPlayback.PlaySound(SoundLib.Option);
- InteractDec;
- end;
- UpdateInputDevice;
- end;
- end;
- end;
-end;
-
-constructor TScreenOptionsRecord.Create;
-var
- DeviceIndex: integer;
- SourceIndex: integer;
- ChannelIndex: integer;
- InputDevice: TAudioInputDevice;
- InputDeviceCfg: PInputDeviceConfig;
- ChannelTheme: ^TThemeSelectSlide;
- ButtonTheme: TThemeButton;
- WidgetYPos: integer;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.OptionsRecord);
-
- // set CurrentDeviceIndex to a valid device
- if (Length(AudioInputProcessor.DeviceList) > 0) then
- CurrentDeviceIndex := 0
- else
- CurrentDeviceIndex := -1;
-
- PreviewDeviceIndex := -1;
-
- WidgetYPos := 0;
-
- // init sliders if at least one device was detected
- if (Length(AudioInputProcessor.DeviceList) > 0) then
- begin
- InputDevice := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
- InputDeviceCfg := @Ini.InputDeviceConfig[InputDevice.CfgIndex];
-
- // init device-selection slider
- SetLength(InputDeviceNames, Length(AudioInputProcessor.DeviceList));
- for DeviceIndex := 0 to High(AudioInputProcessor.DeviceList) do
- begin
- InputDeviceNames[DeviceIndex] := AudioInputProcessor.DeviceList[DeviceIndex].Name;
- end;
- // add device-selection slider (InteractionID: 0)
- AddSelectSlide(Theme.OptionsRecord.SelectSlideCard, CurrentDeviceIndex, InputDeviceNames);
-
- // init source-selection slider
- SetLength(InputSourceNames, Length(InputDevice.Source));
- for SourceIndex := 0 to High(InputDevice.Source) do
- begin
- InputSourceNames[SourceIndex] := InputDevice.Source[SourceIndex].Name;
- end;
- // add source-selection slider (InteractionID: 1)
- SelectInputSourceID := AddSelectSlide(Theme.OptionsRecord.SelectSlideInput,
- InputDeviceCfg.Input, InputSourceNames);
-
- // add space for source volume bar
- WidgetYPos := Theme.OptionsRecord.SelectSlideInput.Y +
- Theme.OptionsRecord.SelectSlideInput.H +
- SourceBarsTotalHeight;
-
- // find max. channel count of all devices
- MaxChannelCount := 0;
- for DeviceIndex := 0 to High(AudioInputProcessor.DeviceList) do
- begin
- if (AudioInputProcessor.DeviceList[DeviceIndex].AudioFormat.Channels > MaxChannelCount) then
- MaxChannelCount := AudioInputProcessor.DeviceList[DeviceIndex].AudioFormat.Channels;
- end;
-
- // init channel-to-player mapping sliders
- SetLength(SelectSlideChannelID, MaxChannelCount);
- SetLength(SelectSlideChannelTheme, MaxChannelCount);
- SetLength(TextPitchID, MaxChannelCount);
-
- for ChannelIndex := 0 to MaxChannelCount-1 do
- begin
- // copy reference slide
- SelectSlideChannelTheme[ChannelIndex] :=
- Theme.OptionsRecord.SelectSlideChannel;
- // set current channel-theme
- ChannelTheme := @SelectSlideChannelTheme[ChannelIndex];
- // adjust vertical position
- ChannelTheme.Y := WidgetYPos;
- // calc size of next slide (add space for bars)
- WidgetYPos := WidgetYPos + ChannelTheme.H + ChannelBarsTotalHeight;
- // append channel index to name
- ChannelTheme.Text := ChannelTheme.Text + IntToStr(ChannelIndex+1);
-
- // add tone-pitch label
- TextPitchID[ChannelIndex] := AddText(
- ChannelTheme.X + ChannelTheme.W,
- ChannelTheme.Y + ChannelTheme.H/2,
- '-');
-
- // show/hide widgets depending on whether the channel exists
- if (ChannelIndex < Length(InputDeviceCfg.ChannelToPlayerMap)) then
- begin
- // current device has this channel
-
- // add slider
- SelectSlideChannelID[ChannelIndex] := AddSelectSlide(ChannelTheme^,
- InputDeviceCfg.ChannelToPlayerMap[ChannelIndex], IChannelPlayer);
- end
- else
- begin
- // current device does not have that many channels
-
- // add slider but hide it and assign a dummy variable to it
- SelectSlideChannelID[ChannelIndex] := AddSelectSlide(ChannelTheme^,
- ChannelToPlayerMapDummy, IChannelPlayer);
- SelectsS[SelectSlideChannelID[ChannelIndex]].Visible := false;
-
- // hide pitch label
- Text[TextPitchID[ChannelIndex]].Visible := false;
- end;
- end;
- end;
-
- // add Exit-button
- ButtonTheme := Theme.OptionsRecord.ButtonExit;
- // adjust button position
- if (WidgetYPos <> 0) then
- ButtonTheme.Y := WidgetYPos;
- AddButton(ButtonTheme);
- if (Length(Button[0].Text) = 0) then
- AddButtonText(14, 20, Theme.Options.Description[7]);
- // store InteractionID
- if (Length(AudioInputProcessor.DeviceList) > 0) then
- ExitButtonIID := MaxChannelCount + 2
- else
- ExitButtonIID := 0;
-
- // set focus
- Interaction := 0;
-end;
-
-procedure TScreenOptionsRecord.UpdateInputDevice;
-var
- SourceIndex: integer;
- InputDevice: TAudioInputDevice;
- InputDeviceCfg: PInputDeviceConfig;
- ChannelIndex: integer;
-begin
- //Log.LogStatus('Update input-device', 'TScreenOptionsRecord.UpdateCard') ;
-
- StopPreview();
-
- // set CurrentDeviceIndex to a valid device
- if (CurrentDeviceIndex > High(AudioInputProcessor.DeviceList)) then
- CurrentDeviceIndex := 0;
-
- // update sliders if at least one device was detected
- if (Length(AudioInputProcessor.DeviceList) > 0) then
- begin
- InputDevice := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
- InputDeviceCfg := @Ini.InputDeviceConfig[InputDevice.CfgIndex];
-
- // update source-selection slider
- SetLength(InputSourceNames, Length(InputDevice.Source));
- for SourceIndex := 0 to High(InputDevice.Source) do
- begin
- InputSourceNames[SourceIndex] := InputDevice.Source[SourceIndex].Name;
- end;
- UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideInput, SelectInputSourceID,
- InputSourceNames, InputDeviceCfg.Input);
-
- // update channel-to-player mapping sliders
- for ChannelIndex := 0 to MaxChannelCount-1 do
- begin
- // show/hide widgets depending on whether the channel exists
- if (ChannelIndex < Length(InputDeviceCfg.ChannelToPlayerMap)) then
- begin
- // current device has this channel
-
- // show slider
- UpdateSelectSlideOptions(SelectSlideChannelTheme[ChannelIndex],
- SelectSlideChannelID[ChannelIndex], IChannelPlayer,
- InputDeviceCfg.ChannelToPlayerMap[ChannelIndex]);
- SelectsS[SelectSlideChannelID[ChannelIndex]].Visible := true;
-
- // show pitch label
- Text[TextPitchID[ChannelIndex]].Visible := true;
- end
- else
- begin
- // current device does not have that many channels
-
- // hide slider and assign a dummy variable to it
- UpdateSelectSlideOptions(SelectSlideChannelTheme[ChannelIndex],
- SelectSlideChannelID[ChannelIndex], IChannelPlayer,
- ChannelToPlayerMapDummy);
- SelectsS[SelectSlideChannelID[ChannelIndex]].Visible := false;
-
- // hide pitch label
- Text[TextPitchID[ChannelIndex]].Visible := false;
- end;
- end;
- end;
-
- StartPreview();
-end;
-
-procedure TScreenOptionsRecord.ChangeVolume(VolumeChange: single);
-var
- InputDevice: TAudioInputDevice;
- Volume: single;
-begin
- // validate CurrentDeviceIndex
- if ((CurrentDeviceIndex < 0) or
- (CurrentDeviceIndex > High(AudioInputProcessor.DeviceList))) then
- begin
- Exit;
- end;
-
- InputDevice := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
- if not assigned(InputDevice) then
- Exit;
-
- // set new volume
- Volume := InputDevice.GetVolume() + VolumeChange;
- InputDevice.SetVolume(Volume);
- //DebugWriteln('Volume: ' + floattostr(InputDevice.GetVolume));
-
- // volume must be polled again
- NextVolumePollTime := 0;
-end;
-
-procedure TScreenOptionsRecord.onShow;
-var
- ChannelIndex: integer;
-begin
- inherited;
-
- Interaction := 0;
-
- // create preview sound-buffers
- SetLength(PreviewChannel, MaxChannelCount);
- for ChannelIndex := 0 to High(PreviewChannel) do
- PreviewChannel[ChannelIndex] := TCaptureBuffer.Create();
-
- SetLength(ChannelPeak, MaxChannelCount);
-
- StartPreview();
-end;
-
-procedure TScreenOptionsRecord.onHide;
-var
- ChannelIndex: integer;
-begin
- StopPreview();
-
- // free preview buffers
- for ChannelIndex := 0 to High(PreviewChannel) do
- PreviewChannel[ChannelIndex].Free;
- SetLength(PreviewChannel, 0);
- SetLength(ChannelPeak, 0);
-end;
-
-procedure TScreenOptionsRecord.StartPreview;
-var
- ChannelIndex: integer;
- Device: TAudioInputDevice;
-begin
- if ((CurrentDeviceIndex >= 0) and
- (CurrentDeviceIndex <= High(AudioInputProcessor.DeviceList))) then
- begin
- Device := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
- // set preview channel as active capture channel
- for ChannelIndex := 0 to High(Device.CaptureChannel) do
- begin
- PreviewChannel[ChannelIndex].Clear();
- Device.LinkCaptureBuffer(ChannelIndex, PreviewChannel[ChannelIndex]);
- FillChar(ChannelPeak[ChannelIndex], SizeOf(TPeakInfo), 0);
- end;
- Device.Start();
- PreviewDeviceIndex := CurrentDeviceIndex;
-
- // volume must be polled again
- NextVolumePollTime := 0;
- end;
-end;
-
-procedure TScreenOptionsRecord.StopPreview;
-var
- ChannelIndex: integer;
- Device: TAudioInputDevice;
-begin
- if ((PreviewDeviceIndex >= 0) and
- (PreviewDeviceIndex <= High(AudioInputProcessor.DeviceList))) then
- begin
- Device := AudioInputProcessor.DeviceList[PreviewDeviceIndex];
- Device.Stop;
- for ChannelIndex := 0 to High(Device.CaptureChannel) do
- Device.CaptureChannel[ChannelIndex] := nil;
- end;
- PreviewDeviceIndex := -1;
-end;
-
-
-procedure TScreenOptionsRecord.DrawVolume(x, y, Width, Height: single);
-var
- x1, y1, x2, y2: single;
- VolBarInnerWidth: integer;
-const
- VolBarInnerHSpacing = 2;
- VolBarInnerVSpacing = 1;
-begin
- // coordinates for black rect
- x1 := x;
- y1 := y;
- x2 := x1 + Width;
- y2 := y1 + Height;
-
- // draw black background-rect
- glColor4f(0, 0, 0, 0.8);
- glBegin(GL_QUADS);
- glVertex2f(x1, y1);
- glVertex2f(x2, y1);
- glVertex2f(x2, y2);
- glVertex2f(x1, y2);
- glEnd();
-
- VolBarInnerWidth := Trunc(Width - 2*VolBarInnerHSpacing);
-
- // coordinates for first half of the volume bar
- x1 := x + VolBarInnerHSpacing;
- x2 := x1 + VolBarInnerWidth * SourceVolume;
- y1 := y1 + VolBarInnerVSpacing;
- y2 := y2 - VolBarInnerVSpacing;
-
- // draw volume-bar
- glBegin(GL_QUADS);
- // draw volume bar
- glColor3f(0.4, 0.3, 0.3);
- glVertex2f(x1, y1);
- glVertex2f(x1, y2);
- glColor3f(1, 0.1, 0.1);
- glVertex2f(x2, y2);
- glVertex2f(x2, y1);
- glEnd();
-
- { not needed anymore
- // coordinates for separator
- x1 := x + VolBarInnerHSpacing;
- x2 := x1 + VolBarInnerWidth;
-
- // draw separator
- glBegin(GL_LINE_STRIP);
- glColor4f(0.1, 0.1, 0.1, 0.2);
- glVertex2f(x1, y2);
- glColor4f(0.4, 0.4, 0.4, 0.2);
- glVertex2f((x1+x2)/2, y2);
- glColor4f(0.1, 0.1, 0.1, 0.2);
- glVertex2f(x2, y2);
- glEnd();
- }
-end;
-
-procedure TScreenOptionsRecord.DrawVUMeter(const State: TDrawState; x, y, Width, Height: single);
-var
- x1, y1, x2, y2: single;
- Volume, PeakVolume: single;
- Delta: single;
- VolBarInnerWidth: integer;
-const
- VolBarInnerHSpacing = 2;
- VolBarInnerVSpacing = 1;
-begin
- // coordinates for black rect
- x1 := x;
- y1 := y;
- x2 := x1 + Width;
- y2 := y1 + Height;
-
- // draw black background-rect
- glColor4f(0, 0, 0, 0.8);
- glBegin(GL_QUADS);
- glVertex2f(x1, y1);
- glVertex2f(x2, y1);
- glVertex2f(x2, y2);
- glVertex2f(x1, y2);
- glEnd();
-
- VolBarInnerWidth := Trunc(Width - 2*VolBarInnerHSpacing);
-
- // vertical positions
- y1 := y1 + VolBarInnerVSpacing;
- y2 := y2 - VolBarInnerVSpacing;
-
- // coordinates for bevel
- x1 := x + VolBarInnerHSpacing;
- x2 := x1 + VolBarInnerWidth;
-
- glBegin(GL_QUADS);
- Volume := PreviewChannel[State.ChannelIndex].MaxSampleVolume();
-
- // coordinates for volume bar
- x1 := x + VolBarInnerHSpacing;
- x2 := x1 + VolBarInnerWidth * Volume;
-
- // draw volume bar
- glColor3f(State.RD, State.GD, State.BD);
- glVertex2f(x1, y1);
- glVertex2f(x1, y2);
- glColor3f(State.R, State.G, State.B);
- glVertex2f(x2, y2);
- glVertex2f(x2, y1);
-
- Delta := (SDL_GetTicks() - ChannelPeak[State.ChannelIndex].Time)/1000;
- PeakVolume := ChannelPeak[State.ChannelIndex].Volume - Delta*Delta*PeakDecay;
-
- // determine new peak-volume
- if (Volume > PeakVolume) then
- begin
- PeakVolume := Volume;
- ChannelPeak[State.ChannelIndex].Volume := Volume;
- ChannelPeak[State.ChannelIndex].Time := SDL_GetTicks();
- end;
-
- x1 := x + VolBarInnerHSpacing + VolBarInnerWidth * PeakVolume;
- x2 := x1 + 2;
-
- // draw peak
- glColor3f(0.8, 0.8, 0.8);
- glVertex2f(x1, y1);
- glVertex2f(x1, y2);
- glVertex2f(x2, y2);
- glVertex2f(x2, y1);
-
- // draw threshold
- x1 := x + VolBarInnerHSpacing;
- x2 := x1 + VolBarInnerWidth * IThresholdVals[Ini.ThresholdIndex];
-
- glColor4f(0.3, 0.3, 0.3, 0.6);
- glVertex2f(x1, y1);
- glVertex2f(x1, y2);
- glVertex2f(x2, y2);
- glVertex2f(x2, y1);
- glEnd();
-end;
-
-procedure TScreenOptionsRecord.DrawPitch(const State: TDrawState; x, y, Width, Height: single);
-var
- x1, y1, x2, y2: single;
- i: integer;
- ToneBoxWidth: real;
-const
- PitchBarInnerHSpacing = 2;
- PitchBarInnerVSpacing = 1;
-begin
- // calc tone pitch
- PreviewChannel[State.ChannelIndex].AnalyzeBuffer();
-
- // coordinates for black rect
- x1 := x;
- y1 := y;
- x2 := x + Width;
- y2 := y + Height;
-
- // draw black background-rect
- glColor4f(0, 0, 0, 0.8);
- glBegin(GL_QUADS);
- glVertex2f(x1, y1);
- glVertex2f(x2, y1);
- glVertex2f(x2, y2);
- glVertex2f(x1, y2);
- glEnd();
-
- // coordinates for tone boxes
- ToneBoxWidth := Width / NumHalftones;
- y1 := y1 + PitchBarInnerVSpacing;
- y2 := y2 - PitchBarInnerVSpacing;
-
- glBegin(GL_QUADS);
- // draw tone boxes
- for i := 0 to NumHalftones-1 do
- begin
- x1 := x + i * ToneBoxWidth + PitchBarInnerHSpacing;
- x2 := x1 + ToneBoxWidth - 2*PitchBarInnerHSpacing;
-
- if ((PreviewChannel[State.ChannelIndex].ToneValid) and
- (PreviewChannel[State.ChannelIndex].ToneAbs = i)) then
- begin
- // highlight current tone-pitch
- glColor3f(1, i / (NumHalftones-1), 0)
- end
- else
- begin
- // grey other tone-pitches
- glColor3f(0.3, i / (NumHalftones-1) * 0.3, 0);
- end;
-
- glVertex2f(x1, y1);
- glVertex2f(x2, y1);
- glVertex2f(x2, y2);
- glVertex2f(x1, y2);
- end;
- glEnd();
-
- // update tone-pitch label
- Text[TextPitchID[State.ChannelIndex]].Text :=
- PreviewChannel[State.ChannelIndex].ToneString;
-end;
-
-function TScreenOptionsRecord.Draw: boolean;
-var
- i: integer;
- Device: TAudioInputDevice;
- DeviceCfg: PInputDeviceConfig;
- SelectSlide: TSelectSlide;
- BarXOffset, BarYOffset, BarWidth: real;
- ChannelIndex: integer;
- State: TDrawState;
-begin
- DrawBG;
- DrawFG;
-
- if ((PreviewDeviceIndex >= 0) and
- (PreviewDeviceIndex <= High(AudioInputProcessor.DeviceList))) then
- begin
- Device := AudioInputProcessor.DeviceList[PreviewDeviceIndex];
- DeviceCfg := @Ini.InputDeviceConfig[Device.CfgIndex];
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- // update source volume
- if (SDL_GetTicks() >= NextVolumePollTime) then
- begin
- NextVolumePollTime := SDL_GetTicks() + 500; // next poll in 500ms
- SourceVolume := Device.GetVolume();
- end;
-
- // get source select slide
- SelectSlide := SelectsS[SelectInputSourceID];
- BarXOffset := SelectSlide.TextureSBG.X;
- BarYOffset := SelectSlide.TextureSBG.Y + SelectSlide.TextureSBG.H + BarUpperSpacing;
- BarWidth := SelectSlide.TextureSBG.W;
- DrawVolume(SelectSlide.TextureSBG.X, BarYOffset, BarWidth, BarHeight);
-
- for ChannelIndex := 0 to High(Device.CaptureChannel) do
- begin
- // load player color mapped to current input channel
- if (DeviceCfg.ChannelToPlayerMap[ChannelIndex] > 0) then
- begin
- // set mapped channel to corresponding player-color
- LoadColor(State.R, State.G, State.B, 'P'+ IntToStr(DeviceCfg.ChannelToPlayerMap[ChannelIndex]) + 'Dark');
- end
- else
- begin
- // set non-mapped channel to white
- State.R := 1; State.G := 1; State.B := 1;
- end;
-
- // dark player colors
- State.RD := 0.2 * State.R;
- State.GD := 0.2 * State.G;
- State.BD := 0.2 * State.B;
-
- // channel select slide
- SelectSlide := SelectsS[SelectSlideChannelID[ChannelIndex]];
-
- BarXOffset := SelectSlide.TextureSBG.X;
- BarYOffset := SelectSlide.TextureSBG.Y + SelectSlide.TextureSBG.H + BarUpperSpacing;
- BarWidth := SelectSlide.TextureSBG.W;
-
- State.ChannelIndex := ChannelIndex;
-
- DrawVUMeter(State, BarXOffset, BarYOffset, BarWidth, BarHeight);
- DrawPitch(State, BarXOffset, BarYOffset+BarHeight, BarWidth, BarHeight);
- end;
-
- glDisable(GL_BLEND);
- end;
-
- Result := True;
-end;
-
-
-end.
+unit UScreenOptionsRecord;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UThemes,
+ UMusic,
+ URecord,
+ UMenu;
+
+type
+ TDrawState = record
+ ChannelIndex: integer;
+ R, G, B: real; // mapped player color (normal)
+ RD, GD, BD: real; // mapped player color (dark)
+ end;
+
+ TPeakInfo = record
+ Volume: single;
+ Time: cardinal;
+ end;
+
+ TScreenOptionsRecord = class(TMenu)
+ private
+ // max. count of input-channels determined for all devices
+ MaxChannelCount: integer;
+
+ // current input device
+ CurrentDeviceIndex: integer;
+ PreviewDeviceIndex: integer;
+
+ // string arrays for select-slide options
+ InputSourceNames: array of string;
+ InputDeviceNames: array of string;
+
+ // dynamic generated themes for channel select-sliders
+ SelectSlideChannelTheme: array of TThemeSelectSlide;
+
+ // indices for widget-updates
+ SelectInputSourceID: integer;
+ SelectSlideChannelID: array of integer;
+ TextPitchID: array of integer;
+
+ // interaction IDs
+ ExitButtonIID: integer;
+
+ // dummy data for non-available channels
+ ChannelToPlayerMapDummy: integer;
+
+ // preview channel-buffers
+ PreviewChannel: array of TCaptureBuffer;
+ ChannelPeak: array of TPeakInfo;
+
+ // Device source volume
+ SourceVolume: single;
+ NextVolumePollTime: cardinal;
+
+ procedure StartPreview;
+ procedure StopPreview;
+ procedure UpdateInputDevice;
+ procedure ChangeVolume(VolumeChange: single);
+ procedure DrawVolume(x, y, Width, Height: single);
+ procedure DrawVUMeter(const State: TDrawState; x, y, Width, Height: single);
+ procedure DrawPitch(const State: TDrawState; x, y, Width, Height: single);
+ public
+ constructor Create; override;
+ function Draw: boolean; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure onHide; override;
+ end;
+
+const
+ PeakDecay = 0.2; // strength of peak-decay (reduction after one sec)
+
+const
+ BarHeight = 11; // height of each bar (volume/vu-meter/pitch)
+ BarUpperSpacing = 1; // spacing between a bar-area and the previous widget
+ BarLowerSpacing = 3; // spacing between a bar-area and the next widget
+ SourceBarsTotalHeight = BarHeight + BarUpperSpacing + BarLowerSpacing;
+ ChannelBarsTotalHeight = 2*BarHeight + BarUpperSpacing + BarLowerSpacing;
+
+implementation
+
+uses
+ SysUtils,
+ Math,
+ SDL,
+ gl,
+ UGraphic,
+ UDraw,
+ UMain,
+ UMenuSelectSlide,
+ UMenuText,
+ UFiles,
+ UDisplay,
+ UIni,
+ ULog;
+
+function TScreenOptionsRecord.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ '+':
+ begin
+ // FIXME: add a nice volume-slider instead
+ // or at least provide visualization and acceleration if the user holds the key pressed.
+ ChangeVolume(0.02);
+ end;
+ '-':
+ begin
+ // FIXME: add a nice volume-slider instead
+ // or at least provide visualization and acceleration if the user holds the key pressed.
+ ChangeVolume(-0.02);
+ end;
+ 'T':
+ begin
+ if ((SDL_GetModState() and KMOD_SHIFT) <> 0) then
+ Ini.ThresholdIndex := (Ini.ThresholdIndex + Length(IThresholdVals) - 1) mod Length(IThresholdVals)
+ else
+ Ini.ThresholdIndex := (Ini.ThresholdIndex + 1) mod Length(IThresholdVals);
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE:
+ begin
+ Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+ if (SelInteraction = ExitButtonIID) then
+ begin
+ Ini.Save;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction < ExitButtonIID) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractInc;
+ end;
+ UpdateInputDevice;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction < ExitButtonIID) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Option);
+ InteractDec;
+ end;
+ UpdateInputDevice;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenOptionsRecord.Create;
+var
+ DeviceIndex: integer;
+ SourceIndex: integer;
+ ChannelIndex: integer;
+ InputDevice: TAudioInputDevice;
+ InputDeviceCfg: PInputDeviceConfig;
+ ChannelTheme: ^TThemeSelectSlide;
+ ButtonTheme: TThemeButton;
+ WidgetYPos: integer;
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.OptionsRecord);
+
+ // set CurrentDeviceIndex to a valid device
+ if (Length(AudioInputProcessor.DeviceList) > 0) then
+ CurrentDeviceIndex := 0
+ else
+ CurrentDeviceIndex := -1;
+
+ PreviewDeviceIndex := -1;
+
+ WidgetYPos := 0;
+
+ // init sliders if at least one device was detected
+ if (Length(AudioInputProcessor.DeviceList) > 0) then
+ begin
+ InputDevice := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
+ InputDeviceCfg := @Ini.InputDeviceConfig[InputDevice.CfgIndex];
+
+ // init device-selection slider
+ SetLength(InputDeviceNames, Length(AudioInputProcessor.DeviceList));
+ for DeviceIndex := 0 to High(AudioInputProcessor.DeviceList) do
+ begin
+ InputDeviceNames[DeviceIndex] := AudioInputProcessor.DeviceList[DeviceIndex].Name;
+ end;
+ // add device-selection slider (InteractionID: 0)
+ AddSelectSlide(Theme.OptionsRecord.SelectSlideCard, CurrentDeviceIndex, InputDeviceNames);
+
+ // init source-selection slider
+ SetLength(InputSourceNames, Length(InputDevice.Source));
+ for SourceIndex := 0 to High(InputDevice.Source) do
+ begin
+ InputSourceNames[SourceIndex] := InputDevice.Source[SourceIndex].Name;
+ end;
+ // add source-selection slider (InteractionID: 1)
+ SelectInputSourceID := AddSelectSlide(Theme.OptionsRecord.SelectSlideInput,
+ InputDeviceCfg.Input, InputSourceNames);
+
+ // add space for source volume bar
+ WidgetYPos := Theme.OptionsRecord.SelectSlideInput.Y +
+ Theme.OptionsRecord.SelectSlideInput.H +
+ SourceBarsTotalHeight;
+
+ // find max. channel count of all devices
+ MaxChannelCount := 0;
+ for DeviceIndex := 0 to High(AudioInputProcessor.DeviceList) do
+ begin
+ if (AudioInputProcessor.DeviceList[DeviceIndex].AudioFormat.Channels > MaxChannelCount) then
+ MaxChannelCount := AudioInputProcessor.DeviceList[DeviceIndex].AudioFormat.Channels;
+ end;
+
+ // init channel-to-player mapping sliders
+ SetLength(SelectSlideChannelID, MaxChannelCount);
+ SetLength(SelectSlideChannelTheme, MaxChannelCount);
+ SetLength(TextPitchID, MaxChannelCount);
+
+ for ChannelIndex := 0 to MaxChannelCount-1 do
+ begin
+ // copy reference slide
+ SelectSlideChannelTheme[ChannelIndex] :=
+ Theme.OptionsRecord.SelectSlideChannel;
+ // set current channel-theme
+ ChannelTheme := @SelectSlideChannelTheme[ChannelIndex];
+ // adjust vertical position
+ ChannelTheme.Y := WidgetYPos;
+ // calc size of next slide (add space for bars)
+ WidgetYPos := WidgetYPos + ChannelTheme.H + ChannelBarsTotalHeight;
+ // append channel index to name
+ ChannelTheme.Text := ChannelTheme.Text + IntToStr(ChannelIndex+1);
+
+ // add tone-pitch label
+ TextPitchID[ChannelIndex] := AddText(
+ ChannelTheme.X + ChannelTheme.W,
+ ChannelTheme.Y + ChannelTheme.H/2,
+ '-');
+
+ // show/hide widgets depending on whether the channel exists
+ if (ChannelIndex < Length(InputDeviceCfg.ChannelToPlayerMap)) then
+ begin
+ // current device has this channel
+
+ // add slider
+ SelectSlideChannelID[ChannelIndex] := AddSelectSlide(ChannelTheme^,
+ InputDeviceCfg.ChannelToPlayerMap[ChannelIndex], IChannelPlayer);
+ end
+ else
+ begin
+ // current device does not have that many channels
+
+ // add slider but hide it and assign a dummy variable to it
+ SelectSlideChannelID[ChannelIndex] := AddSelectSlide(ChannelTheme^,
+ ChannelToPlayerMapDummy, IChannelPlayer);
+ SelectsS[SelectSlideChannelID[ChannelIndex]].Visible := false;
+
+ // hide pitch label
+ Text[TextPitchID[ChannelIndex]].Visible := false;
+ end;
+ end;
+ end;
+
+ // add Exit-button
+ ButtonTheme := Theme.OptionsRecord.ButtonExit;
+ // adjust button position
+ if (WidgetYPos <> 0) then
+ ButtonTheme.Y := WidgetYPos;
+ AddButton(ButtonTheme);
+ if (Length(Button[0].Text) = 0) then
+ AddButtonText(14, 20, Theme.Options.Description[7]);
+ // store InteractionID
+ if (Length(AudioInputProcessor.DeviceList) > 0) then
+ ExitButtonIID := MaxChannelCount + 2
+ else
+ ExitButtonIID := 0;
+
+ // set focus
+ Interaction := 0;
+end;
+
+procedure TScreenOptionsRecord.UpdateInputDevice;
+var
+ SourceIndex: integer;
+ InputDevice: TAudioInputDevice;
+ InputDeviceCfg: PInputDeviceConfig;
+ ChannelIndex: integer;
+begin
+ //Log.LogStatus('Update input-device', 'TScreenOptionsRecord.UpdateCard') ;
+
+ StopPreview();
+
+ // set CurrentDeviceIndex to a valid device
+ if (CurrentDeviceIndex > High(AudioInputProcessor.DeviceList)) then
+ CurrentDeviceIndex := 0;
+
+ // update sliders if at least one device was detected
+ if (Length(AudioInputProcessor.DeviceList) > 0) then
+ begin
+ InputDevice := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
+ InputDeviceCfg := @Ini.InputDeviceConfig[InputDevice.CfgIndex];
+
+ // update source-selection slider
+ SetLength(InputSourceNames, Length(InputDevice.Source));
+ for SourceIndex := 0 to High(InputDevice.Source) do
+ begin
+ InputSourceNames[SourceIndex] := InputDevice.Source[SourceIndex].Name;
+ end;
+ UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideInput, SelectInputSourceID,
+ InputSourceNames, InputDeviceCfg.Input);
+
+ // update channel-to-player mapping sliders
+ for ChannelIndex := 0 to MaxChannelCount-1 do
+ begin
+ // show/hide widgets depending on whether the channel exists
+ if (ChannelIndex < Length(InputDeviceCfg.ChannelToPlayerMap)) then
+ begin
+ // current device has this channel
+
+ // show slider
+ UpdateSelectSlideOptions(SelectSlideChannelTheme[ChannelIndex],
+ SelectSlideChannelID[ChannelIndex], IChannelPlayer,
+ InputDeviceCfg.ChannelToPlayerMap[ChannelIndex]);
+ SelectsS[SelectSlideChannelID[ChannelIndex]].Visible := true;
+
+ // show pitch label
+ Text[TextPitchID[ChannelIndex]].Visible := true;
+ end
+ else
+ begin
+ // current device does not have that many channels
+
+ // hide slider and assign a dummy variable to it
+ UpdateSelectSlideOptions(SelectSlideChannelTheme[ChannelIndex],
+ SelectSlideChannelID[ChannelIndex], IChannelPlayer,
+ ChannelToPlayerMapDummy);
+ SelectsS[SelectSlideChannelID[ChannelIndex]].Visible := false;
+
+ // hide pitch label
+ Text[TextPitchID[ChannelIndex]].Visible := false;
+ end;
+ end;
+ end;
+
+ StartPreview();
+end;
+
+procedure TScreenOptionsRecord.ChangeVolume(VolumeChange: single);
+var
+ InputDevice: TAudioInputDevice;
+ Volume: single;
+begin
+ // validate CurrentDeviceIndex
+ if ((CurrentDeviceIndex < 0) or
+ (CurrentDeviceIndex > High(AudioInputProcessor.DeviceList))) then
+ begin
+ Exit;
+ end;
+
+ InputDevice := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
+ if not assigned(InputDevice) then
+ Exit;
+
+ // set new volume
+ Volume := InputDevice.GetVolume() + VolumeChange;
+ InputDevice.SetVolume(Volume);
+ //DebugWriteln('Volume: ' + floattostr(InputDevice.GetVolume));
+
+ // volume must be polled again
+ NextVolumePollTime := 0;
+end;
+
+procedure TScreenOptionsRecord.onShow;
+var
+ ChannelIndex: integer;
+begin
+ inherited;
+
+ Interaction := 0;
+
+ // create preview sound-buffers
+ SetLength(PreviewChannel, MaxChannelCount);
+ for ChannelIndex := 0 to High(PreviewChannel) do
+ PreviewChannel[ChannelIndex] := TCaptureBuffer.Create();
+
+ SetLength(ChannelPeak, MaxChannelCount);
+
+ StartPreview();
+end;
+
+procedure TScreenOptionsRecord.onHide;
+var
+ ChannelIndex: integer;
+begin
+ StopPreview();
+
+ // free preview buffers
+ for ChannelIndex := 0 to High(PreviewChannel) do
+ PreviewChannel[ChannelIndex].Free;
+ SetLength(PreviewChannel, 0);
+ SetLength(ChannelPeak, 0);
+end;
+
+procedure TScreenOptionsRecord.StartPreview;
+var
+ ChannelIndex: integer;
+ Device: TAudioInputDevice;
+begin
+ if ((CurrentDeviceIndex >= 0) and
+ (CurrentDeviceIndex <= High(AudioInputProcessor.DeviceList))) then
+ begin
+ Device := AudioInputProcessor.DeviceList[CurrentDeviceIndex];
+ // set preview channel as active capture channel
+ for ChannelIndex := 0 to High(Device.CaptureChannel) do
+ begin
+ PreviewChannel[ChannelIndex].Clear();
+ Device.LinkCaptureBuffer(ChannelIndex, PreviewChannel[ChannelIndex]);
+ FillChar(ChannelPeak[ChannelIndex], SizeOf(TPeakInfo), 0);
+ end;
+ Device.Start();
+ PreviewDeviceIndex := CurrentDeviceIndex;
+
+ // volume must be polled again
+ NextVolumePollTime := 0;
+ end;
+end;
+
+procedure TScreenOptionsRecord.StopPreview;
+var
+ ChannelIndex: integer;
+ Device: TAudioInputDevice;
+begin
+ if ((PreviewDeviceIndex >= 0) and
+ (PreviewDeviceIndex <= High(AudioInputProcessor.DeviceList))) then
+ begin
+ Device := AudioInputProcessor.DeviceList[PreviewDeviceIndex];
+ Device.Stop;
+ for ChannelIndex := 0 to High(Device.CaptureChannel) do
+ Device.CaptureChannel[ChannelIndex] := nil;
+ end;
+ PreviewDeviceIndex := -1;
+end;
+
+
+procedure TScreenOptionsRecord.DrawVolume(x, y, Width, Height: single);
+var
+ x1, y1, x2, y2: single;
+ VolBarInnerWidth: integer;
+const
+ VolBarInnerHSpacing = 2;
+ VolBarInnerVSpacing = 1;
+begin
+ // coordinates for black rect
+ x1 := x;
+ y1 := y;
+ x2 := x1 + Width;
+ y2 := y1 + Height;
+
+ // draw black background-rect
+ glColor4f(0, 0, 0, 0.8);
+ glBegin(GL_QUADS);
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y1);
+ glVertex2f(x2, y2);
+ glVertex2f(x1, y2);
+ glEnd();
+
+ VolBarInnerWidth := Trunc(Width - 2*VolBarInnerHSpacing);
+
+ // coordinates for first half of the volume bar
+ x1 := x + VolBarInnerHSpacing;
+ x2 := x1 + VolBarInnerWidth * SourceVolume;
+ y1 := y1 + VolBarInnerVSpacing;
+ y2 := y2 - VolBarInnerVSpacing;
+
+ // draw volume-bar
+ glBegin(GL_QUADS);
+ // draw volume bar
+ glColor3f(0.4, 0.3, 0.3);
+ glVertex2f(x1, y1);
+ glVertex2f(x1, y2);
+ glColor3f(1, 0.1, 0.1);
+ glVertex2f(x2, y2);
+ glVertex2f(x2, y1);
+ glEnd();
+
+ { not needed anymore
+ // coordinates for separator
+ x1 := x + VolBarInnerHSpacing;
+ x2 := x1 + VolBarInnerWidth;
+
+ // draw separator
+ glBegin(GL_LINE_STRIP);
+ glColor4f(0.1, 0.1, 0.1, 0.2);
+ glVertex2f(x1, y2);
+ glColor4f(0.4, 0.4, 0.4, 0.2);
+ glVertex2f((x1+x2)/2, y2);
+ glColor4f(0.1, 0.1, 0.1, 0.2);
+ glVertex2f(x2, y2);
+ glEnd();
+ }
+end;
+
+procedure TScreenOptionsRecord.DrawVUMeter(const State: TDrawState; x, y, Width, Height: single);
+var
+ x1, y1, x2, y2: single;
+ Volume, PeakVolume: single;
+ Delta: single;
+ VolBarInnerWidth: integer;
+const
+ VolBarInnerHSpacing = 2;
+ VolBarInnerVSpacing = 1;
+begin
+ // coordinates for black rect
+ x1 := x;
+ y1 := y;
+ x2 := x1 + Width;
+ y2 := y1 + Height;
+
+ // draw black background-rect
+ glColor4f(0, 0, 0, 0.8);
+ glBegin(GL_QUADS);
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y1);
+ glVertex2f(x2, y2);
+ glVertex2f(x1, y2);
+ glEnd();
+
+ VolBarInnerWidth := Trunc(Width - 2*VolBarInnerHSpacing);
+
+ // vertical positions
+ y1 := y1 + VolBarInnerVSpacing;
+ y2 := y2 - VolBarInnerVSpacing;
+
+ // coordinates for bevel
+ x1 := x + VolBarInnerHSpacing;
+ x2 := x1 + VolBarInnerWidth;
+
+ glBegin(GL_QUADS);
+ Volume := PreviewChannel[State.ChannelIndex].MaxSampleVolume();
+
+ // coordinates for volume bar
+ x1 := x + VolBarInnerHSpacing;
+ x2 := x1 + VolBarInnerWidth * Volume;
+
+ // draw volume bar
+ glColor3f(State.RD, State.GD, State.BD);
+ glVertex2f(x1, y1);
+ glVertex2f(x1, y2);
+ glColor3f(State.R, State.G, State.B);
+ glVertex2f(x2, y2);
+ glVertex2f(x2, y1);
+
+ Delta := (SDL_GetTicks() - ChannelPeak[State.ChannelIndex].Time)/1000;
+ PeakVolume := ChannelPeak[State.ChannelIndex].Volume - Delta*Delta*PeakDecay;
+
+ // determine new peak-volume
+ if (Volume > PeakVolume) then
+ begin
+ PeakVolume := Volume;
+ ChannelPeak[State.ChannelIndex].Volume := Volume;
+ ChannelPeak[State.ChannelIndex].Time := SDL_GetTicks();
+ end;
+
+ x1 := x + VolBarInnerHSpacing + VolBarInnerWidth * PeakVolume;
+ x2 := x1 + 2;
+
+ // draw peak
+ glColor3f(0.8, 0.8, 0.8);
+ glVertex2f(x1, y1);
+ glVertex2f(x1, y2);
+ glVertex2f(x2, y2);
+ glVertex2f(x2, y1);
+
+ // draw threshold
+ x1 := x + VolBarInnerHSpacing;
+ x2 := x1 + VolBarInnerWidth * IThresholdVals[Ini.ThresholdIndex];
+
+ glColor4f(0.3, 0.3, 0.3, 0.6);
+ glVertex2f(x1, y1);
+ glVertex2f(x1, y2);
+ glVertex2f(x2, y2);
+ glVertex2f(x2, y1);
+ glEnd();
+end;
+
+procedure TScreenOptionsRecord.DrawPitch(const State: TDrawState; x, y, Width, Height: single);
+var
+ x1, y1, x2, y2: single;
+ i: integer;
+ ToneBoxWidth: real;
+const
+ PitchBarInnerHSpacing = 2;
+ PitchBarInnerVSpacing = 1;
+begin
+ // calc tone pitch
+ PreviewChannel[State.ChannelIndex].AnalyzeBuffer();
+
+ // coordinates for black rect
+ x1 := x;
+ y1 := y;
+ x2 := x + Width;
+ y2 := y + Height;
+
+ // draw black background-rect
+ glColor4f(0, 0, 0, 0.8);
+ glBegin(GL_QUADS);
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y1);
+ glVertex2f(x2, y2);
+ glVertex2f(x1, y2);
+ glEnd();
+
+ // coordinates for tone boxes
+ ToneBoxWidth := Width / NumHalftones;
+ y1 := y1 + PitchBarInnerVSpacing;
+ y2 := y2 - PitchBarInnerVSpacing;
+
+ glBegin(GL_QUADS);
+ // draw tone boxes
+ for i := 0 to NumHalftones-1 do
+ begin
+ x1 := x + i * ToneBoxWidth + PitchBarInnerHSpacing;
+ x2 := x1 + ToneBoxWidth - 2*PitchBarInnerHSpacing;
+
+ if ((PreviewChannel[State.ChannelIndex].ToneValid) and
+ (PreviewChannel[State.ChannelIndex].ToneAbs = i)) then
+ begin
+ // highlight current tone-pitch
+ glColor3f(1, i / (NumHalftones-1), 0)
+ end
+ else
+ begin
+ // grey other tone-pitches
+ glColor3f(0.3, i / (NumHalftones-1) * 0.3, 0);
+ end;
+
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y1);
+ glVertex2f(x2, y2);
+ glVertex2f(x1, y2);
+ end;
+ glEnd();
+
+ // update tone-pitch label
+ Text[TextPitchID[State.ChannelIndex]].Text :=
+ PreviewChannel[State.ChannelIndex].ToneString;
+end;
+
+function TScreenOptionsRecord.Draw: boolean;
+var
+ i: integer;
+ Device: TAudioInputDevice;
+ DeviceCfg: PInputDeviceConfig;
+ SelectSlide: TSelectSlide;
+ BarXOffset, BarYOffset, BarWidth: real;
+ ChannelIndex: integer;
+ State: TDrawState;
+begin
+ DrawBG;
+ DrawFG;
+
+ if ((PreviewDeviceIndex >= 0) and
+ (PreviewDeviceIndex <= High(AudioInputProcessor.DeviceList))) then
+ begin
+ Device := AudioInputProcessor.DeviceList[PreviewDeviceIndex];
+ DeviceCfg := @Ini.InputDeviceConfig[Device.CfgIndex];
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ // update source volume
+ if (SDL_GetTicks() >= NextVolumePollTime) then
+ begin
+ NextVolumePollTime := SDL_GetTicks() + 500; // next poll in 500ms
+ SourceVolume := Device.GetVolume();
+ end;
+
+ // get source select slide
+ SelectSlide := SelectsS[SelectInputSourceID];
+ BarXOffset := SelectSlide.TextureSBG.X;
+ BarYOffset := SelectSlide.TextureSBG.Y + SelectSlide.TextureSBG.H + BarUpperSpacing;
+ BarWidth := SelectSlide.TextureSBG.W;
+ DrawVolume(SelectSlide.TextureSBG.X, BarYOffset, BarWidth, BarHeight);
+
+ for ChannelIndex := 0 to High(Device.CaptureChannel) do
+ begin
+ // load player color mapped to current input channel
+ if (DeviceCfg.ChannelToPlayerMap[ChannelIndex] > 0) then
+ begin
+ // set mapped channel to corresponding player-color
+ LoadColor(State.R, State.G, State.B, 'P'+ IntToStr(DeviceCfg.ChannelToPlayerMap[ChannelIndex]) + 'Dark');
+ end
+ else
+ begin
+ // set non-mapped channel to white
+ State.R := 1; State.G := 1; State.B := 1;
+ end;
+
+ // dark player colors
+ State.RD := 0.2 * State.R;
+ State.GD := 0.2 * State.G;
+ State.BD := 0.2 * State.B;
+
+ // channel select slide
+ SelectSlide := SelectsS[SelectSlideChannelID[ChannelIndex]];
+
+ BarXOffset := SelectSlide.TextureSBG.X;
+ BarYOffset := SelectSlide.TextureSBG.Y + SelectSlide.TextureSBG.H + BarUpperSpacing;
+ BarWidth := SelectSlide.TextureSBG.W;
+
+ State.ChannelIndex := ChannelIndex;
+
+ DrawVUMeter(State, BarXOffset, BarYOffset, BarWidth, BarHeight);
+ DrawPitch(State, BarXOffset, BarYOffset+BarHeight, BarWidth, BarHeight);
+ end;
+
+ glDisable(GL_BLEND);
+ end;
+
+ Result := True;
+end;
+
+
+end.
diff --git a/Game/Code/Screens/UScreenPartyPlayer.pas b/Game/Code/Screens/UScreenPartyPlayer.pas
index c8600c9b..fa717677 100644
--- a/Game/Code/Screens/UScreenPartyPlayer.pas
+++ b/Game/Code/Screens/UScreenPartyPlayer.pas
@@ -65,15 +65,15 @@ begin
begin // Key Down
// check normal keys
- case CharCode of
+ case CharCode of
'0'..'9', 'a'..'z', 'A'..'Z', ' ', '-', '_', '!', ',', '<', '/', '*', '?', '''', '"':
begin
Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + CharCode;
Exit;
end;
end;
-
- // check special keys
+
+ // check special keys
case PressedKey of
// Templates for Names Mod
SDLK_F1:
diff --git a/Game/Code/Screens/UScreenPartyScore.pas b/Game/Code/Screens/UScreenPartyScore.pas
index e7b53196..176a94b2 100644
--- a/Game/Code/Screens/UScreenPartyScore.pas
+++ b/Game/Code/Screens/UScreenPartyScore.pas
@@ -1,302 +1,302 @@
-unit UScreenPartyScore;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UDisplay, UMusic, SysUtils, UThemes;
-
-type
- TScreenPartyScore = class(TMenu)
- public
- TextScoreTeam1: Cardinal;
- TextScoreTeam2: Cardinal;
- TextScoreTeam3: Cardinal;
- TextNameTeam1: Cardinal;
- TextNameTeam2: Cardinal;
- TextNameTeam3: Cardinal;
- StaticTeam1: Cardinal;
- StaticTeam1BG: Cardinal;
- StaticTeam1Deco: Cardinal;
- StaticTeam2: Cardinal;
- StaticTeam2BG: Cardinal;
- StaticTeam2Deco: Cardinal;
- StaticTeam3: Cardinal;
- StaticTeam3BG: Cardinal;
- StaticTeam3Deco: Cardinal;
- TextWinner: Cardinal;
-
- DecoTex: Array[0..5] of Integer;
- DecoColor: Array[0..5] of Record
- R, G, B: Real;
- end;
-
- MaxScore: Word;
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure SetAnimationProgress(Progress: real); override;
- end;
-
-implementation
-
-uses UGraphic, UMain, UParty, UScreenSingModi, ULanguage, UTexture, USkins;
-
-function TScreenPartyScore.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- {if (PartySession.CurRound < High(PartySession.Rounds)) then
- FadeTo(@ScreenPartyNewRound)
- else // to-do : Party
- begin
- PartySession.EndRound; }
- FadeTo(@ScreenPartyWin);
- //end;
- end;
-
- SDLK_RETURN:
- begin
- AudioPlayback.PlaySound(SoundLib.Start);
- // to-do : Party
- {if (PartySession.CurRound < High(PartySession.Rounds)) then
- FadeTo(@ScreenPartyNewRound)
- else }
- FadeTo(@ScreenPartyWin);
- end;
- end;
- end;
-end;
-
-constructor TScreenPartyScore.Create;
-var
-// I: integer; // Auto Removed, Unused Variable
- Tex: TTexture;
- R, G, B: Real;
- Color: Integer;
-begin
- inherited Create;
-
- TextScoreTeam1 := AddText (Theme.PartyScore.TextScoreTeam1);
- TextScoreTeam2 := AddText (Theme.PartyScore.TextScoreTeam2);
- TextScoreTeam3 := AddText (Theme.PartyScore.TextScoreTeam3);
- TextNameTeam1 := AddText (Theme.PartyScore.TextNameTeam1);
- TextNameTeam2 := AddText (Theme.PartyScore.TextNameTeam2);
- TextNameTeam3 := AddText (Theme.PartyScore.TextNameTeam3);
-
- StaticTeam1 := AddStatic (Theme.PartyScore.StaticTeam1);
- StaticTeam1BG := AddStatic (Theme.PartyScore.StaticTeam1BG);
- StaticTeam1Deco := AddStatic (Theme.PartyScore.StaticTeam1Deco);
- StaticTeam2 := AddStatic (Theme.PartyScore.StaticTeam2);
- StaticTeam2BG := AddStatic (Theme.PartyScore.StaticTeam2BG);
- StaticTeam2Deco := AddStatic (Theme.PartyScore.StaticTeam2Deco);
- StaticTeam3 := AddStatic (Theme.PartyScore.StaticTeam3);
- StaticTeam3BG := AddStatic (Theme.PartyScore.StaticTeam3BG);
- StaticTeam3Deco := AddStatic (Theme.PartyScore.StaticTeam3Deco);
-
- TextWinner := AddText (Theme.PartyScore.TextWinner);
-
- //Load Deco Textures
- if Theme.PartyScore.DecoTextures.ChangeTextures then
- begin
- //Get Color
- LoadColor(R, G, B, Theme.PartyScore.DecoTextures.FirstColor);
- Color := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
- DecoColor[0].R := R;
- DecoColor[0].G := G;
- DecoColor[0].B := B;
-
- //Load Texture
- Tex := Texture.LoadTexture(pchar(Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.FirstTexture)), Theme.PartyScore.DecoTextures.FirstTyp, Color);
- DecoTex[0] := Tex.TexNum;
-
- //Get Second Color
- LoadColor(R, G, B, Theme.PartyScore.DecoTextures.SecondColor);
- Color := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
- DecoColor[1].R := R;
- DecoColor[1].G := G;
- DecoColor[1].B := B;
-
- //Load Second Texture
- Tex := Texture.LoadTexture(pchar(Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.SecondTexture)), Theme.PartyScore.DecoTextures.SecondTyp, Color);
- DecoTex[1] := Tex.TexNum;
-
- //Get Third Color
- LoadColor(R, G, B, Theme.PartyScore.DecoTextures.ThirdColor);
- Color := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
- DecoColor[2].R := R;
- DecoColor[2].G := G;
- DecoColor[2].B := B;
-
- //Load Third Texture
- Tex := Texture.LoadTexture(pchar(Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.ThirdTexture)), Theme.PartyScore.DecoTextures.ThirdTyp, Color);
- DecoTex[2] := Tex.TexNum;
- end;
-
- LoadFromTheme(Theme.PartyScore);
-end;
-
-procedure TScreenPartyScore.onShow;
-var
- I, J: Integer;
- Placings: Array [0..5] of Byte;
-begin
- inherited;
-
-
- //Get Maxscore
-
- MaxScore := 0;
- for I := 0 to ScreenSingModi.PlayerInfo.NumPlayers - 1 do
- begin
- if (ScreenSingModi.PlayerInfo.Playerinfo[I].Score > MaxScore) then
- MaxScore := ScreenSingModi.PlayerInfo.Playerinfo[I].Score;
- end;
-
- //Get Placings
- for I := 0 to ScreenSingModi.PlayerInfo.NumPlayers - 1 do
- begin
- Placings[I] := 0;
- for J := 0 to ScreenSingModi.PlayerInfo.NumPlayers - 1 do
- If (ScreenSingModi.PlayerInfo.Playerinfo[J].Score > ScreenSingModi.PlayerInfo.Playerinfo[I].Score) then
- Inc(Placings[I]);
- end;
-
-
- //Set Static Length
- Static[StaticTeam1].Texture.ScaleW := ScreenSingModi.PlayerInfo.Playerinfo[0].Percentage / 100;
- Static[StaticTeam2].Texture.ScaleW := ScreenSingModi.PlayerInfo.Playerinfo[1].Percentage / 100;
- Static[StaticTeam3].Texture.ScaleW := ScreenSingModi.PlayerInfo.Playerinfo[2].Percentage / 100;
-
- //fix: prevents static from drawn out of bounds.
- if Static[StaticTeam1].Texture.ScaleW > 99 then Static[StaticTeam1].Texture.ScaleW := 99;
- if Static[StaticTeam2].Texture.ScaleW > 99 then Static[StaticTeam2].Texture.ScaleW := 99;
- if Static[StaticTeam3].Texture.ScaleW > 99 then Static[StaticTeam3].Texture.ScaleW := 99;
-
- //End Last Round // to-do : Party
- //PartySession.EndRound;
-
- //Set Winnertext
- //Text[TextWinner].Text := Format(Language.Translate('PARTY_SCORE_WINS'), [PartySession.GetWinnerString(PartySession.CurRound)]);
-
- if (ScreenSingModi.PlayerInfo.NumPlayers >= 1) then
- begin
- Text[TextScoreTeam1].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[0].Score);
- Text[TextNameTeam1].Text := String(ScreenSingModi.TeamInfo.Teaminfo[0].Name);
-
- //Set Deco Texture
- if Theme.PartyScore.DecoTextures.ChangeTextures then
- begin
- Static[StaticTeam1Deco].Texture.TexNum := DecoTex[Placings[0]];
- Static[StaticTeam1Deco].Texture.ColR := DecoColor[Placings[0]].R;
- Static[StaticTeam1Deco].Texture.ColG := DecoColor[Placings[0]].G;
- Static[StaticTeam1Deco].Texture.ColB := DecoColor[Placings[0]].B;
- end;
-
- Text[TextScoreTeam1].Visible := True;
- Text[TextNameTeam1].Visible := True;
- Static[StaticTeam1].Visible := True;
- Static[StaticTeam1BG].Visible := True;
- Static[StaticTeam1Deco].Visible := True;
- end
- else
- begin
- Text[TextScoreTeam1].Visible := False;
- Text[TextNameTeam1].Visible := False;
- Static[StaticTeam1].Visible := False;
- Static[StaticTeam1BG].Visible := False;
- Static[StaticTeam1Deco].Visible := False;
- end;
-
- if (ScreenSingModi.PlayerInfo.NumPlayers >= 2) then
- begin
- Text[TextScoreTeam2].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[1].Score);
- Text[TextNameTeam2].Text := String(ScreenSingModi.TeamInfo.Teaminfo[1].Name);
-
- //Set Deco Texture
- if Theme.PartyScore.DecoTextures.ChangeTextures then
- begin
- Static[StaticTeam2Deco].Texture.TexNum := DecoTex[Placings[1]];
- Static[StaticTeam2Deco].Texture.ColR := DecoColor[Placings[1]].R;
- Static[StaticTeam2Deco].Texture.ColG := DecoColor[Placings[1]].G;
- Static[StaticTeam2Deco].Texture.ColB := DecoColor[Placings[1]].B;
- end;
-
- Text[TextScoreTeam2].Visible := True;
- Text[TextNameTeam2].Visible := True;
- Static[StaticTeam2].Visible := True;
- Static[StaticTeam2BG].Visible := True;
- Static[StaticTeam2Deco].Visible := True;
- end
- else
- begin
- Text[TextScoreTeam2].Visible := False;
- Text[TextNameTeam2].Visible := False;
- Static[StaticTeam2].Visible := False;
- Static[StaticTeam2BG].Visible := False;
- Static[StaticTeam2Deco].Visible := False;
- end;
-
- if (ScreenSingModi.PlayerInfo.NumPlayers >= 3) then
- begin
- Text[TextScoreTeam3].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[2].Score);
- Text[TextNameTeam3].Text := String(ScreenSingModi.TeamInfo.Teaminfo[2].Name);
-
- //Set Deco Texture
- if Theme.PartyScore.DecoTextures.ChangeTextures then
- begin
- Static[StaticTeam3Deco].Texture.TexNum := DecoTex[Placings[2]];
- Static[StaticTeam3Deco].Texture.ColR := DecoColor[Placings[2]].R;
- Static[StaticTeam3Deco].Texture.ColG := DecoColor[Placings[2]].G;
- Static[StaticTeam3Deco].Texture.ColB := DecoColor[Placings[2]].B;
- end;
-
- Text[TextScoreTeam3].Visible := True;
- Text[TextNameTeam3].Visible := True;
- Static[StaticTeam3].Visible := True;
- Static[StaticTeam3BG].Visible := True;
- Static[StaticTeam3Deco].Visible := True;
- end
- else
- begin
- Text[TextScoreTeam3].Visible := False;
- Text[TextNameTeam3].Visible := False;
- Static[StaticTeam3].Visible := False;
- Static[StaticTeam3BG].Visible := False;
- Static[StaticTeam3Deco].Visible := False;
- end;
-
-
-// LCD.WriteText(1, ' Choose mode: ');
-// UpdateLCD;
-end;
-
-procedure TScreenPartyScore.SetAnimationProgress(Progress: real);
-begin
- if (ScreenSingModi.PlayerInfo.NumPlayers >= 1) then
- Static[StaticTeam1].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[0].Percentage / 100;
- if (ScreenSingModi.PlayerInfo.NumPlayers >= 2) then
- Static[StaticTeam2].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[1].Percentage / 100;
- if (ScreenSingModi.PlayerInfo.NumPlayers >= 3) then
- Static[StaticTeam3].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[2].Percentage / 100;
-end;
-
-end.
+unit UScreenPartyScore;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UDisplay, UMusic, SysUtils, UThemes;
+
+type
+ TScreenPartyScore = class(TMenu)
+ public
+ TextScoreTeam1: Cardinal;
+ TextScoreTeam2: Cardinal;
+ TextScoreTeam3: Cardinal;
+ TextNameTeam1: Cardinal;
+ TextNameTeam2: Cardinal;
+ TextNameTeam3: Cardinal;
+ StaticTeam1: Cardinal;
+ StaticTeam1BG: Cardinal;
+ StaticTeam1Deco: Cardinal;
+ StaticTeam2: Cardinal;
+ StaticTeam2BG: Cardinal;
+ StaticTeam2Deco: Cardinal;
+ StaticTeam3: Cardinal;
+ StaticTeam3BG: Cardinal;
+ StaticTeam3Deco: Cardinal;
+ TextWinner: Cardinal;
+
+ DecoTex: Array[0..5] of Integer;
+ DecoColor: Array[0..5] of Record
+ R, G, B: Real;
+ end;
+
+ MaxScore: Word;
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic, UMain, UParty, UScreenSingModi, ULanguage, UTexture, USkins;
+
+function TScreenPartyScore.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ {if (PartySession.CurRound < High(PartySession.Rounds)) then
+ FadeTo(@ScreenPartyNewRound)
+ else // to-do : Party
+ begin
+ PartySession.EndRound; }
+ FadeTo(@ScreenPartyWin);
+ //end;
+ end;
+
+ SDLK_RETURN:
+ begin
+ AudioPlayback.PlaySound(SoundLib.Start);
+ // to-do : Party
+ {if (PartySession.CurRound < High(PartySession.Rounds)) then
+ FadeTo(@ScreenPartyNewRound)
+ else }
+ FadeTo(@ScreenPartyWin);
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenPartyScore.Create;
+var
+// I: integer; // Auto Removed, Unused Variable
+ Tex: TTexture;
+ R, G, B: Real;
+ Color: Integer;
+begin
+ inherited Create;
+
+ TextScoreTeam1 := AddText (Theme.PartyScore.TextScoreTeam1);
+ TextScoreTeam2 := AddText (Theme.PartyScore.TextScoreTeam2);
+ TextScoreTeam3 := AddText (Theme.PartyScore.TextScoreTeam3);
+ TextNameTeam1 := AddText (Theme.PartyScore.TextNameTeam1);
+ TextNameTeam2 := AddText (Theme.PartyScore.TextNameTeam2);
+ TextNameTeam3 := AddText (Theme.PartyScore.TextNameTeam3);
+
+ StaticTeam1 := AddStatic (Theme.PartyScore.StaticTeam1);
+ StaticTeam1BG := AddStatic (Theme.PartyScore.StaticTeam1BG);
+ StaticTeam1Deco := AddStatic (Theme.PartyScore.StaticTeam1Deco);
+ StaticTeam2 := AddStatic (Theme.PartyScore.StaticTeam2);
+ StaticTeam2BG := AddStatic (Theme.PartyScore.StaticTeam2BG);
+ StaticTeam2Deco := AddStatic (Theme.PartyScore.StaticTeam2Deco);
+ StaticTeam3 := AddStatic (Theme.PartyScore.StaticTeam3);
+ StaticTeam3BG := AddStatic (Theme.PartyScore.StaticTeam3BG);
+ StaticTeam3Deco := AddStatic (Theme.PartyScore.StaticTeam3Deco);
+
+ TextWinner := AddText (Theme.PartyScore.TextWinner);
+
+ //Load Deco Textures
+ if Theme.PartyScore.DecoTextures.ChangeTextures then
+ begin
+ //Get Color
+ LoadColor(R, G, B, Theme.PartyScore.DecoTextures.FirstColor);
+ Color := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
+ DecoColor[0].R := R;
+ DecoColor[0].G := G;
+ DecoColor[0].B := B;
+
+ //Load Texture
+ Tex := Texture.LoadTexture(pchar(Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.FirstTexture)), Theme.PartyScore.DecoTextures.FirstTyp, Color);
+ DecoTex[0] := Tex.TexNum;
+
+ //Get Second Color
+ LoadColor(R, G, B, Theme.PartyScore.DecoTextures.SecondColor);
+ Color := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
+ DecoColor[1].R := R;
+ DecoColor[1].G := G;
+ DecoColor[1].B := B;
+
+ //Load Second Texture
+ Tex := Texture.LoadTexture(pchar(Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.SecondTexture)), Theme.PartyScore.DecoTextures.SecondTyp, Color);
+ DecoTex[1] := Tex.TexNum;
+
+ //Get Third Color
+ LoadColor(R, G, B, Theme.PartyScore.DecoTextures.ThirdColor);
+ Color := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
+ DecoColor[2].R := R;
+ DecoColor[2].G := G;
+ DecoColor[2].B := B;
+
+ //Load Third Texture
+ Tex := Texture.LoadTexture(pchar(Skin.GetTextureFileName(Theme.PartyScore.DecoTextures.ThirdTexture)), Theme.PartyScore.DecoTextures.ThirdTyp, Color);
+ DecoTex[2] := Tex.TexNum;
+ end;
+
+ LoadFromTheme(Theme.PartyScore);
+end;
+
+procedure TScreenPartyScore.onShow;
+var
+ I, J: Integer;
+ Placings: Array [0..5] of Byte;
+begin
+ inherited;
+
+
+ //Get Maxscore
+
+ MaxScore := 0;
+ for I := 0 to ScreenSingModi.PlayerInfo.NumPlayers - 1 do
+ begin
+ if (ScreenSingModi.PlayerInfo.Playerinfo[I].Score > MaxScore) then
+ MaxScore := ScreenSingModi.PlayerInfo.Playerinfo[I].Score;
+ end;
+
+ //Get Placings
+ for I := 0 to ScreenSingModi.PlayerInfo.NumPlayers - 1 do
+ begin
+ Placings[I] := 0;
+ for J := 0 to ScreenSingModi.PlayerInfo.NumPlayers - 1 do
+ If (ScreenSingModi.PlayerInfo.Playerinfo[J].Score > ScreenSingModi.PlayerInfo.Playerinfo[I].Score) then
+ Inc(Placings[I]);
+ end;
+
+
+ //Set Static Length
+ Static[StaticTeam1].Texture.ScaleW := ScreenSingModi.PlayerInfo.Playerinfo[0].Percentage / 100;
+ Static[StaticTeam2].Texture.ScaleW := ScreenSingModi.PlayerInfo.Playerinfo[1].Percentage / 100;
+ Static[StaticTeam3].Texture.ScaleW := ScreenSingModi.PlayerInfo.Playerinfo[2].Percentage / 100;
+
+ //fix: prevents static from drawn out of bounds.
+ if Static[StaticTeam1].Texture.ScaleW > 99 then Static[StaticTeam1].Texture.ScaleW := 99;
+ if Static[StaticTeam2].Texture.ScaleW > 99 then Static[StaticTeam2].Texture.ScaleW := 99;
+ if Static[StaticTeam3].Texture.ScaleW > 99 then Static[StaticTeam3].Texture.ScaleW := 99;
+
+ //End Last Round // to-do : Party
+ //PartySession.EndRound;
+
+ //Set Winnertext
+ //Text[TextWinner].Text := Format(Language.Translate('PARTY_SCORE_WINS'), [PartySession.GetWinnerString(PartySession.CurRound)]);
+
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 1) then
+ begin
+ Text[TextScoreTeam1].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[0].Score);
+ Text[TextNameTeam1].Text := String(ScreenSingModi.TeamInfo.Teaminfo[0].Name);
+
+ //Set Deco Texture
+ if Theme.PartyScore.DecoTextures.ChangeTextures then
+ begin
+ Static[StaticTeam1Deco].Texture.TexNum := DecoTex[Placings[0]];
+ Static[StaticTeam1Deco].Texture.ColR := DecoColor[Placings[0]].R;
+ Static[StaticTeam1Deco].Texture.ColG := DecoColor[Placings[0]].G;
+ Static[StaticTeam1Deco].Texture.ColB := DecoColor[Placings[0]].B;
+ end;
+
+ Text[TextScoreTeam1].Visible := True;
+ Text[TextNameTeam1].Visible := True;
+ Static[StaticTeam1].Visible := True;
+ Static[StaticTeam1BG].Visible := True;
+ Static[StaticTeam1Deco].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam1].Visible := False;
+ Text[TextNameTeam1].Visible := False;
+ Static[StaticTeam1].Visible := False;
+ Static[StaticTeam1BG].Visible := False;
+ Static[StaticTeam1Deco].Visible := False;
+ end;
+
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 2) then
+ begin
+ Text[TextScoreTeam2].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[1].Score);
+ Text[TextNameTeam2].Text := String(ScreenSingModi.TeamInfo.Teaminfo[1].Name);
+
+ //Set Deco Texture
+ if Theme.PartyScore.DecoTextures.ChangeTextures then
+ begin
+ Static[StaticTeam2Deco].Texture.TexNum := DecoTex[Placings[1]];
+ Static[StaticTeam2Deco].Texture.ColR := DecoColor[Placings[1]].R;
+ Static[StaticTeam2Deco].Texture.ColG := DecoColor[Placings[1]].G;
+ Static[StaticTeam2Deco].Texture.ColB := DecoColor[Placings[1]].B;
+ end;
+
+ Text[TextScoreTeam2].Visible := True;
+ Text[TextNameTeam2].Visible := True;
+ Static[StaticTeam2].Visible := True;
+ Static[StaticTeam2BG].Visible := True;
+ Static[StaticTeam2Deco].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam2].Visible := False;
+ Text[TextNameTeam2].Visible := False;
+ Static[StaticTeam2].Visible := False;
+ Static[StaticTeam2BG].Visible := False;
+ Static[StaticTeam2Deco].Visible := False;
+ end;
+
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 3) then
+ begin
+ Text[TextScoreTeam3].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[2].Score);
+ Text[TextNameTeam3].Text := String(ScreenSingModi.TeamInfo.Teaminfo[2].Name);
+
+ //Set Deco Texture
+ if Theme.PartyScore.DecoTextures.ChangeTextures then
+ begin
+ Static[StaticTeam3Deco].Texture.TexNum := DecoTex[Placings[2]];
+ Static[StaticTeam3Deco].Texture.ColR := DecoColor[Placings[2]].R;
+ Static[StaticTeam3Deco].Texture.ColG := DecoColor[Placings[2]].G;
+ Static[StaticTeam3Deco].Texture.ColB := DecoColor[Placings[2]].B;
+ end;
+
+ Text[TextScoreTeam3].Visible := True;
+ Text[TextNameTeam3].Visible := True;
+ Static[StaticTeam3].Visible := True;
+ Static[StaticTeam3BG].Visible := True;
+ Static[StaticTeam3Deco].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam3].Visible := False;
+ Text[TextNameTeam3].Visible := False;
+ Static[StaticTeam3].Visible := False;
+ Static[StaticTeam3BG].Visible := False;
+ Static[StaticTeam3Deco].Visible := False;
+ end;
+
+
+// LCD.WriteText(1, ' Choose mode: ');
+// UpdateLCD;
+end;
+
+procedure TScreenPartyScore.SetAnimationProgress(Progress: real);
+begin
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 1) then
+ Static[StaticTeam1].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[0].Percentage / 100;
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 2) then
+ Static[StaticTeam2].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[1].Percentage / 100;
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 3) then
+ Static[StaticTeam3].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[2].Percentage / 100;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenPopup.pas b/Game/Code/Screens/UScreenPopup.pas
index 328e9851..b51fac98 100644
--- a/Game/Code/Screens/UScreenPopup.pas
+++ b/Game/Code/Screens/UScreenPopup.pas
@@ -1,252 +1,252 @@
-unit UScreenPopup;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, UMusic, UFiles, SysUtils, UThemes;
-
-type
- TScreenPopupCheck = class(TMenu)
- public
- Visible: Boolean; //Whether the Menu should be Drawn
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure ShowPopup(msg: String);
- function Draw: boolean; override;
- end;
-
-type
- TScreenPopupError = class(TMenu)
-{ private
- CurMenu: Byte; //Num of the cur. Shown Menu}
- public
- Visible: Boolean; //Whether the Menu should be Drawn
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure onHide; override;
- procedure ShowPopup(msg: String);
- function Draw: boolean; override;
- end;
-
-var
-// ISelections: Array of String;
- SelectValue: Integer;
-
-
-implementation
-
-uses UGraphic, UMain, UIni, UTexture, ULanguage, UParty, UPlaylist, UDisplay;
-
-function TScreenPopupCheck.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- Display.CheckOK:=False;
- Display.NextScreenWithCheck:=NIL;
- Visible:=False;
- Result := false;
- end;
-
- SDLK_RETURN:
- begin
- case Interaction of
- 0: begin
- //Hack to Finish Singscreen correct on Exit with Q Shortcut
- if (Display.NextScreenWithCheck = NIL) then
- begin
- if (Display.CurrentScreen = @ScreenSing) then
- ScreenSing.Finish
- else if (Display.CurrentScreen = @ScreenSingModi) then
- ScreenSingModi.Finish;
- end;
-
- Display.CheckOK:=True;
- end;
- 1: begin
- Display.CheckOK:=False;
- Display.NextScreenWithCheck:=NIL;
- end;
- end;
- Visible:=False;
- Result := false;
- end;
-
- SDLK_DOWN: InteractNext;
- SDLK_UP: InteractPrev;
-
- SDLK_RIGHT: InteractNext;
- SDLK_LEFT: InteractPrev;
- end;
- end;
-end;
-
-constructor TScreenPopupCheck.Create;
-var
- I: integer;
-begin
- inherited Create;
-
- AddBackground(Theme.CheckPopup.Background.Tex);
-
- AddButton(Theme.CheckPopup.Button1);
- if (Length(Button[0].Text) = 0) then
- AddButtonText(14, 20, 'Button 1');
-
- AddButton(Theme.CheckPopup.Button2);
- if (Length(Button[1].Text) = 0) then
- AddButtonText(14, 20, 'Button 2');
-
- AddText(Theme.CheckPopup.TextCheck);
-
- for I := 0 to High(Theme.CheckPopup.Static) do
- AddStatic(Theme.CheckPopup.Static[I]);
-
- for I := 0 to High(Theme.CheckPopup.Text) do
- AddText(Theme.CheckPopup.Text[I]);
-
- Interaction := 0;
-end;
-
-function TScreenPopupCheck.Draw: boolean;
-begin
- Draw:=inherited Draw;
-end;
-
-procedure TScreenPopupCheck.onShow;
-begin
- inherited;
-end;
-
-procedure TScreenPopupCheck.ShowPopup(msg: String);
-begin
- Interaction := 0; //Reset Interaction
- Visible := True; //Set Visible
-
- Text[0].Text := Language.Translate(msg);
-
- Button[0].Visible := True;
- Button[1].Visible := True;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_YES');
- Button[1].Text[0].Text := Language.Translate('SONG_MENU_NO');
-end;
-
-// error popup
-
-function TScreenPopupError.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
-
- case PressedKey of
- SDLK_Q:
- begin
- Result := false;
- end;
-
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- Visible:=False;
- Result := false;
- end;
-
- SDLK_RETURN:
- begin
- Visible:=False;
- Result := false;
- end;
-
- SDLK_DOWN: InteractNext;
- SDLK_UP: InteractPrev;
-
- SDLK_RIGHT: InteractNext;
- SDLK_LEFT: InteractPrev;
- end;
- end;
-end;
-
-constructor TScreenPopupError.Create;
-var
- I: integer;
-begin
- inherited Create;
-
- AddBackground(Theme.CheckPopup.Background.Tex);
-
- AddButton(Theme.ErrorPopup.Button1);
- if (Length(Button[0].Text) = 0) then
- AddButtonText(14, 20, 'Button 1');
-
- AddText(Theme.ErrorPopup.TextError);
-
- for I := 0 to High(Theme.ErrorPopup.Static) do
- AddStatic(Theme.ErrorPopup.Static[I]);
-
- for I := 0 to High(Theme.ErrorPopup.Text) do
- AddText(Theme.ErrorPopup.Text[I]);
-
- Interaction := 0;
-end;
-
-function TScreenPopupError.Draw: boolean;
-begin
- Draw:=inherited Draw;
-end;
-
-procedure TScreenPopupError.onShow;
-begin
- inherited;
-
-end;
-
-procedure TScreenPopupError.onHide;
-begin
-end;
-
-procedure TScreenPopupError.ShowPopup(msg: String);
-begin
- Interaction := 0; //Reset Interaction
- Visible := True; //Set Visible
-
-{ //dirty hack... Text[0] is invisible for some strange reason
- for i:=1 to high(Text) do
- if i-1 <= high(msg) then
- begin
- Text[i].Visible:=True;
- Text[i].Text := msg[i-1];
- end
- else
- begin
- Text[i].Visible:=False;
- end;}
- Text[0].Text:=msg;
-
- Button[0].Visible := True;
-
- Button[0].Text[0].Text := 'OK';
-end;
-
-end.
+unit UScreenPopup;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, UMusic, UFiles, SysUtils, UThemes;
+
+type
+ TScreenPopupCheck = class(TMenu)
+ public
+ Visible: Boolean; //Whether the Menu should be Drawn
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure ShowPopup(msg: String);
+ function Draw: boolean; override;
+ end;
+
+type
+ TScreenPopupError = class(TMenu)
+{ private
+ CurMenu: Byte; //Num of the cur. Shown Menu}
+ public
+ Visible: Boolean; //Whether the Menu should be Drawn
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure onHide; override;
+ procedure ShowPopup(msg: String);
+ function Draw: boolean; override;
+ end;
+
+var
+// ISelections: Array of String;
+ SelectValue: Integer;
+
+
+implementation
+
+uses UGraphic, UMain, UIni, UTexture, ULanguage, UParty, UPlaylist, UDisplay;
+
+function TScreenPopupCheck.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ Display.CheckOK:=False;
+ Display.NextScreenWithCheck:=NIL;
+ Visible:=False;
+ Result := false;
+ end;
+
+ SDLK_RETURN:
+ begin
+ case Interaction of
+ 0: begin
+ //Hack to Finish Singscreen correct on Exit with Q Shortcut
+ if (Display.NextScreenWithCheck = NIL) then
+ begin
+ if (Display.CurrentScreen = @ScreenSing) then
+ ScreenSing.Finish
+ else if (Display.CurrentScreen = @ScreenSingModi) then
+ ScreenSingModi.Finish;
+ end;
+
+ Display.CheckOK:=True;
+ end;
+ 1: begin
+ Display.CheckOK:=False;
+ Display.NextScreenWithCheck:=NIL;
+ end;
+ end;
+ Visible:=False;
+ Result := false;
+ end;
+
+ SDLK_DOWN: InteractNext;
+ SDLK_UP: InteractPrev;
+
+ SDLK_RIGHT: InteractNext;
+ SDLK_LEFT: InteractPrev;
+ end;
+ end;
+end;
+
+constructor TScreenPopupCheck.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ AddBackground(Theme.CheckPopup.Background.Tex);
+
+ AddButton(Theme.CheckPopup.Button1);
+ if (Length(Button[0].Text) = 0) then
+ AddButtonText(14, 20, 'Button 1');
+
+ AddButton(Theme.CheckPopup.Button2);
+ if (Length(Button[1].Text) = 0) then
+ AddButtonText(14, 20, 'Button 2');
+
+ AddText(Theme.CheckPopup.TextCheck);
+
+ for I := 0 to High(Theme.CheckPopup.Static) do
+ AddStatic(Theme.CheckPopup.Static[I]);
+
+ for I := 0 to High(Theme.CheckPopup.Text) do
+ AddText(Theme.CheckPopup.Text[I]);
+
+ Interaction := 0;
+end;
+
+function TScreenPopupCheck.Draw: boolean;
+begin
+ Draw:=inherited Draw;
+end;
+
+procedure TScreenPopupCheck.onShow;
+begin
+ inherited;
+end;
+
+procedure TScreenPopupCheck.ShowPopup(msg: String);
+begin
+ Interaction := 0; //Reset Interaction
+ Visible := True; //Set Visible
+
+ Text[0].Text := Language.Translate(msg);
+
+ Button[0].Visible := True;
+ Button[1].Visible := True;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_YES');
+ Button[1].Text[0].Text := Language.Translate('SONG_MENU_NO');
+end;
+
+// error popup
+
+function TScreenPopupError.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ Visible:=False;
+ Result := false;
+ end;
+
+ SDLK_RETURN:
+ begin
+ Visible:=False;
+ Result := false;
+ end;
+
+ SDLK_DOWN: InteractNext;
+ SDLK_UP: InteractPrev;
+
+ SDLK_RIGHT: InteractNext;
+ SDLK_LEFT: InteractPrev;
+ end;
+ end;
+end;
+
+constructor TScreenPopupError.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ AddBackground(Theme.CheckPopup.Background.Tex);
+
+ AddButton(Theme.ErrorPopup.Button1);
+ if (Length(Button[0].Text) = 0) then
+ AddButtonText(14, 20, 'Button 1');
+
+ AddText(Theme.ErrorPopup.TextError);
+
+ for I := 0 to High(Theme.ErrorPopup.Static) do
+ AddStatic(Theme.ErrorPopup.Static[I]);
+
+ for I := 0 to High(Theme.ErrorPopup.Text) do
+ AddText(Theme.ErrorPopup.Text[I]);
+
+ Interaction := 0;
+end;
+
+function TScreenPopupError.Draw: boolean;
+begin
+ Draw:=inherited Draw;
+end;
+
+procedure TScreenPopupError.onShow;
+begin
+ inherited;
+
+end;
+
+procedure TScreenPopupError.onHide;
+begin
+end;
+
+procedure TScreenPopupError.ShowPopup(msg: String);
+begin
+ Interaction := 0; //Reset Interaction
+ Visible := True; //Set Visible
+
+{ //dirty hack... Text[0] is invisible for some strange reason
+ for i:=1 to high(Text) do
+ if i-1 <= high(msg) then
+ begin
+ Text[i].Visible:=True;
+ Text[i].Text := msg[i-1];
+ end
+ else
+ begin
+ Text[i].Visible:=False;
+ end;}
+ Text[0].Text:=msg;
+
+ Button[0].Visible := True;
+
+ Button[0].Text[0].Text := 'OK';
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenScore.pas b/Game/Code/Screens/UScreenScore.pas
index b47c43f1..59e5719a 100644
--- a/Game/Code/Screens/UScreenScore.pas
+++ b/Game/Code/Screens/UScreenScore.pas
@@ -1,837 +1,837 @@
-unit UScreenScore;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- UMenu,
- SDL,
- SysUtils,
- UDisplay,
- UMusic,
- USongs,
- UThemes,
- gl,
- math,
- UTexture;
-
-const
- ZBars : real = 0.8; // Z value for the bars
- ZRatingPic : real = 0.8; // Z value for the rating pictures
-
- EaseOut_MaxSteps : real = 40; // that's the speed of the bars (10 is fast | 100 is slower)
-
- BarRaiseSpeed : cardinal = 0; // Time for raising the bar one step higher (in ms)
-
-type
- TPlayerScoreScreenTexture = record // holds all colorized textures for up to 6 players
- //Bar textures
- Score_NoteBarLevel_Dark : TTexture; // Note
- Score_NoteBarRound_Dark : TTexture; // that's the round thing on top
-
- Score_NoteBarLevel_Light : TTexture; // LineBonus | Phrasebonus
- Score_NoteBarRound_Light : TTexture;
-
- Score_NoteBarLevel_Lightest : TTexture; // GoldenNotes
- Score_NoteBarRound_Lightest : TTexture;
- end;
-
- TPlayerScoreScreenData = record // holds the positions and other data
- Bar_Y :Real;
- Bar_Actual_Height : Real; // this one holds the actual height of the bar, while we animate it
- BarScore_ActualHeight : Real;
- BarLine_ActualHeight : Real;
- BarGolden_ActualHeight : Real;
- end;
-
- TPlayerScoreRatingPics = record // a fine array of the rating pictures
- RateEaseStep : Integer;
- RateEaseValue: Real;
- end;
-
- TScreenScore = class(TMenu)
- private
- BarTime : Cardinal;
- ArrayStartModifier : integer;
- public
- aPlayerScoreScreenTextures : array[1..6] of TPlayerScoreScreenTexture;
- aPlayerScoreScreenDatas : array[1..6] of TPlayerScoreScreenData;
- aPlayerScoreScreenRatings : array[1..6] of TPlayerScoreRatingPics;
-
- BarScore_EaseOut_Step : real;
- BarPhrase_EaseOut_Step : real;
- BarGolden_EaseOut_Step : real;
-
- TextArtist: integer;
- TextTitle: integer;
-
- TextArtistTitle : integer;
-
- TextName: array[1..6] of integer;
- TextScore: array[1..6] of integer;
-
- TextNotes: array[1..6] of integer;
- TextNotesScore: array[1..6] of integer;
- TextLineBonus: array[1..6] of integer;
- TextLineBonusScore: array[1..6] of integer;
- TextGoldenNotes: array[1..6] of integer;
- TextGoldenNotesScore: array[1..6] of integer;
- TextTotal: array[1..6] of integer;
- TextTotalScore: array[1..6] of integer;
-
- PlayerStatic: array[1..6] of array of integer;
- PlayerTexts : array[1..6] of array of integer;
-
-
- StaticBoxLightest: array[1..6] of integer;
- StaticBoxLight: array[1..6] of integer;
- StaticBoxDark: array[1..6] of integer;
-
- StaticBackLevel: array[1..6] of integer;
- StaticBackLevelRound: array[1..6] of integer;
- StaticLevel: array[1..6] of integer;
- StaticLevelRound: array[1..6] of integer;
-
- Animation: real;
-
- TextScore_ActualValue : array[1..6] of integer;
- TextPhrase_ActualValue : array[1..6] of integer;
- TextGolden_ActualValue : array[1..6] of integer;
-
-
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure onShowFinish; override;
- function Draw: boolean; override;
- procedure FillPlayer(Item, P: integer);
-
- procedure EaseBarIn(PlayerNumber : Integer; BarType: String);
- procedure EaseScoreIn(PlayerNumber : Integer; ScoreType: String);
-
- procedure FillPlayerItems(PlayerNumber : Integer; ScoreType: String);
-
-
- procedure DrawBar(BarType:string; PlayerNumber: integer; BarStartPosY: single; NewHeight: real);
-
- //Rating Picture
- procedure ShowRating(PlayerNumber: integer);
- function CalculateBouncing(PlayerNumber : Integer): real;
- procedure DrawRating(PlayerNumber:integer;Rating:integer);
- end;
-
-implementation
-
-
-uses UGraphic,
- UScreenSong,
- UMenuStatic,
- UTime,
- UMain,
- UIni,
- ULanguage;
-
-function TScreenScore.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then begin
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE,
- SDLK_RETURN:
- begin
- FadeTo(@ScreenTop5);
- Exit;
- end;
-
- SDLK_SYSREQ:
- begin
- Display.SaveScreenShot;
- end;
- end;
- end;
-end;
-
-constructor TScreenScore.Create;
-var
- Player: integer;
- Counter: integer;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.Score);
-
- // These two texts arn't used in the deluxe skin
- TextArtist := AddText(Theme.Score.TextArtist);
- TextTitle := AddText(Theme.Score.TextTitle);
-
- TextArtistTitle := AddText(Theme.Score.TextArtistTitle);
-
- for Player := 1 to 6 do
- begin
- SetLength(PlayerStatic[Player], Length(Theme.Score.PlayerStatic[Player]));
- SetLength(PlayerTexts[Player], Length(Theme.Score.PlayerTexts[Player]));
-
- for Counter := 0 to High(Theme.Score.PlayerStatic[Player]) do
- PlayerStatic[Player, Counter] := AddStatic(Theme.Score.PlayerStatic[Player, Counter]);
-
- for Counter := 0 to High(Theme.Score.PlayerTexts[Player]) do
- PlayerTexts[Player, Counter] := AddText(Theme.Score.PlayerTexts[Player, Counter]);
-
- TextName[Player] := AddText(Theme.Score.TextName[Player]);
- TextScore[Player] := AddText(Theme.Score.TextScore[Player]);
-
- TextNotes[Player] := AddText(Theme.Score.TextNotes[Player]);
- TextNotesScore[Player] := AddText(Theme.Score.TextNotesScore[Player]);
- TextLineBonus[Player] := AddText(Theme.Score.TextLineBonus[Player]);
- TextLineBonusScore[Player] := AddText(Theme.Score.TextLineBonusScore[Player]);
- TextGoldenNotes[Player] := AddText(Theme.Score.TextGoldenNotes[Player]);
- TextGoldenNotesScore[Player] := AddText(Theme.Score.TextGoldenNotesScore[Player]);
- TextTotal[Player] := AddText(Theme.Score.TextTotal[Player]);
- TextTotalScore[Player] := AddText(Theme.Score.TextTotalScore[Player]);
-
- StaticBoxLightest[Player] := AddStatic(Theme.Score.StaticBoxLightest[Player]);
- StaticBoxLight[Player] := AddStatic(Theme.Score.StaticBoxLight[Player]);
- StaticBoxDark[Player] := AddStatic(Theme.Score.StaticBoxDark[Player]);
-
- StaticBackLevel[Player] := AddStatic(Theme.Score.StaticBackLevel[Player]);
- StaticBackLevelRound[Player] := AddStatic(Theme.Score.StaticBackLevelRound[Player]);
- StaticLevel[Player] := AddStatic(Theme.Score.StaticLevel[Player]);
- StaticLevelRound[Player] := AddStatic(Theme.Score.StaticLevelRound[Player]);
-
- //textures
- aPlayerScoreScreenTextures[Player].Score_NoteBarLevel_Dark := Tex_Score_NoteBarLevel_Dark[Player];
- aPlayerScoreScreenTextures[Player].Score_NoteBarRound_Dark := Tex_Score_NoteBarRound_Dark[Player];
-
- aPlayerScoreScreenTextures[Player].Score_NoteBarLevel_Light := Tex_Score_NoteBarLevel_Light[Player];
- aPlayerScoreScreenTextures[Player].Score_NoteBarRound_Light := Tex_Score_NoteBarRound_Light[Player];
-
- aPlayerScoreScreenTextures[Player].Score_NoteBarLevel_Lightest := Tex_Score_NoteBarLevel_Lightest[Player];
- aPlayerScoreScreenTextures[Player].Score_NoteBarRound_Lightest := Tex_Score_NoteBarRound_Lightest[Player];
- end;
-
-end;
-
-procedure TScreenScore.onShow;
-var
- P: integer; // player
- I: integer;
- V: array[1..6] of boolean; // visibility array
-
-begin
- inherited;
-
- // all statics / texts are loaded at start - so that we have them all even if we change the amount of players
- // To show the corrects statics / text from the them, we simply modify the start of the according arrays
- // 1 Player -> Player[0].Score (The score for one player starts at 0)
- // -> Statics[1] (The statics for the one player screen start at 1)
- // 2 Player -> Player[0..1].Score
- // -> Statics[2..3]
- // 3 Player -> Player[0..5].Score
- // -> Statics[4..6]
- case PlayersPlay of
- 1: ArrayStartModifier := 0;
- 2, 4: ArrayStartModifier := 1;
- 3, 6: ArrayStartModifier := 3;
- else
- ArrayStartModifier := 0; //this should never happen
- end;
-
- for P := 1 to PlayersPlay do
- begin
- // data
- aPlayerScoreScreenDatas[P].Bar_Y := Theme.Score.StaticBackLevel[P + ArrayStartModifier].Y;
-
- // ratings
- aPlayerScoreScreenRatings[P].RateEaseStep := 1;
- aPlayerScoreScreenRatings[P].RateEaseValue := 20;
- end;
-
-
- Text[TextArtist].Text := CurrentSong.Artist;
- Text[TextTitle].Text := CurrentSong.Title;
- Text[TextArtistTitle].Text := CurrentSong.Artist + ' - ' + CurrentSong.Title;
-
- // set visibility
- case PlayersPlay of
- 1: begin
- V[1] := true;
- V[2] := false;
- V[3] := false;
- V[4] := false;
- V[5] := false;
- V[6] := false;
- end;
- 2, 4: begin
- V[1] := false;
- V[2] := true;
- V[3] := true;
- V[4] := false;
- V[5] := false;
- V[6] := false;
- end;
- 3, 6: begin
- V[1] := false;
- V[2] := false;
- V[3] := false;
- V[4] := true;
- V[5] := true;
- V[6] := true;
- end;
- end;
-
- for P := 1 to 6 do
- begin
- Text[TextName[P]].Visible := V[P];
- Text[TextScore[P]].Visible := V[P];
-
- // We set alpha to 0 , so we can nicely blend them in when we need them
- Text[TextScore[P]].Alpha := 0;
- Text[TextNotesScore[P]].Alpha := 0;
- Text[TextNotes[P]].Alpha := 0;
- Text[TextLineBonus[P]].Alpha := 0;
- Text[TextLineBonusScore[P]].Alpha := 0;
- Text[TextGoldenNotes[P]].Alpha := 0;
- Text[TextGoldenNotesScore[P]].Alpha := 0;
- Text[TextTotal[P]].Alpha := 0;
- Text[TextTotalScore[P]].Alpha := 0;
- Static[StaticBoxLightest[P]].Texture.Alpha := 0;
- Static[StaticBoxLight[P]].Texture.Alpha := 0;
- Static[StaticBoxDark[P]].Texture.Alpha := 0;
-
-
- Text[TextNotes[P]].Visible := V[P];
- Text[TextNotesScore[P]].Visible := V[P];
- Text[TextLineBonus[P]].Visible := V[P];
- Text[TextLineBonusScore[P]].Visible := V[P];
- Text[TextGoldenNotes[P]].Visible := V[P];
- Text[TextGoldenNotesScore[P]].Visible := V[P];
- Text[TextTotal[P]].Visible := V[P];
- Text[TextTotalScore[P]].Visible := V[P];
-
- for I := 0 to high(PlayerStatic[P]) do
- Static[PlayerStatic[P, I]].Visible := V[P];
-
- for I := 0 to high(PlayerTexts[P]) do
- Text[PlayerTexts[P, I]].Visible := V[P];
-
- Static[StaticBoxLightest[P]].Visible := V[P];
- Static[StaticBoxLight[P]].Visible := V[P];
- Static[StaticBoxDark[P]].Visible := V[P];
-
- // we draw that on our own
- Static[StaticBackLevel[P]].Visible := false;
- Static[StaticBackLevelRound[P]].Visible := false;
- Static[StaticLevel[P]].Visible := false;
- Static[StaticLevelRound[P]].Visible := false;
- end;
-end;
-
-procedure TScreenScore.onShowFinish;
-var
- index : integer;
-begin
- for index := 1 to (PlayersPlay) do
- begin
- TextScore_ActualValue[index] := 0;
- TextPhrase_ActualValue[index] := 0;
- TextGolden_ActualValue[index] := 0;
- end;
-
- BarScore_EaseOut_Step := 1;
- BarPhrase_EaseOut_Step := 1;
- BarGolden_EaseOut_Step := 1;
-end;
-
-function TScreenScore.Draw: boolean;
-var
- CurrentTime : Cardinal;
- PlayerCounter : integer;
-begin
-
- inherited Draw;
-{*
- player[0].ScoreInt := 7000;
- player[0].ScoreLineInt := 2000;
- player[0].ScoreGoldenInt := 1000;
- player[0].ScoreTotalInt := 10000;
-
- player[1].ScoreInt := 2500;
- player[1].ScoreLineInt := 1100;
- player[1].ScoreGoldenInt := 900;
- player[1].ScoreTotalInt := 4500;
-*}
- // Let's start to arise the bars
- CurrentTime := SDL_GetTicks();
- if((CurrentTime >= BarTime) AND ShowFinish) then
- begin
- BarTime := CurrentTime + BarRaiseSpeed;
-
- for PlayerCounter := 1 to PlayersPlay do
- begin
- // We actually arise them in the right order, but we have to draw them in reverse order (golden -> phrase -> mainscore)
- if (BarScore_EaseOut_Step < EaseOut_MaxSteps * 10) then
- BarScore_EaseOut_Step:= BarScore_EaseOut_Step + 1;
-
- // PhrasenBonus
- if (BarScore_EaseOut_Step >= (EaseOut_MaxSteps * 10)) then
- begin
- if (BarPhrase_EaseOut_Step < EaseOut_MaxSteps * 10) then
- BarPhrase_EaseOut_Step := BarPhrase_EaseOut_Step + 1;
-
-
- // GoldenNotebonus
- if (BarPhrase_EaseOut_Step >= (EaseOut_MaxSteps * 10)) then
- begin
- if (BarGolden_EaseOut_Step < EaseOut_MaxSteps * 10) then
- BarGolden_EaseOut_Step := BarGolden_EaseOut_Step + 1;
-
- // Draw golden score bar #
- EaseBarIn(PlayerCounter, 'Golden');
- EaseScoreIn(PlayerCounter,'Golden');
- end;
-
- // Draw phrase score bar #
- EaseBarIn(PlayerCounter, 'Line');
- EaseScoreIn(PlayerCounter,'Line');
- end;
-
- // Draw plain score bar #
- EaseBarIn(PlayerCounter, 'Note');
- EaseScoreIn(PlayerCounter,'Note');
-
-
- FillPlayerItems(PlayerCounter,'Funky');
-
- end;
- end;
-
-
-(*
- //todo: i need a clever method to draw statics with their z value
- for I := 0 to Length(Static) - 1 do
- Static[I].Draw;
- for I := 0 to Length(Text) - 1 do
- Text[I].Draw;
-*)
-end;
-
-procedure TscreenScore.FillPlayerItems(PlayerNumber : Integer; ScoreType: String);
-var
- ThemeIndex: integer;
-begin
- // todo: take the name from player[PlayerNumber].Name instead of the ini when this is done (mog)
- Text[TextName[PlayerNumber + ArrayStartModifier]].Text := Ini.Name[PlayerNumber - 1];
- // end todo
-
- ThemeIndex := PlayerNumber + ArrayStartModifier;
-
- //golden
- Text[TextGoldenNotesScore[ThemeIndex]].Text := IntToStr(TextGolden_ActualValue[PlayerNumber]);
- Text[TextGoldenNotesScore[ThemeIndex]].Alpha := (BarGolden_EaseOut_Step / 100);
-
- Static[StaticBoxLightest[ThemeIndex]].Texture.Alpha := (BarGolden_EaseOut_Step / 100);
- Text[TextGoldenNotes[ThemeIndex]].Alpha := (BarGolden_EaseOut_Step / 100);
-
- // line bonus
- Text[TextLineBonusScore[ThemeIndex]].Text := IntToStr(TextPhrase_ActualValue[PlayerNumber]);
- Text[TextLineBonusScore[ThemeIndex]].Alpha := (BarPhrase_EaseOut_Step / 100);
-
- Static[StaticBoxLight[ThemeIndex]].Texture.Alpha := (BarPhrase_EaseOut_Step / 100);
- Text[TextLineBonus[ThemeIndex]].Alpha := (BarPhrase_EaseOut_Step / 100);
-
- // plain score
- Text[TextNotesScore[ThemeIndex]].Text := IntToStr(TextScore_ActualValue[PlayerNumber]);
- Text[TextNotes[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
-
- Static[StaticBoxDark[ThemeIndex]].Texture.Alpha := (BarScore_EaseOut_Step / 100);
- Text[TextNotesScore[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
-
- // total score
- Text[TextTotalScore[ThemeIndex]].Text := IntToStr(TextScore_ActualValue[PlayerNumber] + TextPhrase_ActualValue[PlayerNumber] + TextGolden_ActualValue[PlayerNumber]);
- Text[TextTotalScore[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
-
- Text[TextTotal[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
-
- Text[TextTotal[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
-
- if(BarGolden_EaseOut_Step > 100) then
- begin
- ShowRating(PlayerNumber);
- end;
-end;
-
-
-procedure TScreenScore.ShowRating(PlayerNumber: integer);
-var
- Rating : integer;
- ThemeIndex : integer;
-begin
-
- ThemeIndex := PlayerNumber + ArrayStartModifier;
-
- case (Player[PlayerNumber-1].ScoreTotalInt) of
- 0..2009:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_TONE_DEAF');
- Rating := 0;
- end;
- 2010..4009:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_AMATEUR');
- Rating := 1;
- end;
- 4010..5009:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_WANNABE');
- Rating := 2;
- end;
- 5010..6009:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_HOPEFUL');
- Rating := 3;
- end;
- 6010..7509:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_RISING_STAR');
- Rating := 4;
- end;
- 7510..8509:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_LEAD_SINGER');
- Rating := 5;
- end;
- 8510..9009:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_SUPERSTAR');
- Rating := 6;
- end;
- 9010..10000:
- begin
- Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_ULTRASTAR');
- Rating := 7;
- end;
- else
- Rating := 0; // Cheata :P
- end;
-
- //todo: this could break if the width is not given, for instance when there's a skin with no picture for ratings
- if ( Theme.Score.StaticRatings[ThemeIndex].W > 0 ) AND ( aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue > 0 ) then
- begin
- Text[TextScore[ThemeIndex]].Alpha := aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue / Theme.Score.StaticRatings[ThemeIndex].W;
- end;
- // end todo
-
- DrawRating(PlayerNumber, Rating);
-end;
-
-procedure TscreenScore.DrawRating(PlayerNumber:integer;Rating:integer);
-var
- Posx : real;
- Posy : real;
- Width :real;
-begin
-
- CalculateBouncing(PlayerNumber);
-
- PosX := Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].X + (Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].W * 0.5);
- PosY := Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].Y + (Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].H * 0.5); ;
-
- Width := aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue/2;
-
- glBindTexture(GL_TEXTURE_2D, Tex_Score_Ratings[Rating].TexNum);
-
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(PosX - Width, PosY - Width);
- glTexCoord2f(Tex_Score_Ratings[Rating].TexW, 0); glVertex2f(PosX + Width, PosY - Width);
- glTexCoord2f(Tex_Score_Ratings[Rating].TexW, Tex_Score_Ratings[Rating].TexH); glVertex2f(PosX + Width, PosY + Width);
- glTexCoord2f(0, Tex_Score_Ratings[Rating].TexH); glVertex2f(PosX - Width, PosY + Width);
- glEnd;
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2d);
-end;
-
-
-
-function TscreenScore.CalculateBouncing(PlayerNumber : Integer): real;
-var
- ReturnValue : real;
- p, s : real;
-
- RaiseStep, MaxVal : real;
- EaseOut_Step : integer;
-begin
- EaseOut_Step := aPlayerScoreScreenRatings[PlayerNumber].RateEaseStep;
- MaxVal := Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].W;
-
- RaiseStep := EaseOut_Step;
-
- if (MaxVal > 0) AND (RaiseStep > 0) then
- RaiseStep := RaiseStep / MaxVal;
-
- if (RaiseStep = 1) then
- begin
- ReturnValue := MaxVal;
- end
- else
- begin
- p := MaxVal * 0.4;
-
- s := p/(2*PI) * arcsin (1);
- ReturnValue := MaxVal * power(2,-5 * RaiseStep) * sin( (RaiseStep * MaxVal - s) * (2 * PI) / p) + MaxVal;
-
- inc(aPlayerScoreScreenRatings[PlayerNumber].RateEaseStep);
- aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue := ReturnValue;
- end;
-
- Result := ReturnValue;
-end;
-
-
-procedure TscreenScore.EaseBarIn(PlayerNumber : Integer; BarType: String);
-const
- RaiseSmoothness : integer = 100;
-var
- MaxHeight : real;
- NewHeight : real;
-
- Height2Reach : real;
- RaiseStep : real;
- BarStartPosY : single;
-
- lTmp : real;
- Score : integer;
-
-begin
-
-
- MaxHeight := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].H;
-
- // let's get the points according to the bar we draw
- // score array starts at 0, which means the score for player 1 is in score[0]
- // EaseOut_Step is the actual step in the raising process, like the 20iest step of EaseOut_MaxSteps
- if (BarType = 'Note') then
- begin
- Score := Player[PlayerNumber - 1].ScoreInt;
- RaiseStep := BarScore_EaseOut_Step;
- BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y + MaxHeight;
- end;
- if (BarType = 'Line') then
- begin
- Score := Player[PlayerNumber - 1].ScoreLineInt;
- RaiseStep := BarPhrase_EaseOut_Step;
- BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y - aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight + MaxHeight;
- end;
- if (BarType = 'Golden') then
- begin
- Score := Player[PlayerNumber - 1].ScoreGoldenInt;
- RaiseStep := BarGolden_EaseOut_Step;
- BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y - aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight - aPlayerScoreScreenDatas[PlayerNumber].BarLine_ActualHeight + MaxHeight;
- end;
-
- // the height dependend of the score
- Height2Reach := (Score / MAX_SONG_SCORE) * MaxHeight;
-
- if (aPlayerScoreScreenDatas[PlayerNumber].Bar_Actual_Height < Height2Reach) then
- begin
- // Check http://proto.layer51.com/d.aspx?f=400 for more info on easing functions
- // Calculate the actual step according to the maxsteps
- RaiseStep := RaiseStep / EaseOut_MaxSteps;
-
- // quadratic easing out - decelerating to zero velocity
- // -end_position * current_time * ( current_time - 2 ) + start_postion
- lTmp := (-Height2Reach * RaiseStep * (RaiseStep - 20) + BarStartPosY);
-
- if ( RaiseSmoothness > 0 ) AND ( lTmp > 0 ) then
- NewHeight := lTmp / RaiseSmoothness;
-
- end
- else
- NewHeight := Height2Reach;
-
- DrawBar(BarType, PlayerNumber, BarStartPosY, NewHeight);
-
- if (BarType = 'Note') then
- aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight := NewHeight;
- if (BarType = 'Line') then
- aPlayerScoreScreenDatas[PlayerNumber].BarLine_ActualHeight := NewHeight;
- if (BarType = 'Golden') then
- aPlayerScoreScreenDatas[PlayerNumber].BarGolden_ActualHeight := NewHeight;
-end;
-
-procedure TscreenScore.DrawBar(BarType:string; PlayerNumber: integer; BarStartPosY: single; NewHeight: real);
-var
- Width:real;
- BarStartPosX:real;
-begin
- // this is solely for better readability of the drawing
- Width := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].W;
- BarStartPosX := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].X;
-
- glColor4f(1, 1, 1, 1);
-
- // set the texture for the bar
- if (BarType = 'Note') then
- glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarLevel_Dark.TexNum);
- if (BarType = 'Line') then
- glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarLevel_Light.TexNum);
- if (BarType = 'Golden') then
- glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarLevel_Lightest.TexNum);
-
- //draw it
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex3f(BarStartPosX, BarStartPosY - NewHeight, ZBars);
- glTexCoord2f(1, 0); glVertex3f(BarStartPosX + Width, BarStartPosY - NewHeight, ZBars);
- glTexCoord2f(1, 1); glVertex3f(BarStartPosX + Width, BarStartPosY, ZBars);
- glTexCoord2f(0, 1); glVertex3f(BarStartPosX, BarStartPosY, ZBars);
- glEnd;
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2d);
-
- //the round thing on top
- if (BarType = 'Note') then
- glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarRound_Dark.TexNum);
- if (BarType = 'Line') then
- glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarRound_Light.TexNum);
- if (BarType = 'Golden') then
- glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarRound_Lightest.TexNum);
-
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex3f(BarStartPosX, (BarStartPosY - Static[StaticLevelRound[PlayerNumber + ArrayStartModifier]].Texture.h) - NewHeight, ZBars);
- glTexCoord2f(1, 0); glVertex3f(BarStartPosX + Width, (BarStartPosY - Static[StaticLevelRound[PlayerNumber + ArrayStartModifier]].Texture.h) - NewHeight, ZBars);
- glTexCoord2f(1, 1); glVertex3f(BarStartPosX + Width, BarStartPosY - NewHeight, ZBars);
- glTexCoord2f(0, 1); glVertex3f(BarStartPosX, BarStartPosY - NewHeight, ZBars);
- glEnd;
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2d);
-end;
-
-procedure TScreenScore.EaseScoreIn(PlayerNumber: integer; ScoreType : String);
-const
- RaiseSmoothness : integer = 100;
-var
- RaiseStep : Real;
- lTmpA : Real;
- ScoreReached :Integer;
- EaseOut_Step :Real;
- ActualScoreValue:integer;
-begin
- if (ScoreType = 'Note') then
- begin
- EaseOut_Step := BarScore_EaseOut_Step;
- ActualScoreValue := TextScore_ActualValue[PlayerNumber];
- ScoreReached := Player[PlayerNumber-1].ScoreInt;
- end;
- if (ScoreType = 'Line') then
- begin
- EaseOut_Step := BarPhrase_EaseOut_Step;
- ActualScoreValue := TextPhrase_ActualValue[PlayerNumber];
- ScoreReached := Player[PlayerNumber-1].ScoreLineInt;
- end;
- if (ScoreType = 'Golden') then
- begin
- EaseOut_Step := BarGolden_EaseOut_Step;
- ActualScoreValue := TextGolden_ActualValue[PlayerNumber];
- ScoreReached := Player[PlayerNumber-1].ScoreGoldenInt;
- end;
-
- // EaseOut_Step is the actual step in the raising process, like the 20iest step of EaseOut_MaxSteps
- RaiseStep := EaseOut_Step;
-
- if (ActualScoreValue < ScoreReached) then
- begin
- // Calculate the actual step according to the maxsteps
- RaiseStep := RaiseStep / EaseOut_MaxSteps;
-
- // quadratic easing out - decelerating to zero velocity
- // -end_position * current_time * ( current_time - 2 ) + start_postion
- lTmpA := (-ScoreReached * RaiseStep * (RaiseStep - 20));
- if ( lTmpA > 0 ) AND
- ( RaiseSmoothness > 0 ) then
- begin
- if (ScoreType = 'Note') then
- TextScore_ActualValue[PlayerNumber] := floor( lTmpA / RaiseSmoothness);
- if (ScoreType = 'Line') then
- TextPhrase_ActualValue[PlayerNumber] := floor( lTmpA / RaiseSmoothness);
- if (ScoreType = 'Golden') then
- TextGolden_ActualValue[PlayerNumber] := floor( lTmpA / RaiseSmoothness);
- end;
- end
- else
- begin
- if (ScoreType = 'Note') then
- TextScore_ActualValue[PlayerNumber] := ScoreReached;
- if (ScoreType = 'Line') then
- TextPhrase_ActualValue[PlayerNumber] := ScoreReached;
- if (ScoreType = 'Golden') then
- TextGolden_ActualValue[PlayerNumber] := ScoreReached;
- end;
-end;
-
-procedure TScreenScore.FillPlayer(Item, P: integer);
-var
- S: string;
-begin
- Text[TextName[Item]].Text := Ini.Name[P];
-
- S := IntToStr((Round(Player[P].Score) div 10) * 10);
- while (Length(S)<4) do
- S := '0' + S;
- Text[TextNotesScore[Item]].Text := S;
-
- // while (Length(S)<5) do S := '0' + S;
- // Text[TextTotalScore[Item]].Text := S;
-
- //fixed: line bonus and golden notes don't show up,
- // another bug: total score was shown without added golden-, linebonus
- S := IntToStr(Player[P].ScoreTotalInt);
- while (Length(S)<5) do
- S := '0' + S;
- Text[TextTotalScore[Item]].Text := S;
-
- S := IntToStr(Player[P].ScoreLineInt);
- while (Length(S)<4) do
- S := '0' + S;
- Text[TextLineBonusScore[Item]].Text := S;
-
- S := IntToStr(Player[P].ScoreGoldenInt);
- while (Length(S)<4) do
- S := '0' + S;
- Text[TextGoldenNotesScore[Item]].Text := S;
- //end of fix
-
-
-end;
-
-end.
+unit UScreenScore;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMenu,
+ SDL,
+ SysUtils,
+ UDisplay,
+ UMusic,
+ USongs,
+ UThemes,
+ gl,
+ math,
+ UTexture;
+
+const
+ ZBars : real = 0.8; // Z value for the bars
+ ZRatingPic : real = 0.8; // Z value for the rating pictures
+
+ EaseOut_MaxSteps : real = 40; // that's the speed of the bars (10 is fast | 100 is slower)
+
+ BarRaiseSpeed : cardinal = 0; // Time for raising the bar one step higher (in ms)
+
+type
+ TPlayerScoreScreenTexture = record // holds all colorized textures for up to 6 players
+ //Bar textures
+ Score_NoteBarLevel_Dark : TTexture; // Note
+ Score_NoteBarRound_Dark : TTexture; // that's the round thing on top
+
+ Score_NoteBarLevel_Light : TTexture; // LineBonus | Phrasebonus
+ Score_NoteBarRound_Light : TTexture;
+
+ Score_NoteBarLevel_Lightest : TTexture; // GoldenNotes
+ Score_NoteBarRound_Lightest : TTexture;
+ end;
+
+ TPlayerScoreScreenData = record // holds the positions and other data
+ Bar_Y :Real;
+ Bar_Actual_Height : Real; // this one holds the actual height of the bar, while we animate it
+ BarScore_ActualHeight : Real;
+ BarLine_ActualHeight : Real;
+ BarGolden_ActualHeight : Real;
+ end;
+
+ TPlayerScoreRatingPics = record // a fine array of the rating pictures
+ RateEaseStep : Integer;
+ RateEaseValue: Real;
+ end;
+
+ TScreenScore = class(TMenu)
+ private
+ BarTime : Cardinal;
+ ArrayStartModifier : integer;
+ public
+ aPlayerScoreScreenTextures : array[1..6] of TPlayerScoreScreenTexture;
+ aPlayerScoreScreenDatas : array[1..6] of TPlayerScoreScreenData;
+ aPlayerScoreScreenRatings : array[1..6] of TPlayerScoreRatingPics;
+
+ BarScore_EaseOut_Step : real;
+ BarPhrase_EaseOut_Step : real;
+ BarGolden_EaseOut_Step : real;
+
+ TextArtist: integer;
+ TextTitle: integer;
+
+ TextArtistTitle : integer;
+
+ TextName: array[1..6] of integer;
+ TextScore: array[1..6] of integer;
+
+ TextNotes: array[1..6] of integer;
+ TextNotesScore: array[1..6] of integer;
+ TextLineBonus: array[1..6] of integer;
+ TextLineBonusScore: array[1..6] of integer;
+ TextGoldenNotes: array[1..6] of integer;
+ TextGoldenNotesScore: array[1..6] of integer;
+ TextTotal: array[1..6] of integer;
+ TextTotalScore: array[1..6] of integer;
+
+ PlayerStatic: array[1..6] of array of integer;
+ PlayerTexts : array[1..6] of array of integer;
+
+
+ StaticBoxLightest: array[1..6] of integer;
+ StaticBoxLight: array[1..6] of integer;
+ StaticBoxDark: array[1..6] of integer;
+
+ StaticBackLevel: array[1..6] of integer;
+ StaticBackLevelRound: array[1..6] of integer;
+ StaticLevel: array[1..6] of integer;
+ StaticLevelRound: array[1..6] of integer;
+
+ Animation: real;
+
+ TextScore_ActualValue : array[1..6] of integer;
+ TextPhrase_ActualValue : array[1..6] of integer;
+ TextGolden_ActualValue : array[1..6] of integer;
+
+
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure onShowFinish; override;
+ function Draw: boolean; override;
+ procedure FillPlayer(Item, P: integer);
+
+ procedure EaseBarIn(PlayerNumber : Integer; BarType: String);
+ procedure EaseScoreIn(PlayerNumber : Integer; ScoreType: String);
+
+ procedure FillPlayerItems(PlayerNumber : Integer; ScoreType: String);
+
+
+ procedure DrawBar(BarType:string; PlayerNumber: integer; BarStartPosY: single; NewHeight: real);
+
+ //Rating Picture
+ procedure ShowRating(PlayerNumber: integer);
+ function CalculateBouncing(PlayerNumber : Integer): real;
+ procedure DrawRating(PlayerNumber:integer;Rating:integer);
+ end;
+
+implementation
+
+
+uses UGraphic,
+ UScreenSong,
+ UMenuStatic,
+ UTime,
+ UMain,
+ UIni,
+ ULanguage;
+
+function TScreenScore.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then begin
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE,
+ SDLK_RETURN:
+ begin
+ FadeTo(@ScreenTop5);
+ Exit;
+ end;
+
+ SDLK_SYSREQ:
+ begin
+ Display.SaveScreenShot;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenScore.Create;
+var
+ Player: integer;
+ Counter: integer;
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.Score);
+
+ // These two texts arn't used in the deluxe skin
+ TextArtist := AddText(Theme.Score.TextArtist);
+ TextTitle := AddText(Theme.Score.TextTitle);
+
+ TextArtistTitle := AddText(Theme.Score.TextArtistTitle);
+
+ for Player := 1 to 6 do
+ begin
+ SetLength(PlayerStatic[Player], Length(Theme.Score.PlayerStatic[Player]));
+ SetLength(PlayerTexts[Player], Length(Theme.Score.PlayerTexts[Player]));
+
+ for Counter := 0 to High(Theme.Score.PlayerStatic[Player]) do
+ PlayerStatic[Player, Counter] := AddStatic(Theme.Score.PlayerStatic[Player, Counter]);
+
+ for Counter := 0 to High(Theme.Score.PlayerTexts[Player]) do
+ PlayerTexts[Player, Counter] := AddText(Theme.Score.PlayerTexts[Player, Counter]);
+
+ TextName[Player] := AddText(Theme.Score.TextName[Player]);
+ TextScore[Player] := AddText(Theme.Score.TextScore[Player]);
+
+ TextNotes[Player] := AddText(Theme.Score.TextNotes[Player]);
+ TextNotesScore[Player] := AddText(Theme.Score.TextNotesScore[Player]);
+ TextLineBonus[Player] := AddText(Theme.Score.TextLineBonus[Player]);
+ TextLineBonusScore[Player] := AddText(Theme.Score.TextLineBonusScore[Player]);
+ TextGoldenNotes[Player] := AddText(Theme.Score.TextGoldenNotes[Player]);
+ TextGoldenNotesScore[Player] := AddText(Theme.Score.TextGoldenNotesScore[Player]);
+ TextTotal[Player] := AddText(Theme.Score.TextTotal[Player]);
+ TextTotalScore[Player] := AddText(Theme.Score.TextTotalScore[Player]);
+
+ StaticBoxLightest[Player] := AddStatic(Theme.Score.StaticBoxLightest[Player]);
+ StaticBoxLight[Player] := AddStatic(Theme.Score.StaticBoxLight[Player]);
+ StaticBoxDark[Player] := AddStatic(Theme.Score.StaticBoxDark[Player]);
+
+ StaticBackLevel[Player] := AddStatic(Theme.Score.StaticBackLevel[Player]);
+ StaticBackLevelRound[Player] := AddStatic(Theme.Score.StaticBackLevelRound[Player]);
+ StaticLevel[Player] := AddStatic(Theme.Score.StaticLevel[Player]);
+ StaticLevelRound[Player] := AddStatic(Theme.Score.StaticLevelRound[Player]);
+
+ //textures
+ aPlayerScoreScreenTextures[Player].Score_NoteBarLevel_Dark := Tex_Score_NoteBarLevel_Dark[Player];
+ aPlayerScoreScreenTextures[Player].Score_NoteBarRound_Dark := Tex_Score_NoteBarRound_Dark[Player];
+
+ aPlayerScoreScreenTextures[Player].Score_NoteBarLevel_Light := Tex_Score_NoteBarLevel_Light[Player];
+ aPlayerScoreScreenTextures[Player].Score_NoteBarRound_Light := Tex_Score_NoteBarRound_Light[Player];
+
+ aPlayerScoreScreenTextures[Player].Score_NoteBarLevel_Lightest := Tex_Score_NoteBarLevel_Lightest[Player];
+ aPlayerScoreScreenTextures[Player].Score_NoteBarRound_Lightest := Tex_Score_NoteBarRound_Lightest[Player];
+ end;
+
+end;
+
+procedure TScreenScore.onShow;
+var
+ P: integer; // player
+ I: integer;
+ V: array[1..6] of boolean; // visibility array
+
+begin
+ inherited;
+
+ // all statics / texts are loaded at start - so that we have them all even if we change the amount of players
+ // To show the corrects statics / text from the them, we simply modify the start of the according arrays
+ // 1 Player -> Player[0].Score (The score for one player starts at 0)
+ // -> Statics[1] (The statics for the one player screen start at 1)
+ // 2 Player -> Player[0..1].Score
+ // -> Statics[2..3]
+ // 3 Player -> Player[0..5].Score
+ // -> Statics[4..6]
+ case PlayersPlay of
+ 1: ArrayStartModifier := 0;
+ 2, 4: ArrayStartModifier := 1;
+ 3, 6: ArrayStartModifier := 3;
+ else
+ ArrayStartModifier := 0; //this should never happen
+ end;
+
+ for P := 1 to PlayersPlay do
+ begin
+ // data
+ aPlayerScoreScreenDatas[P].Bar_Y := Theme.Score.StaticBackLevel[P + ArrayStartModifier].Y;
+
+ // ratings
+ aPlayerScoreScreenRatings[P].RateEaseStep := 1;
+ aPlayerScoreScreenRatings[P].RateEaseValue := 20;
+ end;
+
+
+ Text[TextArtist].Text := CurrentSong.Artist;
+ Text[TextTitle].Text := CurrentSong.Title;
+ Text[TextArtistTitle].Text := CurrentSong.Artist + ' - ' + CurrentSong.Title;
+
+ // set visibility
+ case PlayersPlay of
+ 1: begin
+ V[1] := true;
+ V[2] := false;
+ V[3] := false;
+ V[4] := false;
+ V[5] := false;
+ V[6] := false;
+ end;
+ 2, 4: begin
+ V[1] := false;
+ V[2] := true;
+ V[3] := true;
+ V[4] := false;
+ V[5] := false;
+ V[6] := false;
+ end;
+ 3, 6: begin
+ V[1] := false;
+ V[2] := false;
+ V[3] := false;
+ V[4] := true;
+ V[5] := true;
+ V[6] := true;
+ end;
+ end;
+
+ for P := 1 to 6 do
+ begin
+ Text[TextName[P]].Visible := V[P];
+ Text[TextScore[P]].Visible := V[P];
+
+ // We set alpha to 0 , so we can nicely blend them in when we need them
+ Text[TextScore[P]].Alpha := 0;
+ Text[TextNotesScore[P]].Alpha := 0;
+ Text[TextNotes[P]].Alpha := 0;
+ Text[TextLineBonus[P]].Alpha := 0;
+ Text[TextLineBonusScore[P]].Alpha := 0;
+ Text[TextGoldenNotes[P]].Alpha := 0;
+ Text[TextGoldenNotesScore[P]].Alpha := 0;
+ Text[TextTotal[P]].Alpha := 0;
+ Text[TextTotalScore[P]].Alpha := 0;
+ Static[StaticBoxLightest[P]].Texture.Alpha := 0;
+ Static[StaticBoxLight[P]].Texture.Alpha := 0;
+ Static[StaticBoxDark[P]].Texture.Alpha := 0;
+
+
+ Text[TextNotes[P]].Visible := V[P];
+ Text[TextNotesScore[P]].Visible := V[P];
+ Text[TextLineBonus[P]].Visible := V[P];
+ Text[TextLineBonusScore[P]].Visible := V[P];
+ Text[TextGoldenNotes[P]].Visible := V[P];
+ Text[TextGoldenNotesScore[P]].Visible := V[P];
+ Text[TextTotal[P]].Visible := V[P];
+ Text[TextTotalScore[P]].Visible := V[P];
+
+ for I := 0 to high(PlayerStatic[P]) do
+ Static[PlayerStatic[P, I]].Visible := V[P];
+
+ for I := 0 to high(PlayerTexts[P]) do
+ Text[PlayerTexts[P, I]].Visible := V[P];
+
+ Static[StaticBoxLightest[P]].Visible := V[P];
+ Static[StaticBoxLight[P]].Visible := V[P];
+ Static[StaticBoxDark[P]].Visible := V[P];
+
+ // we draw that on our own
+ Static[StaticBackLevel[P]].Visible := false;
+ Static[StaticBackLevelRound[P]].Visible := false;
+ Static[StaticLevel[P]].Visible := false;
+ Static[StaticLevelRound[P]].Visible := false;
+ end;
+end;
+
+procedure TScreenScore.onShowFinish;
+var
+ index : integer;
+begin
+ for index := 1 to (PlayersPlay) do
+ begin
+ TextScore_ActualValue[index] := 0;
+ TextPhrase_ActualValue[index] := 0;
+ TextGolden_ActualValue[index] := 0;
+ end;
+
+ BarScore_EaseOut_Step := 1;
+ BarPhrase_EaseOut_Step := 1;
+ BarGolden_EaseOut_Step := 1;
+end;
+
+function TScreenScore.Draw: boolean;
+var
+ CurrentTime : Cardinal;
+ PlayerCounter : integer;
+begin
+
+ inherited Draw;
+{*
+ player[0].ScoreInt := 7000;
+ player[0].ScoreLineInt := 2000;
+ player[0].ScoreGoldenInt := 1000;
+ player[0].ScoreTotalInt := 10000;
+
+ player[1].ScoreInt := 2500;
+ player[1].ScoreLineInt := 1100;
+ player[1].ScoreGoldenInt := 900;
+ player[1].ScoreTotalInt := 4500;
+*}
+ // Let's start to arise the bars
+ CurrentTime := SDL_GetTicks();
+ if((CurrentTime >= BarTime) AND ShowFinish) then
+ begin
+ BarTime := CurrentTime + BarRaiseSpeed;
+
+ for PlayerCounter := 1 to PlayersPlay do
+ begin
+ // We actually arise them in the right order, but we have to draw them in reverse order (golden -> phrase -> mainscore)
+ if (BarScore_EaseOut_Step < EaseOut_MaxSteps * 10) then
+ BarScore_EaseOut_Step:= BarScore_EaseOut_Step + 1;
+
+ // PhrasenBonus
+ if (BarScore_EaseOut_Step >= (EaseOut_MaxSteps * 10)) then
+ begin
+ if (BarPhrase_EaseOut_Step < EaseOut_MaxSteps * 10) then
+ BarPhrase_EaseOut_Step := BarPhrase_EaseOut_Step + 1;
+
+
+ // GoldenNotebonus
+ if (BarPhrase_EaseOut_Step >= (EaseOut_MaxSteps * 10)) then
+ begin
+ if (BarGolden_EaseOut_Step < EaseOut_MaxSteps * 10) then
+ BarGolden_EaseOut_Step := BarGolden_EaseOut_Step + 1;
+
+ // Draw golden score bar #
+ EaseBarIn(PlayerCounter, 'Golden');
+ EaseScoreIn(PlayerCounter,'Golden');
+ end;
+
+ // Draw phrase score bar #
+ EaseBarIn(PlayerCounter, 'Line');
+ EaseScoreIn(PlayerCounter,'Line');
+ end;
+
+ // Draw plain score bar #
+ EaseBarIn(PlayerCounter, 'Note');
+ EaseScoreIn(PlayerCounter,'Note');
+
+
+ FillPlayerItems(PlayerCounter,'Funky');
+
+ end;
+ end;
+
+
+(*
+ //todo: i need a clever method to draw statics with their z value
+ for I := 0 to Length(Static) - 1 do
+ Static[I].Draw;
+ for I := 0 to Length(Text) - 1 do
+ Text[I].Draw;
+*)
+end;
+
+procedure TscreenScore.FillPlayerItems(PlayerNumber : Integer; ScoreType: String);
+var
+ ThemeIndex: integer;
+begin
+ // todo: take the name from player[PlayerNumber].Name instead of the ini when this is done (mog)
+ Text[TextName[PlayerNumber + ArrayStartModifier]].Text := Ini.Name[PlayerNumber - 1];
+ // end todo
+
+ ThemeIndex := PlayerNumber + ArrayStartModifier;
+
+ //golden
+ Text[TextGoldenNotesScore[ThemeIndex]].Text := IntToStr(TextGolden_ActualValue[PlayerNumber]);
+ Text[TextGoldenNotesScore[ThemeIndex]].Alpha := (BarGolden_EaseOut_Step / 100);
+
+ Static[StaticBoxLightest[ThemeIndex]].Texture.Alpha := (BarGolden_EaseOut_Step / 100);
+ Text[TextGoldenNotes[ThemeIndex]].Alpha := (BarGolden_EaseOut_Step / 100);
+
+ // line bonus
+ Text[TextLineBonusScore[ThemeIndex]].Text := IntToStr(TextPhrase_ActualValue[PlayerNumber]);
+ Text[TextLineBonusScore[ThemeIndex]].Alpha := (BarPhrase_EaseOut_Step / 100);
+
+ Static[StaticBoxLight[ThemeIndex]].Texture.Alpha := (BarPhrase_EaseOut_Step / 100);
+ Text[TextLineBonus[ThemeIndex]].Alpha := (BarPhrase_EaseOut_Step / 100);
+
+ // plain score
+ Text[TextNotesScore[ThemeIndex]].Text := IntToStr(TextScore_ActualValue[PlayerNumber]);
+ Text[TextNotes[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
+
+ Static[StaticBoxDark[ThemeIndex]].Texture.Alpha := (BarScore_EaseOut_Step / 100);
+ Text[TextNotesScore[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
+
+ // total score
+ Text[TextTotalScore[ThemeIndex]].Text := IntToStr(TextScore_ActualValue[PlayerNumber] + TextPhrase_ActualValue[PlayerNumber] + TextGolden_ActualValue[PlayerNumber]);
+ Text[TextTotalScore[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
+
+ Text[TextTotal[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
+
+ Text[TextTotal[ThemeIndex]].Alpha := (BarScore_EaseOut_Step / 100);
+
+ if(BarGolden_EaseOut_Step > 100) then
+ begin
+ ShowRating(PlayerNumber);
+ end;
+end;
+
+
+procedure TScreenScore.ShowRating(PlayerNumber: integer);
+var
+ Rating : integer;
+ ThemeIndex : integer;
+begin
+
+ ThemeIndex := PlayerNumber + ArrayStartModifier;
+
+ case (Player[PlayerNumber-1].ScoreTotalInt) of
+ 0..2009:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_TONE_DEAF');
+ Rating := 0;
+ end;
+ 2010..4009:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_AMATEUR');
+ Rating := 1;
+ end;
+ 4010..5009:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_WANNABE');
+ Rating := 2;
+ end;
+ 5010..6009:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_HOPEFUL');
+ Rating := 3;
+ end;
+ 6010..7509:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_RISING_STAR');
+ Rating := 4;
+ end;
+ 7510..8509:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_LEAD_SINGER');
+ Rating := 5;
+ end;
+ 8510..9009:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_SUPERSTAR');
+ Rating := 6;
+ end;
+ 9010..10000:
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_ULTRASTAR');
+ Rating := 7;
+ end;
+ else
+ Rating := 0; // Cheata :P
+ end;
+
+ //todo: this could break if the width is not given, for instance when there's a skin with no picture for ratings
+ if ( Theme.Score.StaticRatings[ThemeIndex].W > 0 ) AND ( aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue > 0 ) then
+ begin
+ Text[TextScore[ThemeIndex]].Alpha := aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue / Theme.Score.StaticRatings[ThemeIndex].W;
+ end;
+ // end todo
+
+ DrawRating(PlayerNumber, Rating);
+end;
+
+procedure TscreenScore.DrawRating(PlayerNumber:integer;Rating:integer);
+var
+ Posx : real;
+ Posy : real;
+ Width :real;
+begin
+
+ CalculateBouncing(PlayerNumber);
+
+ PosX := Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].X + (Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].W * 0.5);
+ PosY := Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].Y + (Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].H * 0.5); ;
+
+ Width := aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue/2;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_Score_Ratings[Rating].TexNum);
+
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(PosX - Width, PosY - Width);
+ glTexCoord2f(Tex_Score_Ratings[Rating].TexW, 0); glVertex2f(PosX + Width, PosY - Width);
+ glTexCoord2f(Tex_Score_Ratings[Rating].TexW, Tex_Score_Ratings[Rating].TexH); glVertex2f(PosX + Width, PosY + Width);
+ glTexCoord2f(0, Tex_Score_Ratings[Rating].TexH); glVertex2f(PosX - Width, PosY + Width);
+ glEnd;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2d);
+end;
+
+
+
+function TscreenScore.CalculateBouncing(PlayerNumber : Integer): real;
+var
+ ReturnValue : real;
+ p, s : real;
+
+ RaiseStep, MaxVal : real;
+ EaseOut_Step : integer;
+begin
+ EaseOut_Step := aPlayerScoreScreenRatings[PlayerNumber].RateEaseStep;
+ MaxVal := Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].W;
+
+ RaiseStep := EaseOut_Step;
+
+ if (MaxVal > 0) AND (RaiseStep > 0) then
+ RaiseStep := RaiseStep / MaxVal;
+
+ if (RaiseStep = 1) then
+ begin
+ ReturnValue := MaxVal;
+ end
+ else
+ begin
+ p := MaxVal * 0.4;
+
+ s := p/(2*PI) * arcsin (1);
+ ReturnValue := MaxVal * power(2,-5 * RaiseStep) * sin( (RaiseStep * MaxVal - s) * (2 * PI) / p) + MaxVal;
+
+ inc(aPlayerScoreScreenRatings[PlayerNumber].RateEaseStep);
+ aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue := ReturnValue;
+ end;
+
+ Result := ReturnValue;
+end;
+
+
+procedure TscreenScore.EaseBarIn(PlayerNumber : Integer; BarType: String);
+const
+ RaiseSmoothness : integer = 100;
+var
+ MaxHeight : real;
+ NewHeight : real;
+
+ Height2Reach : real;
+ RaiseStep : real;
+ BarStartPosY : single;
+
+ lTmp : real;
+ Score : integer;
+
+begin
+
+
+ MaxHeight := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].H;
+
+ // let's get the points according to the bar we draw
+ // score array starts at 0, which means the score for player 1 is in score[0]
+ // EaseOut_Step is the actual step in the raising process, like the 20iest step of EaseOut_MaxSteps
+ if (BarType = 'Note') then
+ begin
+ Score := Player[PlayerNumber - 1].ScoreInt;
+ RaiseStep := BarScore_EaseOut_Step;
+ BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y + MaxHeight;
+ end;
+ if (BarType = 'Line') then
+ begin
+ Score := Player[PlayerNumber - 1].ScoreLineInt;
+ RaiseStep := BarPhrase_EaseOut_Step;
+ BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y - aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight + MaxHeight;
+ end;
+ if (BarType = 'Golden') then
+ begin
+ Score := Player[PlayerNumber - 1].ScoreGoldenInt;
+ RaiseStep := BarGolden_EaseOut_Step;
+ BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y - aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight - aPlayerScoreScreenDatas[PlayerNumber].BarLine_ActualHeight + MaxHeight;
+ end;
+
+ // the height dependend of the score
+ Height2Reach := (Score / MAX_SONG_SCORE) * MaxHeight;
+
+ if (aPlayerScoreScreenDatas[PlayerNumber].Bar_Actual_Height < Height2Reach) then
+ begin
+ // Check http://proto.layer51.com/d.aspx?f=400 for more info on easing functions
+ // Calculate the actual step according to the maxsteps
+ RaiseStep := RaiseStep / EaseOut_MaxSteps;
+
+ // quadratic easing out - decelerating to zero velocity
+ // -end_position * current_time * ( current_time - 2 ) + start_postion
+ lTmp := (-Height2Reach * RaiseStep * (RaiseStep - 20) + BarStartPosY);
+
+ if ( RaiseSmoothness > 0 ) AND ( lTmp > 0 ) then
+ NewHeight := lTmp / RaiseSmoothness;
+
+ end
+ else
+ NewHeight := Height2Reach;
+
+ DrawBar(BarType, PlayerNumber, BarStartPosY, NewHeight);
+
+ if (BarType = 'Note') then
+ aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight := NewHeight;
+ if (BarType = 'Line') then
+ aPlayerScoreScreenDatas[PlayerNumber].BarLine_ActualHeight := NewHeight;
+ if (BarType = 'Golden') then
+ aPlayerScoreScreenDatas[PlayerNumber].BarGolden_ActualHeight := NewHeight;
+end;
+
+procedure TscreenScore.DrawBar(BarType:string; PlayerNumber: integer; BarStartPosY: single; NewHeight: real);
+var
+ Width:real;
+ BarStartPosX:real;
+begin
+ // this is solely for better readability of the drawing
+ Width := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].W;
+ BarStartPosX := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].X;
+
+ glColor4f(1, 1, 1, 1);
+
+ // set the texture for the bar
+ if (BarType = 'Note') then
+ glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarLevel_Dark.TexNum);
+ if (BarType = 'Line') then
+ glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarLevel_Light.TexNum);
+ if (BarType = 'Golden') then
+ glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarLevel_Lightest.TexNum);
+
+ //draw it
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex3f(BarStartPosX, BarStartPosY - NewHeight, ZBars);
+ glTexCoord2f(1, 0); glVertex3f(BarStartPosX + Width, BarStartPosY - NewHeight, ZBars);
+ glTexCoord2f(1, 1); glVertex3f(BarStartPosX + Width, BarStartPosY, ZBars);
+ glTexCoord2f(0, 1); glVertex3f(BarStartPosX, BarStartPosY, ZBars);
+ glEnd;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2d);
+
+ //the round thing on top
+ if (BarType = 'Note') then
+ glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarRound_Dark.TexNum);
+ if (BarType = 'Line') then
+ glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarRound_Light.TexNum);
+ if (BarType = 'Golden') then
+ glBindTexture(GL_TEXTURE_2D, aPlayerScoreScreenTextures[PlayerNumber].Score_NoteBarRound_Lightest.TexNum);
+
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex3f(BarStartPosX, (BarStartPosY - Static[StaticLevelRound[PlayerNumber + ArrayStartModifier]].Texture.h) - NewHeight, ZBars);
+ glTexCoord2f(1, 0); glVertex3f(BarStartPosX + Width, (BarStartPosY - Static[StaticLevelRound[PlayerNumber + ArrayStartModifier]].Texture.h) - NewHeight, ZBars);
+ glTexCoord2f(1, 1); glVertex3f(BarStartPosX + Width, BarStartPosY - NewHeight, ZBars);
+ glTexCoord2f(0, 1); glVertex3f(BarStartPosX, BarStartPosY - NewHeight, ZBars);
+ glEnd;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2d);
+end;
+
+procedure TScreenScore.EaseScoreIn(PlayerNumber: integer; ScoreType : String);
+const
+ RaiseSmoothness : integer = 100;
+var
+ RaiseStep : Real;
+ lTmpA : Real;
+ ScoreReached :Integer;
+ EaseOut_Step :Real;
+ ActualScoreValue:integer;
+begin
+ if (ScoreType = 'Note') then
+ begin
+ EaseOut_Step := BarScore_EaseOut_Step;
+ ActualScoreValue := TextScore_ActualValue[PlayerNumber];
+ ScoreReached := Player[PlayerNumber-1].ScoreInt;
+ end;
+ if (ScoreType = 'Line') then
+ begin
+ EaseOut_Step := BarPhrase_EaseOut_Step;
+ ActualScoreValue := TextPhrase_ActualValue[PlayerNumber];
+ ScoreReached := Player[PlayerNumber-1].ScoreLineInt;
+ end;
+ if (ScoreType = 'Golden') then
+ begin
+ EaseOut_Step := BarGolden_EaseOut_Step;
+ ActualScoreValue := TextGolden_ActualValue[PlayerNumber];
+ ScoreReached := Player[PlayerNumber-1].ScoreGoldenInt;
+ end;
+
+ // EaseOut_Step is the actual step in the raising process, like the 20iest step of EaseOut_MaxSteps
+ RaiseStep := EaseOut_Step;
+
+ if (ActualScoreValue < ScoreReached) then
+ begin
+ // Calculate the actual step according to the maxsteps
+ RaiseStep := RaiseStep / EaseOut_MaxSteps;
+
+ // quadratic easing out - decelerating to zero velocity
+ // -end_position * current_time * ( current_time - 2 ) + start_postion
+ lTmpA := (-ScoreReached * RaiseStep * (RaiseStep - 20));
+ if ( lTmpA > 0 ) AND
+ ( RaiseSmoothness > 0 ) then
+ begin
+ if (ScoreType = 'Note') then
+ TextScore_ActualValue[PlayerNumber] := floor( lTmpA / RaiseSmoothness);
+ if (ScoreType = 'Line') then
+ TextPhrase_ActualValue[PlayerNumber] := floor( lTmpA / RaiseSmoothness);
+ if (ScoreType = 'Golden') then
+ TextGolden_ActualValue[PlayerNumber] := floor( lTmpA / RaiseSmoothness);
+ end;
+ end
+ else
+ begin
+ if (ScoreType = 'Note') then
+ TextScore_ActualValue[PlayerNumber] := ScoreReached;
+ if (ScoreType = 'Line') then
+ TextPhrase_ActualValue[PlayerNumber] := ScoreReached;
+ if (ScoreType = 'Golden') then
+ TextGolden_ActualValue[PlayerNumber] := ScoreReached;
+ end;
+end;
+
+procedure TScreenScore.FillPlayer(Item, P: integer);
+var
+ S: string;
+begin
+ Text[TextName[Item]].Text := Ini.Name[P];
+
+ S := IntToStr((Round(Player[P].Score) div 10) * 10);
+ while (Length(S)<4) do
+ S := '0' + S;
+ Text[TextNotesScore[Item]].Text := S;
+
+ // while (Length(S)<5) do S := '0' + S;
+ // Text[TextTotalScore[Item]].Text := S;
+
+ //fixed: line bonus and golden notes don't show up,
+ // another bug: total score was shown without added golden-, linebonus
+ S := IntToStr(Player[P].ScoreTotalInt);
+ while (Length(S)<5) do
+ S := '0' + S;
+ Text[TextTotalScore[Item]].Text := S;
+
+ S := IntToStr(Player[P].ScoreLineInt);
+ while (Length(S)<4) do
+ S := '0' + S;
+ Text[TextLineBonusScore[Item]].Text := S;
+
+ S := IntToStr(Player[P].ScoreGoldenInt);
+ while (Length(S)<4) do
+ S := '0' + S;
+ Text[TextGoldenNotesScore[Item]].Text := S;
+ //end of fix
+
+
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenSing.pas b/Game/Code/Screens/UScreenSing.pas
index ad07a081..3dc90da3 100644
--- a/Game/Code/Screens/UScreenSing.pas
+++ b/Game/Code/Screens/UScreenSing.pas
@@ -1,1439 +1,1439 @@
-unit UScreenSing;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-
-uses UMenu,
- UMusic,
- SDL,
- SysUtils,
- UFiles,
- UTime,
- USongs,
- UIni,
- ULog,
- UTexture,
- ULyrics,
- TextGL,
- gl,
- UThemes,
- //ULCD, //TODO: maybe LCD Support as Plugin?
- UGraphicClasses,
- USingScores;
-
-type
- TScreenSing = class(TMenu)
- protected
- paused: boolean; //Pause Mod
- NumEmptySentences: integer;
- public
- //TextTime: integer;
-
- // TimeBar fields
- StaticTimeProgress: integer;
- TextTimeText: integer;
-
- StaticP1: integer;
- TextP1: integer;
- {StaticP1ScoreBG: integer;
- TextP1Score: integer;}
-
- {//moveable singbar mod
- StaticP1SingBar: integer;
- StaticP1ThreePSingBar: integer;
- StaticP1TwoPSingBar: integer;
- StaticP2RSingBar: integer;
- StaticP2MSingBar: integer;
- StaticP3SingBar: integer;
- //eoa moveable singbar }
-
- //Added for ps3 skin
- //shown when game is in 2/4 player modus
- StaticP1TwoP: integer;
- TextP1TwoP: integer;
-
- {StaticP1TwoPScoreBG: integer;
- TextP1TwoPScore: integer;}
- //shown when game is in 3/6 player modus
- StaticP1ThreeP: integer;
- TextP1ThreeP: integer;
-
- {TextP1ThreePScore: integer;
- StaticP1ThreePScoreBG: integer; }
- //eoa
-
- StaticP2R: integer;
- TextP2R: integer;
-
- {StaticP2RScoreBG: integer;
- TextP2RScore: integer;}
-
- StaticP2M: integer;
- TextP2M: integer;
-
- {StaticP2MScoreBG: integer;
- TextP2MScore: integer; }
-
- StaticP3R: integer;
- TextP3R: integer;
-
- {StaticP3RScoreBG: integer;
- TextP3RScore: integer;}
- StaticPausePopup: integer;
-
- Tex_Background: TTexture;
- FadeOut: boolean;
- //LyricMain: TLyric;
- //LyricSub: TLyric;
- Lyrics: TLyricEngine;
-
- //Score Manager:
- Scores: TSingScores;
-
- fShowVisualization : boolean;
- fCurrentVideoPlaybackEngine : IVideoPlayback;
-
- constructor Create; override;
- procedure onShow; override;
- procedure onShowFinish; override;
-
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- function Draw: boolean; override;
-
- procedure Finish; virtual;
- //procedure UpdateLCD; //TODO: maybe LCD Support as Plugin?
- procedure Pause; //Pause Mod(Toggles Pause)
-
- procedure OnSentenceEnd(SentenceIndex: Cardinal); //OnSentenceEnd for LineBonus + Singbar
- procedure OnSentenceChange(SentenceIndex: Cardinal); //OnSentenceChange (for Golden Notes)
- end;
-
-implementation
-
-uses UGraphic,
- UDraw,
- UMain,
- USong,
- Classes,
- URecord,
- ULanguage,
- math;
-
-// Method for input parsing. If False is returned, GetNextWindow
-// should be checked to know the next window to load;
-function TScreenSing.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- //When not ask before Exit then Finish now
- if (Ini.AskbeforeDel <> 1) then
- Finish
- //else just Pause and let the Popup make the Work
- else if not paused then
- Pause;
-
- Result := false;
- Exit;
- end;
- 'V': //Show Visualization
- begin
- fShowVisualization := not fShowVisualization;
-
- if fShowVisualization then
- fCurrentVideoPlaybackEngine := Visualization
- else
- fCurrentVideoPlaybackEngine := VideoPlayback;
-
- if fShowVisualization then
- fCurrentVideoPlaybackEngine.play;
-
- Exit;
- end;
- 'P':
- begin
- Pause;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- //Record Sound Hack:
- //Sound[0].BufferLong
-
- Finish;
- AudioPlayback.PlaySound(SoundLib.Back);
- FadeTo(@ScreenScore);
- end;
-
- SDLK_SPACE:
- begin
- Pause;
- end;
-
- SDLK_TAB: //Change Visualization Preset
- begin
- if fShowVisualization then
- fCurrentVideoPlaybackEngine.Position := now; // move to a random position
- end;
-
- SDLK_RETURN:
- begin
- end;
-
- // Up and Down could be done at the same time,
- // but I don't want to declare variables inside
- // functions like this one, called so many times
- SDLK_DOWN :
- begin
- end;
- SDLK_UP :
- begin
- end;
- end;
- end;
-end;
-
-//Pause Mod
-procedure TScreenSing.Pause;
-begin
- if not paused then //enable Pause
- begin
- // pause Time
- Paused := true;
-
- LineState.Pause();
-
- // pause Music
- AudioPlayback.Pause;
-
- // pause Video
- if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then
- fCurrentVideoPlaybackEngine.Pause;
-
- end
- else //disable Pause
- begin
- LineState.Resume();
-
- // Position of Music
- // FIXME: remove this and provide LineState.CurrentTime as sync-source instead
- // so every stream can synch itself
- AudioPlayback.Position := LineState.CurrentTime;
-
- // Play Music
- AudioPlayback.Play;
-
- // Video
- if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then
- fCurrentVideoPlaybackEngine.Pause;
-
- Paused := false;
- end;
-end;
-//Pause Mod End
-
-constructor TScreenSing.Create;
-var
- I: integer;
- P: integer;
-begin
- inherited Create;
-
- fShowVisualization := false;
- fCurrentVideoPlaybackEngine := VideoPlayback;
-
-
- //Create Score Class
- Scores := TSingScores.Create;
- Scores.LoadfromTheme;
-
- LoadFromTheme(Theme.Sing);
-
- //TimeBar
- StaticTimeProgress := AddStatic(Theme.Sing.StaticTimeProgress);
- TextTimeText := AddText(Theme.Sing.TextTimeText);
-
-// 1 player | P1
- StaticP1 := AddStatic(Theme.Sing.StaticP1);
- TextP1 := AddText(Theme.Sing.TextP1);
-
- {StaticP1ScoreBG := AddStatic(Theme.Sing.StaticP1ScoreBG);
- TextP1Score := AddText(Theme.Sing.TextP1Score);
- StaticP1SingBar := AddStatic(Theme.Sing.StaticP1SingBar);}
-
-// 2 or 4 players | P1
- StaticP1TwoP := AddStatic(Theme.Sing.StaticP1TwoP);
- TextP1TwoP := AddText(Theme.Sing.TextP1TwoP);
-
- {StaticP1TwoPScoreBG := AddStatic(Theme.Sing.StaticP1TwoPScoreBG);
- TextP1TwoPScore := AddText(Theme.Sing.TextP1TwoPScore);
- StaticP1TwoPSingBar := AddStatic(Theme.Sing.StaticP2RSingBar);}
-
- // | P2
- StaticP2R := AddStatic(Theme.Sing.StaticP2R);
- TextP2R := AddText(Theme.Sing.TextP2R);
-
- {StaticP2RScoreBG := AddStatic(Theme.Sing.StaticP2RScoreBG);
- TextP2RScore := AddText(Theme.Sing.TextP2RScore);
- StaticP2RSingBar := AddStatic(Theme.Sing.StaticP2RSingBar); }
-
-// 3 or 6 players | P1
- StaticP1ThreeP := AddStatic(Theme.Sing.StaticP1ThreeP);
- TextP1ThreeP := AddText(Theme.Sing.TextP1ThreeP);
-
- {StaticP1ThreePScoreBG := AddStatic(Theme.Sing.StaticP1ThreePScoreBG);
- TextP1ThreePScore := AddText(Theme.Sing.TextP1ThreePScore);
- StaticP1ThreePSingBar := AddStatic(Theme.Sing.StaticP1ThreePSingBar);}
-
- // | P2
- StaticP2M := AddStatic(Theme.Sing.StaticP2M);
- TextP2M := AddText(Theme.Sing.TextP2M);
-
- {StaticP2MScoreBG := AddStatic(Theme.Sing.StaticP2MScoreBG);
- TextP2MScore := AddText(Theme.Sing.TextP2MScore);
- StaticP2MSingBar := AddStatic(Theme.Sing.StaticP2MSingBar);}
-
- // | P3
- StaticP3R := AddStatic(Theme.Sing.StaticP3R);
- TextP3R := AddText(Theme.Sing.TextP3R);
-
- {StaticP3RScoreBG := AddStatic(Theme.Sing.StaticP3RScoreBG);
- TextP3RScore := AddText(Theme.Sing.TextP3RScore);
- StaticP3SingBar := AddStatic(Theme.Sing.StaticP3SingBar);}
-
- StaticPausePopup := AddStatic(Theme.Sing.PausePopUp);
- Static[StaticPausePopup].Visible := false; //Pausepopup is not visibile at the beginning
-
- if ScreenAct = 2 then begin
- // katze und affe
-
- end;
-
- Lyrics := TLyricEngine.Create(80,Skin_LyricsT,640,12,80,Skin_LyricsT+36,640,12);
-
- if assigned( fCurrentVideoPlaybackEngine ) then
- fCurrentVideoPlaybackEngine.Init();
-end;
-
-procedure TScreenSing.onShow;
-var
- P: integer;
- V1: boolean;
- V1TwoP: boolean; //added for ps3 skin
- V1ThreeP: boolean; //added for ps3 skin
- V2R: boolean;
- V2M: boolean;
- V3R: boolean;
- NR: TRecR; //Line Bonus Mod
-
- Color: TRGB;
-
- success: boolean;
-begin
- inherited;
-
- Log.LogStatus('Begin', 'onShow');
- FadeOut := false;
-
- // reset video playback engine, to play Video Clip...
- fCurrentVideoPlaybackEngine := VideoPlayback;
-
- // setup score manager
- Scores.ClearPlayers; // clear old player values
- Color.R := 0; Color.G := 0; Color.B := 0; // dummy atm
-
- // add new players
- for P := 0 to PlayersPlay-1 do
- begin
- Scores.AddPlayer(Tex_ScoreBG[P], Color);
- end;
-
- Scores.Init; //Get Positions for Players
-
-
-
- // prepare players
- SetLength(Player, PlayersPlay);
- //Player[0].ScoreTotalInt := 0;
-
- case PlayersPlay of
- 1: begin
- V1 := true;
- V1TwoP := false;
- V1ThreeP := false;
- V2R := false;
- V2M := false;
- V3R := false;
- end;
- 2: begin
- V1 := false;
- V1TwoP := true;
- V1ThreeP := false;
- V2R := true;
- V2M := false;
- V3R := false;
- end;
- 3: begin
- V1 := false;
- V1TwoP := false;
- V1ThreeP := true;
- V2R := false;
- V2M := true;
- V3R := true;
- end;
- 4: begin // double screen
- V1 := false;
- V1TwoP := true;
- V1ThreeP := false;
- V2R := true;
- V2M := false;
- V3R := false;
- end;
- 6: begin // double screen
- V1 := false;
- V1TwoP := false;
- V1ThreeP := true;
- V2R := false;
- V2M := true;
- V3R := true;
- end;
-
- end;
-
- //This one is shown in 1P mode
- Static[StaticP1].Visible := V1;
- Text[TextP1].Visible := V1;
-
- {Static[StaticP1ScoreBG].Visible := V1;
- Text[TextP1Score].Visible := V1;}
-
-
- //This one is shown in 2/4P mode
- Static[StaticP1TwoP].Visible := V1TwoP;
- Text[TextP1TwoP].Visible := V1TwoP;
-
- {Static[StaticP1TwoPScoreBG].Visible := V1TwoP;
- Text[TextP1TwoPScore].Visible := V1TwoP;}
-
- Static[StaticP2R].Visible := V2R;
- Text[TextP2R].Visible := V2R;
-
- {Static[StaticP2RScoreBG].Visible := V2R;
- Text[TextP2RScore].Visible := V2R; }
-
-
- //This one is shown in 3/6P mode
- Static[StaticP1ThreeP].Visible := V1ThreeP;
- Text[TextP1ThreeP].Visible := V1ThreeP;
-
- {Static[StaticP1ThreePScoreBG].Visible := V1ThreeP;
- Text[TextP1ThreePScore].Visible := V1ThreeP; }
-
- Static[StaticP2M].Visible := V2M;
- Text[TextP2M].Visible := V2M;
-
- {Static[StaticP2MScoreBG].Visible := V2M;
- Text[TextP2MScore].Visible := V2M; }
-
- Static[StaticP3R].Visible := V3R;
- Text[TextP3R].Visible := V3R;
-
- {Static[StaticP3RScoreBG].Visible := V3R;
- Text[TextP3RScore].Visible := V3R; }
-
- // FIXME: sets Path and Filename to ''
- ResetSingTemp;
-
- CurrentSong := CatSongs.Song[CatSongs.Selected];
-
- // FIXME: bad style, put the try-except into LoadSong() and not here
- try
- // Check if file is XML
- if copy(CurrentSong.FileName,length(CurrentSong.FileName)-3,4) = '.xml'
- then success := CurrentSong.LoadXMLSong()
- else success := CurrentSong.LoadSong();
- except
- success := false;
- end;
-
- if (not success) then
- begin
- // error loading song -> go back to song screen and show some error message
- FadeTo(@ScreenSong);
- // select new song in party mode
- if ScreenSong.Mode = smPartyMode then
- ScreenSong.SelectRandomSong();
- ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG'));
- // FIXME: do we need this?
- CurrentSong.Path := CatSongs.Song[CatSongs.Selected].Path;
- Exit;
- end;
-
-
-
- // reset video playback engine, to play video clip...
-
- Visualization.Init();
-
- fCurrentVideoPlaybackEngine.Close;
- fCurrentVideoPlaybackEngine := VideoPlayback;
-
- // set movie
- CurrentSong.VideoLoaded := false;
- fShowVisualization := false;
- if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then
- begin
- // TODO: use VideoGap and start time
- fCurrentVideoPlaybackEngine.Open( CurrentSong.Path + CurrentSong.Video );
- fCurrentVideoPlaybackEngine.Position := CurrentSong.VideoGAP + CurrentSong.Start;
- CurrentSong.VideoLoaded := true;
- end;
-
- // set background
- if (CurrentSong.Background <> '') and (CurrentSong.VideoLoaded = false) then
- try
- Tex_Background := Texture.LoadTexture(CurrentSong.Path + CurrentSong.Background);
- except
- log.LogError('Background could not be loaded: ' + CurrentSong.Path + CurrentSong.Background);
- Tex_Background.TexNum := 0;
- end
- else
- Tex_Background.TexNum := 0;
-
-
-
- // play music (I)
- AudioInput.CaptureStart;
- AudioPlayback.Position := CurrentSong.Start;
-// Music.Play;
-
- // prepare timer (I)
-// CountSkipTimeSet;
- LineState.CurrentTime := CurrentSong.Start;
- LineState.TotalTime := AudioPlayback.Length;
-
- if (CurrentSong.Finish > 0) then
- LineState.TotalTime := CurrentSong.Finish / 1000;
- LineState.OldBeat := -1;
- for P := 0 to High(Player) do
- ClearScores(P);
-
- // main text
- Lyrics.Clear (CurrentSong.BPM[0].BPM, CurrentSong.Resolution);
-
- // set custom options
- case Ini.LyricsFont of
- 0:
- begin
- Lyrics.UpperLineSize := 14;
- Lyrics.LowerLineSize := 14;
- Lyrics.FontStyle := 0;
-
- Lyrics.LineColor_en.R := Skin_FontR;
- Lyrics.LineColor_en.G := Skin_FontG;
- Lyrics.LineColor_en.B := Skin_FontB;
- Lyrics.LineColor_en.A := 1;
-
- Lyrics.LineColor_dis.R := 0.4;
- Lyrics.LineColor_dis.G := 0.4;
- Lyrics.LineColor_dis.B := 0.4;
- Lyrics.LineColor_dis.A := 1;
-
- Lyrics.LineColor_act.R := 5/256;
- Lyrics.LineColor_act.G := 163/256;
- Lyrics.LineColor_act.B := 210/256;
- Lyrics.LineColor_act.A := 1;
-
- {
- LyricSub.FontStyle := 0;
- LyricMain.Size := 14; // 13
- LyricSub.Size := 14; // 13
- LyricMain.ColR := Skin_FontR;
- LyricMain.ColG := Skin_FontG;
- LyricMain.ColB := Skin_FontB; //Change für Crazy Joker
- }
- {
- LyricMain.ColSR := Skin_FontHighlightR;
- LyricMain.ColSG := Skin_FontHighlightG;
- LyricMain.ColSB := Skin_FontHighlightB;
- }{
- LyricMain.ColSR := 5/255; //26
- LyricMain.ColSG := 163/255; //165
- LyricMain.ColSB := 210/255; //220
-
- LyricSub.ColR := 0.4; //0.6
- LyricSub.ColG := 0.4; //0.6
- LyricSub.ColB := 0.4; //0.6
- }
- end;
- 1:
- begin
- {
- LyricMain.FontStyle := 2;
- LyricSub.FontStyle := 2;
- LyricMain.Size := 14;
- LyricSub.Size := 14;
- LyricMain.ColR := 0.75;
- LyricMain.ColG := 0.75;
- LyricMain.ColB := 1;
- LyricMain.ColSR := 0.5;
- LyricMain.ColSG := 0.5;
- LyricMain.ColSB := 1;
- LyricSub.ColR := 0.8;
- LyricSub.ColG := 0.8;
- LyricSub.ColB := 0.8;
- }
-
- Lyrics.UpperLineSize := 14;
- Lyrics.LowerLineSize := 14;
- Lyrics.FontStyle := 2;
-
- Lyrics.LineColor_en.R := 0.75;
- Lyrics.LineColor_en.G := 0.75;
- Lyrics.LineColor_en.B := 1;
- Lyrics.LineColor_en.A := 1;
-
- Lyrics.LineColor_dis.R := 0.8;
- Lyrics.LineColor_dis.G := 0.8;
- Lyrics.LineColor_dis.B := 0.8;
- Lyrics.LineColor_dis.A := 1;
-
- Lyrics.LineColor_act.R := 0.5;
- Lyrics.LineColor_act.G := 0.5;
- Lyrics.LineColor_act.B := 1;
- Lyrics.LineColor_act.A := 1;
- end;
- 2:
- begin
- Lyrics.UpperLineSize := 12;
- Lyrics.LowerLineSize := 12;
- Lyrics.FontStyle := 3;
-
- Lyrics.LineColor_en.R := 0.75;
- Lyrics.LineColor_en.G := 0.75;
- Lyrics.LineColor_en.B := 1;
- Lyrics.LineColor_en.A := 1;
-
- Lyrics.LineColor_dis.R := 0.8;
- Lyrics.LineColor_dis.G := 0.8;
- Lyrics.LineColor_dis.B := 0.8;
- Lyrics.LineColor_dis.A := 1;
-
- Lyrics.LineColor_act.R := 0.5;
- Lyrics.LineColor_act.G := 0.5;
- Lyrics.LineColor_act.B := 1;
- Lyrics.LineColor_act.A := 1;
- {
- LyricSub.FontStyle := 3;
- LyricMain.Size := 12;
- LyricSub.Size := 12;
- LyricMain.ColR := 0.75;
- LyricMain.ColG := 0.75;
- LyricMain.ColB := 1;
- LyricMain.ColSR := 0.5;
- LyricMain.ColSG := 0.5;
- LyricMain.ColSB := 1;
- LyricSub.ColR := 0.8;
- LyricSub.ColG := 0.8;
- LyricSub.ColB := 0.8;
- }
- end;
- end; // case
-
- // Add lines to lyrics
- while (not Lyrics.LineinQueue) and (Lyrics.LineCounter <= High(Lines[0].Line)) do
- Lyrics.AddLine(@Lines[0].Line[Lyrics.LineCounter]);
-
- //UpdateLCD; //TODO: maybe LCD Support as Plugin?
-
- // Deactivate pause
- Paused := False;
-
- // Kill all stars not killed yet (GoldenStarsTwinkle Mod)
- GoldenRec.SentenceChange;
-
- {//Set Position of Line Bonus - Line Bonus start
- if (Ini.LineBonus = 1) then //Show Line Bonus at Scores
- begin
- Case PlayersPlay of
- 1: begin
- Player[0].LineBonus_TargetX := Theme.Sing.StaticP1ScoreBG.x;
- Player[0].LineBonus_TargetY := Theme.Sing.TextP1Score.Y;
- Player[0].LineBonus_StartX := Theme.Sing.StaticP1ScoreBG.x;
- Player[0].LineBonus_StartY := Theme.Sing.TextP1Score.Y + 65;
- end;
-
- 2: begin
- //P1
- Player[0].LineBonus_TargetX := Theme.Sing.StaticP1TwoPScoreBG.x;
- Player[0].LineBonus_TargetY := Theme.Sing.TextP1TwoPScore.Y;
- Player[0].LineBonus_StartX := Theme.Sing.StaticP1TwoPScoreBG.X;
- Player[0].LineBonus_StartY := Theme.Sing.TextP1TwoPScore.Y + 65;
-
- //P2
- Player[1].LineBonus_TargetX := Theme.Sing.StaticP2RScoreBG.X;
- Player[1].LineBonus_TargetY := Theme.Sing.TextP2RScore.Y;
- Player[1].LineBonus_StartX := Theme.Sing.StaticP2RScoreBG.X;
- Player[1].LineBonus_StartY := Theme.Sing.TextP2RScore.Y + 65;
- end;
-
- 3: begin
- //P1
- Player[0].LineBonus_TargetX := Theme.Sing.StaticP1ThreePScoreBG.x;
- Player[0].LineBonus_TargetY := Theme.Sing.TextP1ThreePScore.Y;
- Player[0].LineBonus_StartX := Theme.Sing.StaticP1ThreePScoreBG.x;
- Player[0].LineBonus_StartY := Theme.Sing.TextP1ThreePScore.Y + 65;
-
- //P2
- Player[1].LineBonus_TargetX := Theme.Sing.StaticP2MScoreBG.x;
- Player[1].LineBonus_TargetY := Theme.Sing.TextP2MScore.Y;
- Player[1].LineBonus_StartX := Theme.Sing.StaticP2MScoreBG.x;
- Player[1].LineBonus_StartY := Theme.Sing.TextP2MScore.Y + 65;
-
- //P3
- Player[2].LineBonus_TargetX := Theme.Sing.StaticP3RScoreBG.x;
- Player[2].LineBonus_TargetY := Theme.Sing.TextP3RScore.Y;
- Player[2].LineBonus_StartX := Theme.Sing.StaticP3RScoreBG.x;
- Player[2].LineBonus_StartY := Theme.Sing.TextP3RScore.Y + 65;
- end;
-
- 4: begin
- //P1
- Player[0].LineBonus_TargetX := Theme.Sing.StaticP1TwoPScoreBG.x;
- Player[0].LineBonus_TargetY := Theme.Sing.TextP1TwoPScore.Y;
- Player[0].LineBonus_StartX := Theme.Sing.StaticP1TwoPScoreBG.x;
- Player[0].LineBonus_StartY := Theme.Sing.TextP1TwoPScore.Y + 65;
-
- //P2
- Player[1].LineBonus_TargetX := Theme.Sing.StaticP2RScoreBG.x;
- Player[1].LineBonus_TargetY := Theme.Sing.TextP2RScore.Y;
- Player[1].LineBonus_StartX := Theme.Sing.StaticP2RScoreBG.x;
- Player[1].LineBonus_StartY := Theme.Sing.TextP2RScore.Y + 65;
-
- //P3
- Player[2].LineBonus_TargetX := Theme.Sing.StaticP1TwoPScoreBG.x;
- Player[2].LineBonus_TargetY := Theme.Sing.TextP1TwoPScore.Y;
- Player[2].LineBonus_StartX := Theme.Sing.StaticP1TwoPScoreBG.x;
- Player[2].LineBonus_StartY := Theme.Sing.TextP1TwoPScore.Y + 65;
-
- //P4
- Player[3].LineBonus_TargetX := Theme.Sing.StaticP2RScoreBG.x;
- Player[3].LineBonus_TargetY := Theme.Sing.TextP2RScore.Y;
- Player[3].LineBonus_StartX := Theme.Sing.StaticP2RScoreBG.x;
- Player[3].LineBonus_StartY := Theme.Sing.TextP2RScore.Y + 65;
- end;
-
- 6: begin
- //P1
- Player[0].LineBonus_TargetX := Theme.Sing.StaticP1ThreePScoreBG.x;
- Player[0].LineBonus_TargetY := Theme.Sing.TextP1ThreePScore.Y;
- Player[0].LineBonus_StartX := Theme.Sing.StaticP1ThreePScoreBG.x;
- Player[0].LineBonus_StartY := Theme.Sing.TextP1ThreePScore.Y + 65;
-
- //P2
- Player[1].LineBonus_TargetX := Theme.Sing.StaticP2MScoreBG.x;
- Player[1].LineBonus_TargetY := Theme.Sing.TextP2MScore.Y;
- Player[1].LineBonus_StartX := Theme.Sing.StaticP2MScoreBG.x;
- Player[1].LineBonus_StartY := Theme.Sing.TextP2MScore.Y + 65;
-
- //P3
- Player[2].LineBonus_TargetX := Theme.Sing.StaticP3RScoreBG.x;
- Player[2].LineBonus_TargetY := Theme.Sing.TextP3RScore.Y;
- Player[2].LineBonus_StartX := Theme.Sing.StaticP3RScoreBG.x;
- Player[2].LineBonus_StartY := Theme.Sing.TextP3RScore.Y + 65;
-
- //P4
- Player[3].LineBonus_TargetX := Theme.Sing.StaticP1ThreePScoreBG.x;
- Player[3].LineBonus_TargetY := Theme.Sing.TextP1ThreePScore.Y;
- Player[3].LineBonus_StartX := Theme.Sing.StaticP1ThreePScoreBG.x;
- Player[3].LineBonus_StartY := Theme.Sing.TextP1ThreePScore.Y + 65;
-
- //P5
- Player[4].LineBonus_TargetX := Theme.Sing.StaticP2MScoreBG.x;
- Player[4].LineBonus_TargetY := Theme.Sing.TextP2MScore.Y;
- Player[4].LineBonus_StartX := Theme.Sing.StaticP2MScoreBG.x;
- Player[4].LineBonus_StartY := Theme.Sing.TextP2MScore.Y + 65;
-
- //P6
- Player[5].LineBonus_TargetX := Theme.Sing.StaticP3RScoreBG.x;
- Player[5].LineBonus_TargetY := Theme.Sing.TextP3RScore.Y;
- Player[5].LineBonus_StartX := Theme.Sing.StaticP3RScoreBG.x;
- Player[5].LineBonus_StartY := Theme.Sing.TextP3RScore.Y + 65;
- end;
- end;
- end
- else if (Ini.LineBonus = 2) then //Show Line Bonus at Notes
- begin
-
- // positions
- if Ini.SingWindow = 0 then begin
- NR.Left := 120;
- end else begin
- NR.Left := 20;
- end;
- NR.Right := 780;
-
- NR.Width := NR.Right - NR.Left;
- NR.WMid := NR.Width / 2;
- NR.Mid := NR.Left + NR.WMid;
-
- Case PlayersPlay of
- 1: begin
- Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65;
- Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_StartY := Skin_P2_NotesB - 105;
- end;
-
- 2: begin
- //P1
- Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
- Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
-
- //P2
- Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
- Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
- end;
-
- 3: begin
- //P1
- Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_TargetY := 120 - 65 + 28;
- Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_StartY := 120 + 28;
-
- //P2
- Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_TargetY := 245 - 65 + 28;
- Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_StartY := 245 + 28;
-
- //P3
- Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[2].LineBonus_TargetY := 370 - 65 + 28;
- Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[2].LineBonus_StartY := 370 + 28;
- end;
-
- 4: begin
- //P1
- Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
- Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
-
- //P2
- Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
- Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
-
- //P3
- Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[2].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
- Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[2].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
-
- //P4
- Player[3].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[3].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
- Player[3].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[3].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
- end;
-
- 6: begin
- //P1
- Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_TargetY := 120 - 65 + 28;
- Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_StartY := 120 + 28;
-
- //P2
- Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_TargetY := 245 - 65 + 28;
- Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_StartY := 245 + 28;
-
- //P3
- Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[2].LineBonus_TargetY := 370 - 65 + 28;
- Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[2].LineBonus_StartY := 370 + 28;
-
- //P4
- Player[3].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[3].LineBonus_TargetY := 120 - 65 + 28;
- Player[3].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[3].LineBonus_StartY := 120 + 28;
-
- //P5
- Player[4].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[4].LineBonus_TargetY := 245 - 65 + 28;
- Player[4].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[4].LineBonus_StartY := 245 + 28;
-
- //P6
- Player[5].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[5].LineBonus_TargetY := 370 - 65 + 28;
- Player[5].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[5].LineBonus_StartY := 370 + 28;
- end;
- end;
- end; }
-
- // set Position of Line Bonus - Line Bonus end
- // set number of empty sentences for Line Bonus
- NumEmptySentences := 0;
- for P := Low(Lines[0].Line) to High(Lines[0].Line) do
- if Lines[0].Line[P].TotalNotes = 0 then Inc(NumEmptySentences);
-
- Log.LogStatus('End', 'onShow');
-end;
-
-procedure TScreenSing.onShowFinish;
-begin
- // play movie (II)
-
- if CurrentSong.VideoLoaded then
- begin
- try
- fCurrentVideoPlaybackEngine.GetFrame(LineState.CurrentTime);
- fCurrentVideoPlaybackEngine.DrawGL(ScreenAct);
- except on E : Exception do
- begin
- //If an error occurs reading video: prevent video from being drawn again and close video
- CurrentSong.VideoLoaded := False;
- Log.LogError('Error drawing Video, Video has been disabled for this Song/Session.');
- Log.LogError('Error Message : '+ E.message );
- Log.LogError(' In : '+ E.ClassName +' (TScreenSing.onShowFinish)' );
- Log.LogError('Corrupted File: ' + CurrentSong.Video);
-
- fCurrentVideoPlaybackEngine.Close;
- end;
- end;
- end;
-
-
- // play music (II)
- AudioPlayback.Play;
-
- // prepare timer (II)
- CountSkipTimeSet;
-end;
-
-function TScreenSing.Draw: boolean;
-var
- Min: integer;
- Sec: integer;
- Tekst: string;
- Flash: real;
- S: integer;
- T: integer;
-begin
- // ScoreBG Mod
- // TODO: remove this commented out section as we do not need it anymore.
- // We use colorized png's now. Set player colors does nothing than changing
- // the colors of the statics which will lead to ugly effects on colorized pngs
- {
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
- Static[StaticP1TwoP].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P2Dark');
-
- LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
- Static[StaticP1TwoPScoreBG].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
- end;
- if ScreenAct = 2 then begin
- LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
- Static[StaticP1TwoP].Texture.ColB, 'P3Dark');
- LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P4Dark');
-
- LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
- Static[StaticP1TwoPScoreBG].Texture.ColB, 'P3Dark');
- LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P4Dark');
- end;
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
- Static[StaticP1ThreeP].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P2Dark');
- LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
- Static[StaticP3R].Texture.ColB, 'P3Dark');
-
- LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
- Static[StaticP1ThreePScoreBG].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
- LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
- Static[StaticP3RScoreBG].Texture.ColB, 'P3Dark');
- end;
- if ScreenAct = 2 then begin
-
- LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
- Static[StaticP1ThreeP].Texture.ColB, 'P4Dark');
- LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P5Dark');
- LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
- Static[StaticP3R].Texture.ColB, 'P6Dark');
-
-
- LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
- Static[StaticP1ThreePScoreBG].Texture.ColB, 'P4Dark');
- LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P5Dark');
- LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
- Static[StaticP3RScoreBG].Texture.ColB, 'P6Dark');
- end;
- end;
- }
-
- // set player names (for 2 screens and only Singstar skin)
- if ScreenAct = 1 then begin
- Text[TextP1].Text := 'P1';
- Text[TextP1TwoP].Text := 'P1';
- Text[TextP1ThreeP].Text := 'P1';
- Text[TextP2R].Text := 'P2';
- Text[TextP2M].Text := 'P2';
- Text[TextP3R].Text := 'P3';
- end;
-
- if ScreenAct = 2 then begin
- case PlayersPlay of
- {
- 1: begin
- Text[TextP1].Text := 'P2';
- end;
- 2: begin
- Text[TextP1].Text := 'P3';
- Text[TextP2R].Text := 'P4';
- end;
- 3: begin
- Text[TextP1].Text := 'P4';
- Text[TextP2M].Text := 'P5';
- Text[TextP3R].Text := 'P6';
- end;
- }
- 4: begin
- Text[TextP1TwoP].Text := 'P3';
- Text[TextP2R].Text := 'P4';
- end;
- 6: begin
- Text[TextP1ThreeP].Text := 'P4';
- Text[TextP2M].Text := 'P5';
- Text[TextP3R].Text := 'P6';
- end;
- end; // case
- end; // if
-
-
- ////
- // dual screen, part 1
- ////////////////////////
-
- // Note: ScreenX is the offset of the current screen in dual-screen mode so we
- // will move the statics and texts to the correct screen here.
- // FIXME: clean up this weird stuff. Commenting this stuff out, nothing
- // was missing on screen w/ 6 players - so do we even need this stuff?
- Static[StaticP1].Texture.X := Static[StaticP1].Texture.X + 10*ScreenX;
-
- Text[TextP1].X := Text[TextP1].X + 10*ScreenX;
-
- {Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X + 10*ScreenX;
- Text[TextP1Score].X := Text[TextP1Score].X + 10*ScreenX;}
-
-
- Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X + 10*ScreenX;
-
- Text[TextP2R].X := Text[TextP2R].X + 10*ScreenX;
-
- {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X + 10*ScreenX;
- Text[TextP2RScore].X := Text[TextP2RScore].X + 10*ScreenX;}
-
- // end of weird stuff
-
- Static[1].Texture.X := Static[1].Texture.X + 10*ScreenX;
-
- for T := 0 to 1 do
- Text[T].X := Text[T].X + 10*ScreenX;
-
- // update static menu with time ...
- Min := Round(LineState.CurrentTime) div 60;
- Sec := Round(LineState.CurrentTime) mod 60;
- Text[TextTimeText].Text := '';
- if Min < 10 then Text[TextTimeText].Text := '0';
- Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Min) + ':';
- if Sec < 10 then Text[TextTimeText].Text := Text[TextTimeText].Text + '0';
- Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Sec);
-
- {// .. and scores
- if PlayersPlay = 1 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1Score].Text := Tekst;
- end;
-
- if PlayersPlay = 2 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1TwoPScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2RScore].Text := Tekst;
- end;
-
- if PlayersPlay = 3 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1ThreePScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2MScore].Text := Tekst;
-
- Tekst := IntToStr(Player[2].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP3RScore].Text := Tekst;
- end;
-
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1TwoPScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2RScore].Text := Tekst;
- end;
- if ScreenAct = 2 then begin
- Tekst := IntToStr(Player[2].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1TwoPScore].Text := Tekst;
-
- Tekst := IntToStr(Player[3].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2RScore].Text := Tekst;
- end;
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1ThreePScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2MScore].Text := Tekst;
-
- Tekst := IntToStr(Player[2].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP3RScore].Text := Tekst;
- end;
- if ScreenAct = 2 then begin
- Tekst := IntToStr(Player[3].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1ThreePScore].Text := Tekst;
-
- Tekst := IntToStr(Player[4].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2MScore].Text := Tekst;
-
- Tekst := IntToStr(Player[5].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP3RScore].Text := Tekst;
- end;
- end; }
-
- // draw static menu (BG)
- // Note: there is no menu and the animated background brakes the video playback
- //DrawBG;
-
- // Draw Background
- SingDrawBackground;
-
- // update and draw movie
- if (ShowFinish and
- (CurrentSong.VideoLoaded or fShowVisualization)) then
- begin
- //try
- // TODO: find a way to determine, when a new frame is needed
- // TODO: same for the need to skip frames
- if assigned( fCurrentVideoPlaybackEngine ) then
- begin
- fCurrentVideoPlaybackEngine.GetFrame(LineState.CurrentTime);
- fCurrentVideoPlaybackEngine.DrawGL(ScreenAct);
- end;
- (*
- except
- on E : Exception do
- begin
- //If an Error occurs drawing: prevent Video from being Drawn again and Close Video
- CurrentSong.VideoLoaded := False;
- log.LogError('Error drawing Video, Video has been disabled for this Song/Session.');
- Log.LogError('Error Message : '+ E.message );
- Log.LogError(' In : '+ E.ClassName +' (TScreenSing.Draw)' );
-
- Log.LogError('Corrupted File: ' + CurrentSong.Video);
- fCurrentVideoPlaybackEngine.Close;
- end;
- end;
- *)
- end;
-
- // draw static menu (FG)
- DrawFG;
-
- // check for music finish
- //Log.LogError('Check for music finish: ' + BoolToStr(Music.Finished) + ' ' + FloatToStr(LineState.CurrentTime*1000) + ' ' + IntToStr(CurrentSong.Finish));
- if ShowFinish then
- begin
- if (not AudioPlayback.Finished) and
- ((CurrentSong.Finish = 0) or (LineState.CurrentTime*1000 <= CurrentSong.Finish)) then
- begin
- // analyze song if not paused
- if (not Paused) then
- Sing(Self);
- end
- else
- begin
- if (not FadeOut) then
- begin
- Finish;
- FadeOut := true;
- FadeTo(@ScreenScore);
- end;
- end;
- end;
-
- // always draw custom items
- SingDraw;
-
- //GoldenNoteStarsTwinkle
- GoldenRec.SpawnRec;
-
- //Draw Scores
- Scores.Draw;
-
- ////
- // dual screen, part 2
- ////////////////////////
-
- // Note: ScreenX is the offset of the current screen in dual-screen mode so we
- // will move the statics and texts to the correct screen here.
- // FIXME: clean up this weird stuff
-
- Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10*ScreenX;
- Text[TextP1].X := Text[TextP1].X - 10*ScreenX;
-
- {Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X - 10*ScreenX;
- Text[TextP1Score].X := Text[TextP1Score].X - 10*ScreenX;}
-
-
- Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X - 10*ScreenX;
- Text[TextP2R].X := Text[TextP2R].X - 10*ScreenX;
-
- {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X - 10*ScreenX;
- Text[TextP2RScore].X := Text[TextP2RScore].X - 10*ScreenX;}
-
- //end of weird
-
- Static[1].Texture.X := Static[1].Texture.X - 10*ScreenX;
-
- for T := 0 to 1 do
- Text[T].X := Text[T].X - 10*ScreenX;
-
- // Draw Pausepopup
- // FIXME: this is a workaround that the Static is drawn over the Lyrics, Lines, Scores and Effects
- // maybe someone could find a better solution
- if Paused then
- begin
- Static[StaticPausePopup].Visible := true;
- Static[StaticPausePopup].Draw;
- Static[StaticPausePopup].Visible := false;
- end;
-
-end;
-
-procedure TScreenSing.Finish;
-begin
- AudioInput.CaptureStop;
- AudioPlayback.Stop;
-
- if (Ini.SavePlayback = 1) then begin
- Log.BenchmarkStart(0);
- Log.LogVoice(0);
- Log.LogVoice(1);
- Log.LogVoice(2);
- Log.BenchmarkEnd(0);
- Log.LogBenchmark('Creating files', 0);
- end;
-
- if CurrentSong.VideoLoaded then
- begin
- fCurrentVideoPlaybackEngine.Close;
- CurrentSong.VideoLoaded := false; // to prevent drawing closed video
- end;
-
- SetFontItalic (False);
-end;
-
-(*
-procedure TScreenSing.UpdateLCD; //TODO: maybe LCD Support as Plugin?
-var
- T: string;
-begin
- //Todo: Lyrics
-{ LCD.HideCursor;
- LCD.Clear;
-
- T := LyricMain.Text;
- if Copy(T, Length(T), 1) <> ' ' then T := T + ' ';
- LCD.AddTextBR(T);
-
- T := LyricSub.Text;
- if Copy(T, Length(T), 1) <> ' ' then T := T + ' ';
- LCD.AddTextBR(T);}
-end;
-*)
-
-procedure TScreenSing.OnSentenceEnd(SentenceIndex: Cardinal);
-var
- PlayerIndex: Integer;
- CurrentPlayer: PPLayer;
- CurrentScore: Real;
- Line: PLine;
- LinePerfection: Real; // perfection of singing performance on the current line
- Rating: integer;
- LineScore: Real;
- LineBonus: Real;
- MaxSongScore: integer; // max. points for the song (without line bonus)
- MaxLineScore: Real; // max. points for the current line
-const
- // TODO: move this to a better place
- MAX_LINE_RATING = 8; // max. rating for singing performance
-begin
- Line := @Lines[0].Line[SentenceIndex];
-
- // check for empty sentence
- if (Line.TotalNotes <= 0) then
- Exit;
-
- // set max song score
- if (Ini.LineBonus = 0) then
- MaxSongScore := MAX_SONG_SCORE
- else
- MaxSongScore := MAX_SONG_SCORE - MAX_SONG_LINE_BONUS;
-
- // Note: ScoreValue is the sum of all note values of the song
- MaxLineScore := MaxSongScore * (Line.TotalNotes / Lines[0].ScoreValue);
-
- for PlayerIndex := 0 to High(Player) do
- begin
- CurrentPlayer := @Player[PlayerIndex];
- CurrentScore := CurrentPlayer.Score + CurrentPlayer.ScoreGolden;
-
- // Line Bonus
-
- // points for this line
- LineScore := CurrentScore - CurrentPlayer.ScoreLast;
-
- // determine LinePerfection
- // Note: the "+2" extra points are a little bonus so the player does not
- // have to be that perfect to reach the bonus steps.
- LinePerfection := (LineScore + 2) / MaxLineScore;
-
- // clamp LinePerfection to range [0..1]
- if (LinePerfection < 0) then
- LinePerfection := 0
- else if (LinePerfection > 1) then
- LinePerfection := 1;
-
- // add line-bonus if enabled
- if (Ini.LineBonus > 0) then
- begin
- // line-bonus points (same for each line, no matter how long the line is)
- LineBonus := MAX_SONG_LINE_BONUS /
- (Length(Lines[0].Line) - NumEmptySentences);
- // apply line-bonus
- CurrentPlayer.ScoreLine := CurrentPlayer.ScoreLine +
- LineBonus * LinePerfection;
- CurrentPlayer.ScoreLineInt := Round(CurrentPlayer.ScoreLine / 10) * 10;
- // update total score
- CurrentPlayer.ScoreTotalInt := CurrentPlayer.ScoreInt +
- CurrentPlayer.ScoreGoldenInt +
- CurrentPlayer.ScoreLineInt;
-
- // spawn rating pop-up
- Rating := Round(LinePerfection * MAX_LINE_RATING);
- Scores.SpawnPopUp(PlayerIndex, Rating, CurrentPlayer.ScoreTotalInt);
- end;
-
- // PerfectLineTwinkle (effect), Part 1
- If (Ini.EffectSing = 1) then
- CurrentPlayer.LastSentencePerfect := (LinePerfection >= 1);
-
- // refresh last score
- CurrentPlayer.ScoreLast := CurrentScore;
- end;
-
- // PerfectLineTwinkle (effect), Part 2
- if (Ini.EffectSing = 1) then
- GoldenRec.SpawnPerfectLineTwinkle;
-end;
-
-//Called on Sentence Change S= New Current Sentence
-procedure TScreenSing.OnSentenceChange(SentenceIndex: Cardinal);
-begin
- //GoldenStarsTwinkle Mod
- GoldenRec.SentenceChange;
- if (Lyrics.LineCounter <= High(Lines[0].Line)) then
- begin
- Lyrics.AddLine(@Lines[0].Line[Lyrics.LineCounter]);
- end
- else
- Lyrics.AddLine(nil);
-
- // addline uses display memory
- // calling draw makes sure, there's the singscreen in it, when the next
- // swap between onscreen and offscreen buffers is done
- // (this eliminates the onSentenceChange flickering)
- // note: maybe it would be better to make sure, a display redraw is done
- // right after the sentence change (before buffer swap) or make sure
- // onsentencechange is only called right before calling Display.Draw
- // (or whatever it was called)
- Draw;
-
- //GoldenStarsTwinkle Mod End
-end;
-
-end.
+unit UScreenSing;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+
+uses UMenu,
+ UMusic,
+ SDL,
+ SysUtils,
+ UFiles,
+ UTime,
+ USongs,
+ UIni,
+ ULog,
+ UTexture,
+ ULyrics,
+ TextGL,
+ gl,
+ UThemes,
+ //ULCD, //TODO: maybe LCD Support as Plugin?
+ UGraphicClasses,
+ USingScores;
+
+type
+ TScreenSing = class(TMenu)
+ protected
+ paused: boolean; //Pause Mod
+ NumEmptySentences: integer;
+ public
+ //TextTime: integer;
+
+ // TimeBar fields
+ StaticTimeProgress: integer;
+ TextTimeText: integer;
+
+ StaticP1: integer;
+ TextP1: integer;
+ {StaticP1ScoreBG: integer;
+ TextP1Score: integer;}
+
+ {//moveable singbar mod
+ StaticP1SingBar: integer;
+ StaticP1ThreePSingBar: integer;
+ StaticP1TwoPSingBar: integer;
+ StaticP2RSingBar: integer;
+ StaticP2MSingBar: integer;
+ StaticP3SingBar: integer;
+ //eoa moveable singbar }
+
+ //Added for ps3 skin
+ //shown when game is in 2/4 player modus
+ StaticP1TwoP: integer;
+ TextP1TwoP: integer;
+
+ {StaticP1TwoPScoreBG: integer;
+ TextP1TwoPScore: integer;}
+ //shown when game is in 3/6 player modus
+ StaticP1ThreeP: integer;
+ TextP1ThreeP: integer;
+
+ {TextP1ThreePScore: integer;
+ StaticP1ThreePScoreBG: integer; }
+ //eoa
+
+ StaticP2R: integer;
+ TextP2R: integer;
+
+ {StaticP2RScoreBG: integer;
+ TextP2RScore: integer;}
+
+ StaticP2M: integer;
+ TextP2M: integer;
+
+ {StaticP2MScoreBG: integer;
+ TextP2MScore: integer; }
+
+ StaticP3R: integer;
+ TextP3R: integer;
+
+ {StaticP3RScoreBG: integer;
+ TextP3RScore: integer;}
+ StaticPausePopup: integer;
+
+ Tex_Background: TTexture;
+ FadeOut: boolean;
+ //LyricMain: TLyric;
+ //LyricSub: TLyric;
+ Lyrics: TLyricEngine;
+
+ //Score Manager:
+ Scores: TSingScores;
+
+ fShowVisualization : boolean;
+ fCurrentVideoPlaybackEngine : IVideoPlayback;
+
+ constructor Create; override;
+ procedure onShow; override;
+ procedure onShowFinish; override;
+
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+
+ procedure Finish; virtual;
+ //procedure UpdateLCD; //TODO: maybe LCD Support as Plugin?
+ procedure Pause; //Pause Mod(Toggles Pause)
+
+ procedure OnSentenceEnd(SentenceIndex: Cardinal); //OnSentenceEnd for LineBonus + Singbar
+ procedure OnSentenceChange(SentenceIndex: Cardinal); //OnSentenceChange (for Golden Notes)
+ end;
+
+implementation
+
+uses UGraphic,
+ UDraw,
+ UMain,
+ USong,
+ Classes,
+ URecord,
+ ULanguage,
+ math;
+
+// Method for input parsing. If False is returned, GetNextWindow
+// should be checked to know the next window to load;
+function TScreenSing.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ //When not ask before Exit then Finish now
+ if (Ini.AskbeforeDel <> 1) then
+ Finish
+ //else just Pause and let the Popup make the Work
+ else if not paused then
+ Pause;
+
+ Result := false;
+ Exit;
+ end;
+ 'V': //Show Visualization
+ begin
+ fShowVisualization := not fShowVisualization;
+
+ if fShowVisualization then
+ fCurrentVideoPlaybackEngine := Visualization
+ else
+ fCurrentVideoPlaybackEngine := VideoPlayback;
+
+ if fShowVisualization then
+ fCurrentVideoPlaybackEngine.play;
+
+ Exit;
+ end;
+ 'P':
+ begin
+ Pause;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ //Record Sound Hack:
+ //Sound[0].BufferLong
+
+ Finish;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenScore);
+ end;
+
+ SDLK_SPACE:
+ begin
+ Pause;
+ end;
+
+ SDLK_TAB: //Change Visualization Preset
+ begin
+ if fShowVisualization then
+ fCurrentVideoPlaybackEngine.Position := now; // move to a random position
+ end;
+
+ SDLK_RETURN:
+ begin
+ end;
+
+ // Up and Down could be done at the same time,
+ // but I don't want to declare variables inside
+ // functions like this one, called so many times
+ SDLK_DOWN :
+ begin
+ end;
+ SDLK_UP :
+ begin
+ end;
+ end;
+ end;
+end;
+
+//Pause Mod
+procedure TScreenSing.Pause;
+begin
+ if not paused then //enable Pause
+ begin
+ // pause Time
+ Paused := true;
+
+ LineState.Pause();
+
+ // pause Music
+ AudioPlayback.Pause;
+
+ // pause Video
+ if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then
+ fCurrentVideoPlaybackEngine.Pause;
+
+ end
+ else //disable Pause
+ begin
+ LineState.Resume();
+
+ // Position of Music
+ // FIXME: remove this and provide LineState.CurrentTime as sync-source instead
+ // so every stream can synch itself
+ AudioPlayback.Position := LineState.CurrentTime;
+
+ // Play Music
+ AudioPlayback.Play;
+
+ // Video
+ if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then
+ fCurrentVideoPlaybackEngine.Pause;
+
+ Paused := false;
+ end;
+end;
+//Pause Mod End
+
+constructor TScreenSing.Create;
+var
+ I: integer;
+ P: integer;
+begin
+ inherited Create;
+
+ fShowVisualization := false;
+ fCurrentVideoPlaybackEngine := VideoPlayback;
+
+
+ //Create Score Class
+ Scores := TSingScores.Create;
+ Scores.LoadfromTheme;
+
+ LoadFromTheme(Theme.Sing);
+
+ //TimeBar
+ StaticTimeProgress := AddStatic(Theme.Sing.StaticTimeProgress);
+ TextTimeText := AddText(Theme.Sing.TextTimeText);
+
+// 1 player | P1
+ StaticP1 := AddStatic(Theme.Sing.StaticP1);
+ TextP1 := AddText(Theme.Sing.TextP1);
+
+ {StaticP1ScoreBG := AddStatic(Theme.Sing.StaticP1ScoreBG);
+ TextP1Score := AddText(Theme.Sing.TextP1Score);
+ StaticP1SingBar := AddStatic(Theme.Sing.StaticP1SingBar);}
+
+// 2 or 4 players | P1
+ StaticP1TwoP := AddStatic(Theme.Sing.StaticP1TwoP);
+ TextP1TwoP := AddText(Theme.Sing.TextP1TwoP);
+
+ {StaticP1TwoPScoreBG := AddStatic(Theme.Sing.StaticP1TwoPScoreBG);
+ TextP1TwoPScore := AddText(Theme.Sing.TextP1TwoPScore);
+ StaticP1TwoPSingBar := AddStatic(Theme.Sing.StaticP2RSingBar);}
+
+ // | P2
+ StaticP2R := AddStatic(Theme.Sing.StaticP2R);
+ TextP2R := AddText(Theme.Sing.TextP2R);
+
+ {StaticP2RScoreBG := AddStatic(Theme.Sing.StaticP2RScoreBG);
+ TextP2RScore := AddText(Theme.Sing.TextP2RScore);
+ StaticP2RSingBar := AddStatic(Theme.Sing.StaticP2RSingBar); }
+
+// 3 or 6 players | P1
+ StaticP1ThreeP := AddStatic(Theme.Sing.StaticP1ThreeP);
+ TextP1ThreeP := AddText(Theme.Sing.TextP1ThreeP);
+
+ {StaticP1ThreePScoreBG := AddStatic(Theme.Sing.StaticP1ThreePScoreBG);
+ TextP1ThreePScore := AddText(Theme.Sing.TextP1ThreePScore);
+ StaticP1ThreePSingBar := AddStatic(Theme.Sing.StaticP1ThreePSingBar);}
+
+ // | P2
+ StaticP2M := AddStatic(Theme.Sing.StaticP2M);
+ TextP2M := AddText(Theme.Sing.TextP2M);
+
+ {StaticP2MScoreBG := AddStatic(Theme.Sing.StaticP2MScoreBG);
+ TextP2MScore := AddText(Theme.Sing.TextP2MScore);
+ StaticP2MSingBar := AddStatic(Theme.Sing.StaticP2MSingBar);}
+
+ // | P3
+ StaticP3R := AddStatic(Theme.Sing.StaticP3R);
+ TextP3R := AddText(Theme.Sing.TextP3R);
+
+ {StaticP3RScoreBG := AddStatic(Theme.Sing.StaticP3RScoreBG);
+ TextP3RScore := AddText(Theme.Sing.TextP3RScore);
+ StaticP3SingBar := AddStatic(Theme.Sing.StaticP3SingBar);}
+
+ StaticPausePopup := AddStatic(Theme.Sing.PausePopUp);
+ Static[StaticPausePopup].Visible := false; //Pausepopup is not visibile at the beginning
+
+ if ScreenAct = 2 then begin
+ // katze und affe
+
+ end;
+
+ Lyrics := TLyricEngine.Create(80,Skin_LyricsT,640,12,80,Skin_LyricsT+36,640,12);
+
+ if assigned( fCurrentVideoPlaybackEngine ) then
+ fCurrentVideoPlaybackEngine.Init();
+end;
+
+procedure TScreenSing.onShow;
+var
+ P: integer;
+ V1: boolean;
+ V1TwoP: boolean; //added for ps3 skin
+ V1ThreeP: boolean; //added for ps3 skin
+ V2R: boolean;
+ V2M: boolean;
+ V3R: boolean;
+ NR: TRecR; //Line Bonus Mod
+
+ Color: TRGB;
+
+ success: boolean;
+begin
+ inherited;
+
+ Log.LogStatus('Begin', 'onShow');
+ FadeOut := false;
+
+ // reset video playback engine, to play Video Clip...
+ fCurrentVideoPlaybackEngine := VideoPlayback;
+
+ // setup score manager
+ Scores.ClearPlayers; // clear old player values
+ Color.R := 0; Color.G := 0; Color.B := 0; // dummy atm
+
+ // add new players
+ for P := 0 to PlayersPlay-1 do
+ begin
+ Scores.AddPlayer(Tex_ScoreBG[P], Color);
+ end;
+
+ Scores.Init; //Get Positions for Players
+
+
+
+ // prepare players
+ SetLength(Player, PlayersPlay);
+ //Player[0].ScoreTotalInt := 0;
+
+ case PlayersPlay of
+ 1: begin
+ V1 := true;
+ V1TwoP := false;
+ V1ThreeP := false;
+ V2R := false;
+ V2M := false;
+ V3R := false;
+ end;
+ 2: begin
+ V1 := false;
+ V1TwoP := true;
+ V1ThreeP := false;
+ V2R := true;
+ V2M := false;
+ V3R := false;
+ end;
+ 3: begin
+ V1 := false;
+ V1TwoP := false;
+ V1ThreeP := true;
+ V2R := false;
+ V2M := true;
+ V3R := true;
+ end;
+ 4: begin // double screen
+ V1 := false;
+ V1TwoP := true;
+ V1ThreeP := false;
+ V2R := true;
+ V2M := false;
+ V3R := false;
+ end;
+ 6: begin // double screen
+ V1 := false;
+ V1TwoP := false;
+ V1ThreeP := true;
+ V2R := false;
+ V2M := true;
+ V3R := true;
+ end;
+
+ end;
+
+ //This one is shown in 1P mode
+ Static[StaticP1].Visible := V1;
+ Text[TextP1].Visible := V1;
+
+ {Static[StaticP1ScoreBG].Visible := V1;
+ Text[TextP1Score].Visible := V1;}
+
+
+ //This one is shown in 2/4P mode
+ Static[StaticP1TwoP].Visible := V1TwoP;
+ Text[TextP1TwoP].Visible := V1TwoP;
+
+ {Static[StaticP1TwoPScoreBG].Visible := V1TwoP;
+ Text[TextP1TwoPScore].Visible := V1TwoP;}
+
+ Static[StaticP2R].Visible := V2R;
+ Text[TextP2R].Visible := V2R;
+
+ {Static[StaticP2RScoreBG].Visible := V2R;
+ Text[TextP2RScore].Visible := V2R; }
+
+
+ //This one is shown in 3/6P mode
+ Static[StaticP1ThreeP].Visible := V1ThreeP;
+ Text[TextP1ThreeP].Visible := V1ThreeP;
+
+ {Static[StaticP1ThreePScoreBG].Visible := V1ThreeP;
+ Text[TextP1ThreePScore].Visible := V1ThreeP; }
+
+ Static[StaticP2M].Visible := V2M;
+ Text[TextP2M].Visible := V2M;
+
+ {Static[StaticP2MScoreBG].Visible := V2M;
+ Text[TextP2MScore].Visible := V2M; }
+
+ Static[StaticP3R].Visible := V3R;
+ Text[TextP3R].Visible := V3R;
+
+ {Static[StaticP3RScoreBG].Visible := V3R;
+ Text[TextP3RScore].Visible := V3R; }
+
+ // FIXME: sets Path and Filename to ''
+ ResetSingTemp;
+
+ CurrentSong := CatSongs.Song[CatSongs.Selected];
+
+ // FIXME: bad style, put the try-except into LoadSong() and not here
+ try
+ // Check if file is XML
+ if copy(CurrentSong.FileName,length(CurrentSong.FileName)-3,4) = '.xml'
+ then success := CurrentSong.LoadXMLSong()
+ else success := CurrentSong.LoadSong();
+ except
+ success := false;
+ end;
+
+ if (not success) then
+ begin
+ // error loading song -> go back to song screen and show some error message
+ FadeTo(@ScreenSong);
+ // select new song in party mode
+ if ScreenSong.Mode = smPartyMode then
+ ScreenSong.SelectRandomSong();
+ ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG'));
+ // FIXME: do we need this?
+ CurrentSong.Path := CatSongs.Song[CatSongs.Selected].Path;
+ Exit;
+ end;
+
+
+
+ // reset video playback engine, to play video clip...
+
+ Visualization.Init();
+
+ fCurrentVideoPlaybackEngine.Close;
+ fCurrentVideoPlaybackEngine := VideoPlayback;
+
+ // set movie
+ CurrentSong.VideoLoaded := false;
+ fShowVisualization := false;
+ if (CurrentSong.Video <> '') and FileExists(CurrentSong.Path + CurrentSong.Video) then
+ begin
+ // TODO: use VideoGap and start time
+ fCurrentVideoPlaybackEngine.Open( CurrentSong.Path + CurrentSong.Video );
+ fCurrentVideoPlaybackEngine.Position := CurrentSong.VideoGAP + CurrentSong.Start;
+ CurrentSong.VideoLoaded := true;
+ end;
+
+ // set background
+ if (CurrentSong.Background <> '') and (CurrentSong.VideoLoaded = false) then
+ try
+ Tex_Background := Texture.LoadTexture(CurrentSong.Path + CurrentSong.Background);
+ except
+ log.LogError('Background could not be loaded: ' + CurrentSong.Path + CurrentSong.Background);
+ Tex_Background.TexNum := 0;
+ end
+ else
+ Tex_Background.TexNum := 0;
+
+
+
+ // play music (I)
+ AudioInput.CaptureStart;
+ AudioPlayback.Position := CurrentSong.Start;
+// Music.Play;
+
+ // prepare timer (I)
+// CountSkipTimeSet;
+ LineState.CurrentTime := CurrentSong.Start;
+ LineState.TotalTime := AudioPlayback.Length;
+
+ if (CurrentSong.Finish > 0) then
+ LineState.TotalTime := CurrentSong.Finish / 1000;
+ LineState.OldBeat := -1;
+ for P := 0 to High(Player) do
+ ClearScores(P);
+
+ // main text
+ Lyrics.Clear (CurrentSong.BPM[0].BPM, CurrentSong.Resolution);
+
+ // set custom options
+ case Ini.LyricsFont of
+ 0:
+ begin
+ Lyrics.UpperLineSize := 14;
+ Lyrics.LowerLineSize := 14;
+ Lyrics.FontStyle := 0;
+
+ Lyrics.LineColor_en.R := Skin_FontR;
+ Lyrics.LineColor_en.G := Skin_FontG;
+ Lyrics.LineColor_en.B := Skin_FontB;
+ Lyrics.LineColor_en.A := 1;
+
+ Lyrics.LineColor_dis.R := 0.4;
+ Lyrics.LineColor_dis.G := 0.4;
+ Lyrics.LineColor_dis.B := 0.4;
+ Lyrics.LineColor_dis.A := 1;
+
+ Lyrics.LineColor_act.R := 5/256;
+ Lyrics.LineColor_act.G := 163/256;
+ Lyrics.LineColor_act.B := 210/256;
+ Lyrics.LineColor_act.A := 1;
+
+ {
+ LyricSub.FontStyle := 0;
+ LyricMain.Size := 14; // 13
+ LyricSub.Size := 14; // 13
+ LyricMain.ColR := Skin_FontR;
+ LyricMain.ColG := Skin_FontG;
+ LyricMain.ColB := Skin_FontB; //Change für Crazy Joker
+ }
+ {
+ LyricMain.ColSR := Skin_FontHighlightR;
+ LyricMain.ColSG := Skin_FontHighlightG;
+ LyricMain.ColSB := Skin_FontHighlightB;
+ }{
+ LyricMain.ColSR := 5/255; //26
+ LyricMain.ColSG := 163/255; //165
+ LyricMain.ColSB := 210/255; //220
+
+ LyricSub.ColR := 0.4; //0.6
+ LyricSub.ColG := 0.4; //0.6
+ LyricSub.ColB := 0.4; //0.6
+ }
+ end;
+ 1:
+ begin
+ {
+ LyricMain.FontStyle := 2;
+ LyricSub.FontStyle := 2;
+ LyricMain.Size := 14;
+ LyricSub.Size := 14;
+ LyricMain.ColR := 0.75;
+ LyricMain.ColG := 0.75;
+ LyricMain.ColB := 1;
+ LyricMain.ColSR := 0.5;
+ LyricMain.ColSG := 0.5;
+ LyricMain.ColSB := 1;
+ LyricSub.ColR := 0.8;
+ LyricSub.ColG := 0.8;
+ LyricSub.ColB := 0.8;
+ }
+
+ Lyrics.UpperLineSize := 14;
+ Lyrics.LowerLineSize := 14;
+ Lyrics.FontStyle := 2;
+
+ Lyrics.LineColor_en.R := 0.75;
+ Lyrics.LineColor_en.G := 0.75;
+ Lyrics.LineColor_en.B := 1;
+ Lyrics.LineColor_en.A := 1;
+
+ Lyrics.LineColor_dis.R := 0.8;
+ Lyrics.LineColor_dis.G := 0.8;
+ Lyrics.LineColor_dis.B := 0.8;
+ Lyrics.LineColor_dis.A := 1;
+
+ Lyrics.LineColor_act.R := 0.5;
+ Lyrics.LineColor_act.G := 0.5;
+ Lyrics.LineColor_act.B := 1;
+ Lyrics.LineColor_act.A := 1;
+ end;
+ 2:
+ begin
+ Lyrics.UpperLineSize := 12;
+ Lyrics.LowerLineSize := 12;
+ Lyrics.FontStyle := 3;
+
+ Lyrics.LineColor_en.R := 0.75;
+ Lyrics.LineColor_en.G := 0.75;
+ Lyrics.LineColor_en.B := 1;
+ Lyrics.LineColor_en.A := 1;
+
+ Lyrics.LineColor_dis.R := 0.8;
+ Lyrics.LineColor_dis.G := 0.8;
+ Lyrics.LineColor_dis.B := 0.8;
+ Lyrics.LineColor_dis.A := 1;
+
+ Lyrics.LineColor_act.R := 0.5;
+ Lyrics.LineColor_act.G := 0.5;
+ Lyrics.LineColor_act.B := 1;
+ Lyrics.LineColor_act.A := 1;
+ {
+ LyricSub.FontStyle := 3;
+ LyricMain.Size := 12;
+ LyricSub.Size := 12;
+ LyricMain.ColR := 0.75;
+ LyricMain.ColG := 0.75;
+ LyricMain.ColB := 1;
+ LyricMain.ColSR := 0.5;
+ LyricMain.ColSG := 0.5;
+ LyricMain.ColSB := 1;
+ LyricSub.ColR := 0.8;
+ LyricSub.ColG := 0.8;
+ LyricSub.ColB := 0.8;
+ }
+ end;
+ end; // case
+
+ // Add lines to lyrics
+ while (not Lyrics.LineinQueue) and (Lyrics.LineCounter <= High(Lines[0].Line)) do
+ Lyrics.AddLine(@Lines[0].Line[Lyrics.LineCounter]);
+
+ //UpdateLCD; //TODO: maybe LCD Support as Plugin?
+
+ // Deactivate pause
+ Paused := False;
+
+ // Kill all stars not killed yet (GoldenStarsTwinkle Mod)
+ GoldenRec.SentenceChange;
+
+ {//Set Position of Line Bonus - Line Bonus start
+ if (Ini.LineBonus = 1) then //Show Line Bonus at Scores
+ begin
+ Case PlayersPlay of
+ 1: begin
+ Player[0].LineBonus_TargetX := Theme.Sing.StaticP1ScoreBG.x;
+ Player[0].LineBonus_TargetY := Theme.Sing.TextP1Score.Y;
+ Player[0].LineBonus_StartX := Theme.Sing.StaticP1ScoreBG.x;
+ Player[0].LineBonus_StartY := Theme.Sing.TextP1Score.Y + 65;
+ end;
+
+ 2: begin
+ //P1
+ Player[0].LineBonus_TargetX := Theme.Sing.StaticP1TwoPScoreBG.x;
+ Player[0].LineBonus_TargetY := Theme.Sing.TextP1TwoPScore.Y;
+ Player[0].LineBonus_StartX := Theme.Sing.StaticP1TwoPScoreBG.X;
+ Player[0].LineBonus_StartY := Theme.Sing.TextP1TwoPScore.Y + 65;
+
+ //P2
+ Player[1].LineBonus_TargetX := Theme.Sing.StaticP2RScoreBG.X;
+ Player[1].LineBonus_TargetY := Theme.Sing.TextP2RScore.Y;
+ Player[1].LineBonus_StartX := Theme.Sing.StaticP2RScoreBG.X;
+ Player[1].LineBonus_StartY := Theme.Sing.TextP2RScore.Y + 65;
+ end;
+
+ 3: begin
+ //P1
+ Player[0].LineBonus_TargetX := Theme.Sing.StaticP1ThreePScoreBG.x;
+ Player[0].LineBonus_TargetY := Theme.Sing.TextP1ThreePScore.Y;
+ Player[0].LineBonus_StartX := Theme.Sing.StaticP1ThreePScoreBG.x;
+ Player[0].LineBonus_StartY := Theme.Sing.TextP1ThreePScore.Y + 65;
+
+ //P2
+ Player[1].LineBonus_TargetX := Theme.Sing.StaticP2MScoreBG.x;
+ Player[1].LineBonus_TargetY := Theme.Sing.TextP2MScore.Y;
+ Player[1].LineBonus_StartX := Theme.Sing.StaticP2MScoreBG.x;
+ Player[1].LineBonus_StartY := Theme.Sing.TextP2MScore.Y + 65;
+
+ //P3
+ Player[2].LineBonus_TargetX := Theme.Sing.StaticP3RScoreBG.x;
+ Player[2].LineBonus_TargetY := Theme.Sing.TextP3RScore.Y;
+ Player[2].LineBonus_StartX := Theme.Sing.StaticP3RScoreBG.x;
+ Player[2].LineBonus_StartY := Theme.Sing.TextP3RScore.Y + 65;
+ end;
+
+ 4: begin
+ //P1
+ Player[0].LineBonus_TargetX := Theme.Sing.StaticP1TwoPScoreBG.x;
+ Player[0].LineBonus_TargetY := Theme.Sing.TextP1TwoPScore.Y;
+ Player[0].LineBonus_StartX := Theme.Sing.StaticP1TwoPScoreBG.x;
+ Player[0].LineBonus_StartY := Theme.Sing.TextP1TwoPScore.Y + 65;
+
+ //P2
+ Player[1].LineBonus_TargetX := Theme.Sing.StaticP2RScoreBG.x;
+ Player[1].LineBonus_TargetY := Theme.Sing.TextP2RScore.Y;
+ Player[1].LineBonus_StartX := Theme.Sing.StaticP2RScoreBG.x;
+ Player[1].LineBonus_StartY := Theme.Sing.TextP2RScore.Y + 65;
+
+ //P3
+ Player[2].LineBonus_TargetX := Theme.Sing.StaticP1TwoPScoreBG.x;
+ Player[2].LineBonus_TargetY := Theme.Sing.TextP1TwoPScore.Y;
+ Player[2].LineBonus_StartX := Theme.Sing.StaticP1TwoPScoreBG.x;
+ Player[2].LineBonus_StartY := Theme.Sing.TextP1TwoPScore.Y + 65;
+
+ //P4
+ Player[3].LineBonus_TargetX := Theme.Sing.StaticP2RScoreBG.x;
+ Player[3].LineBonus_TargetY := Theme.Sing.TextP2RScore.Y;
+ Player[3].LineBonus_StartX := Theme.Sing.StaticP2RScoreBG.x;
+ Player[3].LineBonus_StartY := Theme.Sing.TextP2RScore.Y + 65;
+ end;
+
+ 6: begin
+ //P1
+ Player[0].LineBonus_TargetX := Theme.Sing.StaticP1ThreePScoreBG.x;
+ Player[0].LineBonus_TargetY := Theme.Sing.TextP1ThreePScore.Y;
+ Player[0].LineBonus_StartX := Theme.Sing.StaticP1ThreePScoreBG.x;
+ Player[0].LineBonus_StartY := Theme.Sing.TextP1ThreePScore.Y + 65;
+
+ //P2
+ Player[1].LineBonus_TargetX := Theme.Sing.StaticP2MScoreBG.x;
+ Player[1].LineBonus_TargetY := Theme.Sing.TextP2MScore.Y;
+ Player[1].LineBonus_StartX := Theme.Sing.StaticP2MScoreBG.x;
+ Player[1].LineBonus_StartY := Theme.Sing.TextP2MScore.Y + 65;
+
+ //P3
+ Player[2].LineBonus_TargetX := Theme.Sing.StaticP3RScoreBG.x;
+ Player[2].LineBonus_TargetY := Theme.Sing.TextP3RScore.Y;
+ Player[2].LineBonus_StartX := Theme.Sing.StaticP3RScoreBG.x;
+ Player[2].LineBonus_StartY := Theme.Sing.TextP3RScore.Y + 65;
+
+ //P4
+ Player[3].LineBonus_TargetX := Theme.Sing.StaticP1ThreePScoreBG.x;
+ Player[3].LineBonus_TargetY := Theme.Sing.TextP1ThreePScore.Y;
+ Player[3].LineBonus_StartX := Theme.Sing.StaticP1ThreePScoreBG.x;
+ Player[3].LineBonus_StartY := Theme.Sing.TextP1ThreePScore.Y + 65;
+
+ //P5
+ Player[4].LineBonus_TargetX := Theme.Sing.StaticP2MScoreBG.x;
+ Player[4].LineBonus_TargetY := Theme.Sing.TextP2MScore.Y;
+ Player[4].LineBonus_StartX := Theme.Sing.StaticP2MScoreBG.x;
+ Player[4].LineBonus_StartY := Theme.Sing.TextP2MScore.Y + 65;
+
+ //P6
+ Player[5].LineBonus_TargetX := Theme.Sing.StaticP3RScoreBG.x;
+ Player[5].LineBonus_TargetY := Theme.Sing.TextP3RScore.Y;
+ Player[5].LineBonus_StartX := Theme.Sing.StaticP3RScoreBG.x;
+ Player[5].LineBonus_StartY := Theme.Sing.TextP3RScore.Y + 65;
+ end;
+ end;
+ end
+ else if (Ini.LineBonus = 2) then //Show Line Bonus at Notes
+ begin
+
+ // positions
+ if Ini.SingWindow = 0 then begin
+ NR.Left := 120;
+ end else begin
+ NR.Left := 20;
+ end;
+ NR.Right := 780;
+
+ NR.Width := NR.Right - NR.Left;
+ NR.WMid := NR.Width / 2;
+ NR.Mid := NR.Left + NR.WMid;
+
+ Case PlayersPlay of
+ 1: begin
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_StartY := Skin_P2_NotesB - 105;
+ end;
+
+ 2: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
+ end;
+
+ 3: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_TargetY := 120 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_StartY := 120 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_TargetY := 245 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_StartY := 245 + 28;
+
+ //P3
+ Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[2].LineBonus_TargetY := 370 - 65 + 28;
+ Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[2].LineBonus_StartY := 370 + 28;
+ end;
+
+ 4: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
+
+ //P3
+ Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[2].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
+ Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[2].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
+
+ //P4
+ Player[3].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[3].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
+ Player[3].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[3].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
+ end;
+
+ 6: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_TargetY := 120 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_StartY := 120 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_TargetY := 245 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_StartY := 245 + 28;
+
+ //P3
+ Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[2].LineBonus_TargetY := 370 - 65 + 28;
+ Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[2].LineBonus_StartY := 370 + 28;
+
+ //P4
+ Player[3].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[3].LineBonus_TargetY := 120 - 65 + 28;
+ Player[3].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[3].LineBonus_StartY := 120 + 28;
+
+ //P5
+ Player[4].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[4].LineBonus_TargetY := 245 - 65 + 28;
+ Player[4].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[4].LineBonus_StartY := 245 + 28;
+
+ //P6
+ Player[5].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[5].LineBonus_TargetY := 370 - 65 + 28;
+ Player[5].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[5].LineBonus_StartY := 370 + 28;
+ end;
+ end;
+ end; }
+
+ // set Position of Line Bonus - Line Bonus end
+ // set number of empty sentences for Line Bonus
+ NumEmptySentences := 0;
+ for P := Low(Lines[0].Line) to High(Lines[0].Line) do
+ if Lines[0].Line[P].TotalNotes = 0 then Inc(NumEmptySentences);
+
+ Log.LogStatus('End', 'onShow');
+end;
+
+procedure TScreenSing.onShowFinish;
+begin
+ // play movie (II)
+
+ if CurrentSong.VideoLoaded then
+ begin
+ try
+ fCurrentVideoPlaybackEngine.GetFrame(LineState.CurrentTime);
+ fCurrentVideoPlaybackEngine.DrawGL(ScreenAct);
+ except on E : Exception do
+ begin
+ //If an error occurs reading video: prevent video from being drawn again and close video
+ CurrentSong.VideoLoaded := False;
+ Log.LogError('Error drawing Video, Video has been disabled for this Song/Session.');
+ Log.LogError('Error Message : '+ E.message );
+ Log.LogError(' In : '+ E.ClassName +' (TScreenSing.onShowFinish)' );
+ Log.LogError('Corrupted File: ' + CurrentSong.Video);
+
+ fCurrentVideoPlaybackEngine.Close;
+ end;
+ end;
+ end;
+
+
+ // play music (II)
+ AudioPlayback.Play;
+
+ // prepare timer (II)
+ CountSkipTimeSet;
+end;
+
+function TScreenSing.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ Flash: real;
+ S: integer;
+ T: integer;
+begin
+ // ScoreBG Mod
+ // TODO: remove this commented out section as we do not need it anymore.
+ // We use colorized png's now. Set player colors does nothing than changing
+ // the colors of the statics which will lead to ugly effects on colorized pngs
+ {
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
+ Static[StaticP1TwoP].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P2Dark');
+
+ LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
+ Static[StaticP1TwoPScoreBG].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
+ end;
+ if ScreenAct = 2 then begin
+ LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
+ Static[StaticP1TwoP].Texture.ColB, 'P3Dark');
+ LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P4Dark');
+
+ LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
+ Static[StaticP1TwoPScoreBG].Texture.ColB, 'P3Dark');
+ LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P4Dark');
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
+ Static[StaticP1ThreeP].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P2Dark');
+ LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
+ Static[StaticP3R].Texture.ColB, 'P3Dark');
+
+ LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
+ Static[StaticP1ThreePScoreBG].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
+ LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
+ Static[StaticP3RScoreBG].Texture.ColB, 'P3Dark');
+ end;
+ if ScreenAct = 2 then begin
+
+ LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
+ Static[StaticP1ThreeP].Texture.ColB, 'P4Dark');
+ LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P5Dark');
+ LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
+ Static[StaticP3R].Texture.ColB, 'P6Dark');
+
+
+ LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
+ Static[StaticP1ThreePScoreBG].Texture.ColB, 'P4Dark');
+ LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P5Dark');
+ LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
+ Static[StaticP3RScoreBG].Texture.ColB, 'P6Dark');
+ end;
+ end;
+ }
+
+ // set player names (for 2 screens and only Singstar skin)
+ if ScreenAct = 1 then begin
+ Text[TextP1].Text := 'P1';
+ Text[TextP1TwoP].Text := 'P1';
+ Text[TextP1ThreeP].Text := 'P1';
+ Text[TextP2R].Text := 'P2';
+ Text[TextP2M].Text := 'P2';
+ Text[TextP3R].Text := 'P3';
+ end;
+
+ if ScreenAct = 2 then begin
+ case PlayersPlay of
+ {
+ 1: begin
+ Text[TextP1].Text := 'P2';
+ end;
+ 2: begin
+ Text[TextP1].Text := 'P3';
+ Text[TextP2R].Text := 'P4';
+ end;
+ 3: begin
+ Text[TextP1].Text := 'P4';
+ Text[TextP2M].Text := 'P5';
+ Text[TextP3R].Text := 'P6';
+ end;
+ }
+ 4: begin
+ Text[TextP1TwoP].Text := 'P3';
+ Text[TextP2R].Text := 'P4';
+ end;
+ 6: begin
+ Text[TextP1ThreeP].Text := 'P4';
+ Text[TextP2M].Text := 'P5';
+ Text[TextP3R].Text := 'P6';
+ end;
+ end; // case
+ end; // if
+
+
+ ////
+ // dual screen, part 1
+ ////////////////////////
+
+ // Note: ScreenX is the offset of the current screen in dual-screen mode so we
+ // will move the statics and texts to the correct screen here.
+ // FIXME: clean up this weird stuff. Commenting this stuff out, nothing
+ // was missing on screen w/ 6 players - so do we even need this stuff?
+ Static[StaticP1].Texture.X := Static[StaticP1].Texture.X + 10*ScreenX;
+
+ Text[TextP1].X := Text[TextP1].X + 10*ScreenX;
+
+ {Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X + 10*ScreenX;
+ Text[TextP1Score].X := Text[TextP1Score].X + 10*ScreenX;}
+
+
+ Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X + 10*ScreenX;
+
+ Text[TextP2R].X := Text[TextP2R].X + 10*ScreenX;
+
+ {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X + 10*ScreenX;
+ Text[TextP2RScore].X := Text[TextP2RScore].X + 10*ScreenX;}
+
+ // end of weird stuff
+
+ Static[1].Texture.X := Static[1].Texture.X + 10*ScreenX;
+
+ for T := 0 to 1 do
+ Text[T].X := Text[T].X + 10*ScreenX;
+
+ // update static menu with time ...
+ Min := Round(LineState.CurrentTime) div 60;
+ Sec := Round(LineState.CurrentTime) mod 60;
+ Text[TextTimeText].Text := '';
+ if Min < 10 then Text[TextTimeText].Text := '0';
+ Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Min) + ':';
+ if Sec < 10 then Text[TextTimeText].Text := Text[TextTimeText].Text + '0';
+ Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Sec);
+
+ {// .. and scores
+ if PlayersPlay = 1 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1Score].Text := Tekst;
+ end;
+
+ if PlayersPlay = 2 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1TwoPScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2RScore].Text := Tekst;
+ end;
+
+ if PlayersPlay = 3 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1ThreePScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2MScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[2].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP3RScore].Text := Tekst;
+ end;
+
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1TwoPScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2RScore].Text := Tekst;
+ end;
+ if ScreenAct = 2 then begin
+ Tekst := IntToStr(Player[2].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1TwoPScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[3].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2RScore].Text := Tekst;
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1ThreePScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2MScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[2].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP3RScore].Text := Tekst;
+ end;
+ if ScreenAct = 2 then begin
+ Tekst := IntToStr(Player[3].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1ThreePScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[4].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2MScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[5].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP3RScore].Text := Tekst;
+ end;
+ end; }
+
+ // draw static menu (BG)
+ // Note: there is no menu and the animated background brakes the video playback
+ //DrawBG;
+
+ // Draw Background
+ SingDrawBackground;
+
+ // update and draw movie
+ if (ShowFinish and
+ (CurrentSong.VideoLoaded or fShowVisualization)) then
+ begin
+ //try
+ // TODO: find a way to determine, when a new frame is needed
+ // TODO: same for the need to skip frames
+ if assigned( fCurrentVideoPlaybackEngine ) then
+ begin
+ fCurrentVideoPlaybackEngine.GetFrame(LineState.CurrentTime);
+ fCurrentVideoPlaybackEngine.DrawGL(ScreenAct);
+ end;
+ (*
+ except
+ on E : Exception do
+ begin
+ //If an Error occurs drawing: prevent Video from being Drawn again and Close Video
+ CurrentSong.VideoLoaded := False;
+ log.LogError('Error drawing Video, Video has been disabled for this Song/Session.');
+ Log.LogError('Error Message : '+ E.message );
+ Log.LogError(' In : '+ E.ClassName +' (TScreenSing.Draw)' );
+
+ Log.LogError('Corrupted File: ' + CurrentSong.Video);
+ fCurrentVideoPlaybackEngine.Close;
+ end;
+ end;
+ *)
+ end;
+
+ // draw static menu (FG)
+ DrawFG;
+
+ // check for music finish
+ //Log.LogError('Check for music finish: ' + BoolToStr(Music.Finished) + ' ' + FloatToStr(LineState.CurrentTime*1000) + ' ' + IntToStr(CurrentSong.Finish));
+ if ShowFinish then
+ begin
+ if (not AudioPlayback.Finished) and
+ ((CurrentSong.Finish = 0) or (LineState.CurrentTime*1000 <= CurrentSong.Finish)) then
+ begin
+ // analyze song if not paused
+ if (not Paused) then
+ Sing(Self);
+ end
+ else
+ begin
+ if (not FadeOut) then
+ begin
+ Finish;
+ FadeOut := true;
+ FadeTo(@ScreenScore);
+ end;
+ end;
+ end;
+
+ // always draw custom items
+ SingDraw;
+
+ //GoldenNoteStarsTwinkle
+ GoldenRec.SpawnRec;
+
+ //Draw Scores
+ Scores.Draw;
+
+ ////
+ // dual screen, part 2
+ ////////////////////////
+
+ // Note: ScreenX is the offset of the current screen in dual-screen mode so we
+ // will move the statics and texts to the correct screen here.
+ // FIXME: clean up this weird stuff
+
+ Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10*ScreenX;
+ Text[TextP1].X := Text[TextP1].X - 10*ScreenX;
+
+ {Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X - 10*ScreenX;
+ Text[TextP1Score].X := Text[TextP1Score].X - 10*ScreenX;}
+
+
+ Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X - 10*ScreenX;
+ Text[TextP2R].X := Text[TextP2R].X - 10*ScreenX;
+
+ {Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X - 10*ScreenX;
+ Text[TextP2RScore].X := Text[TextP2RScore].X - 10*ScreenX;}
+
+ //end of weird
+
+ Static[1].Texture.X := Static[1].Texture.X - 10*ScreenX;
+
+ for T := 0 to 1 do
+ Text[T].X := Text[T].X - 10*ScreenX;
+
+ // Draw Pausepopup
+ // FIXME: this is a workaround that the Static is drawn over the Lyrics, Lines, Scores and Effects
+ // maybe someone could find a better solution
+ if Paused then
+ begin
+ Static[StaticPausePopup].Visible := true;
+ Static[StaticPausePopup].Draw;
+ Static[StaticPausePopup].Visible := false;
+ end;
+
+end;
+
+procedure TScreenSing.Finish;
+begin
+ AudioInput.CaptureStop;
+ AudioPlayback.Stop;
+
+ if (Ini.SavePlayback = 1) then begin
+ Log.BenchmarkStart(0);
+ Log.LogVoice(0);
+ Log.LogVoice(1);
+ Log.LogVoice(2);
+ Log.BenchmarkEnd(0);
+ Log.LogBenchmark('Creating files', 0);
+ end;
+
+ if CurrentSong.VideoLoaded then
+ begin
+ fCurrentVideoPlaybackEngine.Close;
+ CurrentSong.VideoLoaded := false; // to prevent drawing closed video
+ end;
+
+ SetFontItalic (False);
+end;
+
+(*
+procedure TScreenSing.UpdateLCD; //TODO: maybe LCD Support as Plugin?
+var
+ T: string;
+begin
+ //Todo: Lyrics
+{ LCD.HideCursor;
+ LCD.Clear;
+
+ T := LyricMain.Text;
+ if Copy(T, Length(T), 1) <> ' ' then T := T + ' ';
+ LCD.AddTextBR(T);
+
+ T := LyricSub.Text;
+ if Copy(T, Length(T), 1) <> ' ' then T := T + ' ';
+ LCD.AddTextBR(T);}
+end;
+*)
+
+procedure TScreenSing.OnSentenceEnd(SentenceIndex: Cardinal);
+var
+ PlayerIndex: Integer;
+ CurrentPlayer: PPLayer;
+ CurrentScore: Real;
+ Line: PLine;
+ LinePerfection: Real; // perfection of singing performance on the current line
+ Rating: integer;
+ LineScore: Real;
+ LineBonus: Real;
+ MaxSongScore: integer; // max. points for the song (without line bonus)
+ MaxLineScore: Real; // max. points for the current line
+const
+ // TODO: move this to a better place
+ MAX_LINE_RATING = 8; // max. rating for singing performance
+begin
+ Line := @Lines[0].Line[SentenceIndex];
+
+ // check for empty sentence
+ if (Line.TotalNotes <= 0) then
+ Exit;
+
+ // set max song score
+ if (Ini.LineBonus = 0) then
+ MaxSongScore := MAX_SONG_SCORE
+ else
+ MaxSongScore := MAX_SONG_SCORE - MAX_SONG_LINE_BONUS;
+
+ // Note: ScoreValue is the sum of all note values of the song
+ MaxLineScore := MaxSongScore * (Line.TotalNotes / Lines[0].ScoreValue);
+
+ for PlayerIndex := 0 to High(Player) do
+ begin
+ CurrentPlayer := @Player[PlayerIndex];
+ CurrentScore := CurrentPlayer.Score + CurrentPlayer.ScoreGolden;
+
+ // Line Bonus
+
+ // points for this line
+ LineScore := CurrentScore - CurrentPlayer.ScoreLast;
+
+ // determine LinePerfection
+ // Note: the "+2" extra points are a little bonus so the player does not
+ // have to be that perfect to reach the bonus steps.
+ LinePerfection := (LineScore + 2) / MaxLineScore;
+
+ // clamp LinePerfection to range [0..1]
+ if (LinePerfection < 0) then
+ LinePerfection := 0
+ else if (LinePerfection > 1) then
+ LinePerfection := 1;
+
+ // add line-bonus if enabled
+ if (Ini.LineBonus > 0) then
+ begin
+ // line-bonus points (same for each line, no matter how long the line is)
+ LineBonus := MAX_SONG_LINE_BONUS /
+ (Length(Lines[0].Line) - NumEmptySentences);
+ // apply line-bonus
+ CurrentPlayer.ScoreLine := CurrentPlayer.ScoreLine +
+ LineBonus * LinePerfection;
+ CurrentPlayer.ScoreLineInt := Round(CurrentPlayer.ScoreLine / 10) * 10;
+ // update total score
+ CurrentPlayer.ScoreTotalInt := CurrentPlayer.ScoreInt +
+ CurrentPlayer.ScoreGoldenInt +
+ CurrentPlayer.ScoreLineInt;
+
+ // spawn rating pop-up
+ Rating := Round(LinePerfection * MAX_LINE_RATING);
+ Scores.SpawnPopUp(PlayerIndex, Rating, CurrentPlayer.ScoreTotalInt);
+ end;
+
+ // PerfectLineTwinkle (effect), Part 1
+ If (Ini.EffectSing = 1) then
+ CurrentPlayer.LastSentencePerfect := (LinePerfection >= 1);
+
+ // refresh last score
+ CurrentPlayer.ScoreLast := CurrentScore;
+ end;
+
+ // PerfectLineTwinkle (effect), Part 2
+ if (Ini.EffectSing = 1) then
+ GoldenRec.SpawnPerfectLineTwinkle;
+end;
+
+//Called on Sentence Change S= New Current Sentence
+procedure TScreenSing.OnSentenceChange(SentenceIndex: Cardinal);
+begin
+ //GoldenStarsTwinkle Mod
+ GoldenRec.SentenceChange;
+ if (Lyrics.LineCounter <= High(Lines[0].Line)) then
+ begin
+ Lyrics.AddLine(@Lines[0].Line[Lyrics.LineCounter]);
+ end
+ else
+ Lyrics.AddLine(nil);
+
+ // addline uses display memory
+ // calling draw makes sure, there's the singscreen in it, when the next
+ // swap between onscreen and offscreen buffers is done
+ // (this eliminates the onSentenceChange flickering)
+ // note: maybe it would be better to make sure, a display redraw is done
+ // right after the sentence change (before buffer swap) or make sure
+ // onsentencechange is only called right before calling Display.Draw
+ // (or whatever it was called)
+ Draw;
+
+ //GoldenStarsTwinkle Mod End
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenSingModi.pas b/Game/Code/Screens/UScreenSingModi.pas
index f010ec31..7606abe6 100644
--- a/Game/Code/Screens/UScreenSingModi.pas
+++ b/Game/Code/Screens/UScreenSingModi.pas
@@ -76,11 +76,11 @@ type
end;
type
- TCustomSoundEntry = record
- Filename : String;
- Stream : TAudioPlaybackStream;
- end;
-
+ TCustomSoundEntry = record
+ Filename : String;
+ Stream : TAudioPlaybackStream;
+ end;
+
var
//Custom Sounds
CustomSounds: array of TCustomSoundEntry;
diff --git a/Game/Code/Screens/UScreenSong.pas b/Game/Code/Screens/UScreenSong.pas
index 1653e310..5dc3c7ef 100644
--- a/Game/Code/Screens/UScreenSong.pas
+++ b/Game/Code/Screens/UScreenSong.pas
@@ -1,2130 +1,2130 @@
-unit UScreenSong;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-
-uses
- UMenu,
- SDL,
- UMusic,
- UFiles,
- UTime,
- UDisplay,
- USongs,
- SysUtils,
- UCommon,
- ULog,
- UThemes,
- UTexture,
- ULanguage,
- //ULCD, //TODO: maybe LCD Support as Plugin?
- //ULight, //TODO: maybe Light Support as Plugin?
- USong,
- UIni;
-
-type
- TScreenSong = class(TMenu)
- private
- EqualizerData: TFFTData; // moved here to avoid stack overflows
- EqualizerBands: array of Byte;
- EqualizerTime: Cardinal;
-
- procedure StartMusicPreview(Song: TSong);
- public
- TextArtist: integer;
- TextTitle: integer;
- TextNumber: integer;
-
- //Video Icon Mod
- VideoIcon: Cardinal;
-
- TextCat: integer;
- StaticCat: integer;
-
- SongCurrent: real;
- SongTarget: real;
-
- HighSpeed: boolean;
- CoverFull: boolean;
- CoverTime: real;
- MusicStartTime: cardinal;
-
- CoverX: integer;
- CoverY: integer;
- CoverW: integer;
- is_jump: boolean; // Jump to Song Mod
- is_jump_title:boolean; //Jump to SOng MOd-YTrue if search for Title
-
- //Party Mod
- Mode: TSingMode;
-
- //party Statics (Joker)
- StaticTeam1Joker1: Cardinal;
- StaticTeam1Joker2: Cardinal;
- StaticTeam1Joker3: Cardinal;
- StaticTeam1Joker4: Cardinal;
- StaticTeam1Joker5: Cardinal;
-
- StaticTeam2Joker1: Cardinal;
- StaticTeam2Joker2: Cardinal;
- StaticTeam2Joker3: Cardinal;
- StaticTeam2Joker4: Cardinal;
- StaticTeam2Joker5: Cardinal;
-
- StaticTeam3Joker1: Cardinal;
- StaticTeam3Joker2: Cardinal;
- StaticTeam3Joker3: Cardinal;
- StaticTeam3Joker4: Cardinal;
- StaticTeam3Joker5: Cardinal;
-
- StaticParty: array of Cardinal;
- TextParty: array of Cardinal;
- StaticNonParty: array of Cardinal;
- TextNonParty: array of Cardinal;
-
-
- constructor Create; override;
- procedure SetScroll;
- procedure SetScroll1;
- procedure SetScroll2;
- procedure SetScroll3;
- procedure SetScroll4;
- procedure SetScroll5;
- procedure SetScroll6;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- function Draw: boolean; override;
- procedure GenerateThumbnails();
- procedure onShow; override;
- procedure onHide; override;
- procedure SelectNext;
- procedure SelectPrev;
- //procedure UpdateLCD; //TODO: maybe LCD Support as Plugin?
- procedure SkipTo(Target: Cardinal);
- procedure FixSelected; //Show Wrong Song when Tabs on Fix
- procedure FixSelected2; //Show Wrong Song when Tabs on Fix
- procedure ShowCatTL(Cat: Integer);// Show Cat in Top left
- procedure ShowCatTLCustom(Caption: String);// Show Custom Text in Top left
- procedure HideCatTL;// Show Cat in Tob left
- procedure Refresh; //Refresh Song Sorting
- procedure DrawEqualizer;
- procedure ChangeMusic;
- //Party Mode
- procedure SelectRandomSong;
- procedure SetJoker;
- procedure SetStatics;
- //procedures for Menu
- procedure StartSong;
- procedure OpenEditor;
- procedure DoJoker(Team: Byte);
- procedure SelectPlayers;
-
- procedure UnLoadDetailedCover;
-
- //Extensions
- procedure DrawExtensions;
- end;
-
-implementation
-
-uses
- UGraphic,
- UMain,
- UCovers,
- math,
- gl,
- USkins,
- UDLLManager,
- UParty,
- UPlaylist,
- UScreenSongMenu;
-
-// ***** Public methods ****** //
-
-//Show Wrong Song when Tabs on Fix
-procedure TScreenSong.FixSelected;
-var I, I2: Integer;
-begin
- if CatSongs.VisibleSongs > 0 then
- begin
- I2:= 0;
- for I := low(CatSongs.Song) to High(Catsongs.Song) do
- begin
- if CatSongs.Song[I].Visible then
- inc(I2);
-
- if I = Interaction - 1 then
- break;
- end;
-
- SongCurrent := I2;
- SongTarget := I2;
- end;
-end;
-
-procedure TScreenSong.FixSelected2;
-var I, I2: Integer;
-begin
- if CatSongs.VisibleSongs > 0 then
- begin
- I2:= 0;
- for I := low(CatSongs.Song) to High(Catsongs.Song) do
- begin
- if CatSongs.Song[I].Visible then
- inc(I2);
-
- if I = Interaction - 1 then
- break;
- end;
-
- SongTarget := I2;
- end;
-end;
-//Show Wrong Song when Tabs on Fix End
-
-procedure TScreenSong.ShowCatTLCustom(Caption: String);// Show Custom Text in Top left
-begin
- Text[TextCat].Text := Caption;
- Text[TextCat].Visible := true;
- Static[StaticCat].Visible := False;
-end;
-
-//Show Cat in Top Left Mod
-procedure TScreenSong.ShowCatTL(Cat: Integer);
-begin
- //Change
- Text[TextCat].Text := CatSongs.Song[Cat].Artist;
- //showmessage(CatSongs.Song[Cat].Path + CatSongs.Song[Cat].Cover);
- //Static[StaticCat].Texture := Texture.GetTexture(Button[Cat].Texture.Name, TEXTURE_TYPE_PLAIN, true);
-
- Static[StaticCat].Texture := Texture.GetTexture(Button[Cat].Texture.Name, TEXTURE_TYPE_PLAIN, true);
- //Texture.GetTexture(Button[Cat].Texture.Name, TEXTURE_TYPE_PLAIN, false);
-
- //Show
- Text[TextCat].Visible := true;
- Static[StaticCat].Visible := True;
-end;
-
-procedure TScreenSong.HideCatTL;
-begin
- //Hide
- //Text[TextCat].Visible := false;
- Static[StaticCat].Visible := false;
- //New -> Show Text specified in Theme
- Text[TextCat].Visible := True;
- Text[TextCat].Text := Theme.Song.TextCat.Text;
-end;
-//Show Cat in Top Left Mod End
-
-
-// Method for input parsing. If False is returned, GetNextWindow
-// should be checked to know the next window to load;
-function TScreenSong.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-var
- I: integer;
- I2: integer;
- SDL_ModState: Word;
- Letter: WideChar;
-begin
- Result := true;
-
- //Song Screen Extensions (Jumpto + Menu)
- if (ScreenSongMenu.Visible) then
- begin
- Result := ScreenSongMenu.ParseInput(PressedKey, CharCode, PressedDown);
- Exit;
- end
- else if (ScreenSongJumpto.Visible) then
- begin
- Result := ScreenSongJumpto.ParseInput(PressedKey, CharCode, PressedDown);
- Exit;
- end;
-
- if (PressedDown) then
- begin // Key Down
-
- SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
- + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT);
-
- //Jump to Artist/Titel
- if ((SDL_ModState and KMOD_LALT <> 0) and (Mode = smNormal)) then
- begin
- if (WideCharUpperCase(CharCode)[1] in ([WideChar('A')..WideChar('Z')]) ) then
- begin
- Letter := WideCharUpperCase(CharCode)[1];
- I2 := Length(CatSongs.Song);
-
- //Jump To Titel
- if (SDL_ModState = (KMOD_LALT or KMOD_LSHIFT)) then
- begin
- for I := 1 to high(CatSongs.Song) do
- begin
- if (CatSongs.Song[(I + Interaction) mod I2].Visible) and
- (Length(CatSongs.Song[(I + Interaction) mod I2].Title)>0) and
- (WideStringUpperCase(CatSongs.Song[(I + Interaction) mod I2].Title)[1] = Letter) then
- begin
- SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2));
-
- AudioPlayback.PlaySound(SoundLib.Change);
-
- ChangeMusic;
- SetScroll4;
- //UpdateLCD; //TODO: maybe LCD Support as Plugin?
- //Break and Exit
- Exit;
- end;
- end;
- end
- //Jump to Artist
- else if (SDL_ModState = KMOD_LALT) then
- begin
- for I := 1 to high(CatSongs.Song) do
- begin
- if (CatSongs.Song[(I + Interaction) mod I2].Visible) and
- (Length(CatSongs.Song[(I + Interaction) mod I2].Artist)>0) and
- (WideStringUpperCase(CatSongs.Song[(I + Interaction) mod I2].Artist)[1] = Letter) then
- begin
- SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2));
-
- AudioPlayback.PlaySound(SoundLib.Change);
-
- ChangeMusic;
- SetScroll4;
- //UpdateLCD; //TODO: maybe LCD Support as Plugin?
-
- //Break and Exit
- Exit;
- end;
- end;
- end;
- end;
-
- Exit;
- end;
-
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
-
- 'M': //Show SongMenu
- begin
- if (Songs.SongList.Count > 0) then
- begin
- if (Mode = smNormal) then
- begin
- if (not CatSongs.Song[Interaction].Main) then // clicked on Song
- begin
- if CatSongs.CatNumShow = -3 then
- ScreenSongMenu.MenuShow(SM_Playlist)
- else
- ScreenSongMenu.MenuShow(SM_Main);
- end
- else
- begin
- ScreenSongMenu.MenuShow(SM_Playlist_Load);
- end;
- end //Party Mode -> Show Party Menu
- else
- begin
- ScreenSongMenu.MenuShow(SM_Party_Main);
- end;
- end;
- Exit;
- end;
-
- 'P': //Show Playlist Menu
- begin
- if (Songs.SongList.Count > 0) and (Mode = smNormal) then
- begin
- ScreenSongMenu.MenuShow(SM_Playlist_Load);
- end;
- Exit;
- end;
-
- 'J': //Show Jumpto Menu
- begin
- if (Songs.SongList.Count > 0) and (Mode = smNormal) then
- begin
- ScreenSongJumpto.Visible := True;
- end;
- Exit;
- end;
-
- 'E':
- begin
- OpenEditor;
- Exit;
- end;
-
- 'R':
- begin
- if (Songs.SongList.Count > 0) and (Mode = smNormal) then
- begin
- if (SDL_ModState = KMOD_LSHIFT) and (Ini.Tabs_at_startup = 1) then //Random Category
- begin
- I2 := 0; //Count Cats
- for I:= low(CatSongs.Song) to high (CatSongs.Song) do
- begin
- if CatSongs.Song[I].Main then
- Inc(I2);
- end;
-
- I2 := Random (I2)+1; //Zufall
-
- //Find Cat:
- for I:= low(CatSongs.Song) to high (CatSongs.Song) do
- begin
- if CatSongs.Song[I].Main then
- Dec(I2);
- if (I2<=0) then
- begin
- //Show Cat in Top Left Mod
- ShowCatTL (I);
-
- Interaction := I;
-
- CatSongs.ShowCategoryList;
- CatSongs.ClickCategoryButton(I);
- SelectNext;
- FixSelected;
- break;
- end;
- end;
- end
- else if (SDL_ModState = KMOD_LCTRL) and (Ini.Tabs_at_startup = 1) then //random in All Categorys
- begin
- repeat
- I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1;
- until CatSongs.Song[I2].Main = false;
-
- //Search Cat
- for I := I2 downto low(CatSongs.Song) do
- begin
- if CatSongs.Song[I].Main then
- break;
- end;
-
- //In I is now the categorie in I2 the song
-
- //Choose Cat
- CatSongs.ShowCategoryList;
-
- //Show Cat in Top Left Mod
- ShowCatTL (I);
-
- CatSongs.ClickCategoryButton(I);
- SelectNext;
-
- //Fix: Not Existing Song selected:
- //if (I+1=I2) then Inc(I2);
-
- //Choose Song
- SkipTo(I2-I);
- end
- else //Random in one Category
- begin
- SkipTo(Random(CatSongs.VisibleSongs));
- end;
- AudioPlayback.PlaySound(SoundLib.Change);
-
- ChangeMusic;
- SetScroll4;
- //UpdateLCD; //TODO: maybe LCD Support as Plugin?
- end;
- Exit;
- end;
- end; // normal keys
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- if (Mode = smNormal) then
- begin
- //On Escape goto Cat-List Hack
- if (Ini.Tabs_at_startup = 1) and (CatSongs.CatNumShow <> -1) then
- begin
- //Find Category
- I := Interaction;
- while not catsongs.Song[I].Main do
- begin
- Dec (I);
- if (I < low(catsongs.Song)) then
- break;
- end;
- if (I<= 1) then
- Interaction := high(catsongs.Song)
- else
- Interaction := I - 1;
-
- //Stop Music
- AudioPlayback.Stop;
-
- CatSongs.ShowCategoryList;
-
- //Show Cat in Top Left Mod
- HideCatTL;
-
-
- //Show Wrong Song when Tabs on Fix
- SelectNext;
- FixSelected;
- //SelectPrev;
- //CatSongs.Song[0].Visible := False;
- end
- else
- begin
- //On Escape goto Cat-List Hack End
- //Tabs off and in Search or Playlist -> Go back to Song view
- if (CatSongs.CatNumShow < -1) then
- begin
- //Atm: Set Empty Filter
- CatSongs.SetFilter('', 0);
-
- //Show Cat in Top Left Mod
- HideCatTL;
- Interaction := 0;
-
- //Show Wrong Song when Tabs on Fix
- SelectNext;
- FixSelected;
-
- ChangeMusic;
- end
- else
- begin
- AudioPlayback.Stop;
- AudioPlayback.PlaySound(SoundLib.Back);
-
- FadeTo(@ScreenMain);
- end;
-
- end;
- end
- //When in party Mode then Ask before Close
- else if (Mode = smPartyMode) then
- begin
- AudioPlayback.PlaySound(SoundLib.Back);
- CheckFadeTo(@ScreenMain,'MSG_END_PARTY');
- end;
- end;
- SDLK_RETURN:
- begin
- if Songs.SongList.Count > 0 then
- begin
- {$IFDEF UseSerialPort}
- // PortWriteB($378, 0);
- {$ENDIF}
- if CatSongs.Song[Interaction].Main then
- begin // clicked on Category Button
- //Show Cat in Top Left Mod
- ShowCatTL (Interaction);
-
- //I := CatSongs.VisibleIndex(Interaction);
- CatSongs.ClickCategoryButton(Interaction);
- {I2 := CatSongs.VisibleIndex(Interaction);
- SongCurrent := SongCurrent - I + I2;
- SongTarget := SongTarget - I + I2; }
-
- // SetScroll4;
-
- //Show Wrong Song when Tabs on Fix
- SelectNext;
- FixSelected;
-
- //Play Music:
- ChangeMusic;
- end
- else
- begin // clicked on song
- if (Mode = smNormal) then //Normal Mode -> Start Song
- begin
- //Do the Action that is specified in Ini
- case Ini.OnSongClick of
- 0: StartSong;
- 1: SelectPlayers;
- 2:begin
- if (CatSongs.CatNumShow = -3) then
- ScreenSongMenu.MenuShow(SM_Playlist)
- else
- ScreenSongMenu.MenuShow(SM_Main);
- end;
- end;
- end
- else if (Mode = smPartyMode) then //PartyMode -> Show Menu
- begin
- if (Ini.PartyPopup = 1) then
- ScreenSongMenu.MenuShow(SM_Party_Main)
- else
- ScreenSong.StartSong;
- end;
- end;
- end;
- end;
-
- SDLK_DOWN:
- begin
- if (Mode = smNormal) then
- begin
- //Only Change Cat when not in Playlist or Search Mode
- if (CatSongs.CatNumShow > -2) then
- begin
- //Cat Change Hack
- if Ini.Tabs_at_startup = 1 then
- begin
- I := Interaction;
- if I <= 0 then I := 1;
-
- while not catsongs.Song[I].Main do
- begin
- Inc (I);
- if (I > high(catsongs.Song)) then
- I := low(catsongs.Song);
- end;
-
- Interaction := I;
-
- //Show Cat in Top Left Mod
- ShowCatTL (Interaction);
-
- CatSongs.ClickCategoryButton(Interaction);
- SelectNext;
- FixSelected;
-
- //Play Music:
- AudioPlayback.PlaySound(SoundLib.Change);
- ChangeMusic;
-
- end;
-
- //
- //Cat Change Hack End}
- end;
- end;
- end;
- SDLK_UP:
- begin
- if (Mode = smNormal) then
- begin
- //Only Change Cat when not in Playlist or Search Mode
- if (CatSongs.CatNumShow > -2) then
- begin
- //Cat Change Hack
- if Ini.Tabs_at_startup = 1 then
- begin
- I := Interaction;
- I2 := 0;
- if I <= 0 then I := 1;
-
- while not catsongs.Song[I].Main or (I2 = 0) do
- begin
- if catsongs.Song[I].Main then
- Inc(I2);
- Dec (I);
- if (I < low(catsongs.Song)) then
- I := high(catsongs.Song);
- end;
-
- Interaction := I;
-
- //Show Cat in Top Left Mod
- ShowCatTL (I);
-
- CatSongs.ClickCategoryButton(I);
- SelectNext;
- FixSelected;
-
- //Play Music:
- AudioPlayback.PlaySound(SoundLib.Change);
- ChangeMusic;
- end;
- end;
- //Cat Change Hack End}
- end;
- end;
-
- SDLK_RIGHT:
- begin
- if (Songs.SongList.Count > 0) and (Mode = smNormal) then
- begin
- AudioPlayback.PlaySound(SoundLib.Change);
- SelectNext;
- //InteractNext;
- //SongTarget := Interaction;
- ChangeMusic;
- SetScroll4;
- //UpdateLCD; //TODO: maybe LCD Support as Plugin?
- //Light.LightOne(1, 200); //TODO: maybe Light Support as Plugin?
- end;
- end;
-
- SDLK_LEFT:
- begin
- if (Songs.SongList.Count > 0)and (Mode = smNormal) then
- begin
- AudioPlayback.PlaySound(SoundLib.Change);
- SelectPrev;
- ChangeMusic;
- SetScroll4;
- //UpdateLCD; //TODO: maybe LCD Support as Plugin?
- //Light.LightOne(0, 200); //TODO: maybe Light Support as Plugin?
- end;
- end;
-
- SDLK_1:
- begin //Joker // to-do : Party
- {if (Mode = smPartyMode) and (PartySession.Teams.NumTeams >= 1) and (PartySession.Teams.Teaminfo[0].Joker > 0) then
- begin
- //Use Joker
- Dec(PartySession.Teams.Teaminfo[0].Joker);
- SelectRandomSong;
- SetJoker;
- end; }
- end;
-
- SDLK_2:
- begin //Joker
- {if (Mode = smPartyMode) and (PartySession.Teams.NumTeams >= 2) and (PartySession.Teams.Teaminfo[1].Joker > 0) then
- begin
- //Use Joker
- Dec(PartySession.Teams.Teaminfo[1].Joker);
- SelectRandomSong;
- SetJoker;
- end; }
- end;
-
- SDLK_3:
- begin //Joker
- {if (Mode = smPartyMode) and (PartySession.Teams.NumTeams >= 3) and (PartySession.Teams.Teaminfo[2].Joker > 0) then
- begin
- //Use Joker
- Dec(PartySession.Teams.Teaminfo[2].Joker);
- SelectRandomSong;
- SetJoker;
- end; }
- end;
- end;
- end;
-end;
-
-constructor TScreenSong.Create;
-var
- i: integer;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.Song);
-
- TextArtist := AddText(Theme.Song.TextArtist);
- TextTitle := AddText(Theme.Song.TextTitle);
- TextNumber := AddText(Theme.Song.TextNumber);
-
- //Show Cat in Top Left mod
- TextCat := AddText(Theme.Song.TextCat);
- StaticCat := AddStatic(Theme.Song.StaticCat);
-
- //Show Video Icon Mod
- VideoIcon := AddStatic(Theme.Song.VideoIcon);
-
- //Party Mode
- StaticTeam1Joker1 := AddStatic(Theme.Song.StaticTeam1Joker1);
- StaticTeam1Joker2 := AddStatic(Theme.Song.StaticTeam1Joker2);
- StaticTeam1Joker3 := AddStatic(Theme.Song.StaticTeam1Joker3);
- StaticTeam1Joker4 := AddStatic(Theme.Song.StaticTeam1Joker4);
- StaticTeam1Joker5 := AddStatic(Theme.Song.StaticTeam1Joker5);
-
- StaticTeam2Joker1 := AddStatic(Theme.Song.StaticTeam2Joker1);
- StaticTeam2Joker2 := AddStatic(Theme.Song.StaticTeam2Joker2);
- StaticTeam2Joker3 := AddStatic(Theme.Song.StaticTeam2Joker3);
- StaticTeam2Joker4 := AddStatic(Theme.Song.StaticTeam2Joker4);
- StaticTeam2Joker5 := AddStatic(Theme.Song.StaticTeam2Joker5);
-
- StaticTeam3Joker1 := AddStatic(Theme.Song.StaticTeam3Joker1);
- StaticTeam3Joker2 := AddStatic(Theme.Song.StaticTeam3Joker2);
- StaticTeam3Joker3 := AddStatic(Theme.Song.StaticTeam3Joker3);
- StaticTeam3Joker4 := AddStatic(Theme.Song.StaticTeam3Joker4);
- StaticTeam3Joker5 := AddStatic(Theme.Song.StaticTeam3Joker5);
-
- //Load Party or NonParty specific Statics and Texts
- SetLength(StaticParty, Length(Theme.Song.StaticParty));
- for i := 0 to High(Theme.Song.StaticParty) do
- StaticParty[i] := AddStatic(Theme.Song.StaticParty[i]);
-
- SetLength(TextParty, Length(Theme.Song.TextParty));
- for i := 0 to High(Theme.Song.TextParty) do
- TextParty[i] := AddText(Theme.Song.TextParty[i]);
-
- SetLength(StaticNonParty, Length(Theme.Song.StaticNonParty));
- for i := 0 to High(Theme.Song.StaticNonParty) do
- StaticNonParty[i] := AddStatic(Theme.Song.StaticNonParty[i]);
-
- SetLength(TextNonParty, Length(Theme.Song.TextNonParty));
- for i := 0 to High(Theme.Song.TextNonParty) do
- TextNonParty[i] := AddText(Theme.Song.TextNonParty[i]);
-
- // Song List
- //Songs.LoadSongList; // moved to the UltraStar unit
- CatSongs.Refresh;
-
- GenerateThumbnails();
-
-
- // Randomize Patch
- Randomize;
- //Equalizer
- SetLength(EqualizerBands, Theme.Song.Equalizer.Bands);
- //ClearArray
- For I := low(EqualizerBands) to high(EqualizerBands) do
- EqualizerBands[I] := 3;
-
- if (Length(CatSongs.Song) > 0) then
- Interaction := 0;
-end;
-
-procedure TScreenSong.GenerateThumbnails();
-var
- I: Integer;
- LoadNoCover: boolean;
- OldTextureLimit: integer;
-begin
- if (Length(CatSongs.Song) <= 0) then
- Exit;
-
- // set length of button array once instead for every song
- SetButtonLength(Length(CatSongs.Song));
-
- // backup and set texture limit
- OldTextureLimit := Texture.Limit;
- Texture.Limit := 512;
-
- // create all buttons
- for I := 0 to High(CatSongs.Song) do
- begin
- // if cover not found then show 'no cover'
- if (not FileExists(CatSongs.Song[I].Path + CatSongs.Song[I].Cover)) then
- CatSongs.Song[I].Cover := '';
-
- if (CatSongs.Song[I].Cover = '') then
- begin
- LoadNoCover := true;
- end
- else
- begin
- // cache texture if there is a need to this
- if (not Covers.CoverExists(CatSongs.Song[I].Path + CatSongs.Song[I].Cover)) then
- begin
- Texture.CreateCacheMipmap := true;
- Texture.GetTexture(CatSongs.Song[I].Path + CatSongs.Song[I].Cover, TEXTURE_TYPE_PLAIN, true); // preloads textures and creates cache mipmap
- Texture.CreateCacheMipmap := false;
-
- // puts this texture to the cache file
- Covers.AddCover(CatSongs.Song[I].Path + CatSongs.Song[I].Cover);
-
- // unload full size texture
- Texture.UnloadTexture(CatSongs.Song[I].Path + CatSongs.Song[I].Cover, TEXTURE_TYPE_PLAIN, false);
-
- // TODO: we should also add mipmap texture by calling createtexture and use mipmap cache as data source
- end;
-
- // and now load it from cache file (small place for the optimization by eliminating reading it from file, but not here)
- try
- // FIXME: do we really need try-except here? AddButton does not seem to throw exceptions if it fails.
- AddButton(300 + I*250, 140, 200, 200, CatSongs.Song[I].Path + CatSongs.Song[I].Cover, TEXTURE_TYPE_PLAIN, Theme.Song.Cover.Reflections);
- LoadNoCover := false;
- except
- // report error and change cover to NoCover
- Log.LogError('Could not load Cover: ' + CatSongs.Song[I].Cover);
- LoadNoCover := true;
- end;
- end;
-
- if (LoadNoCover) then
- begin
- try
- // FIXME: do we really need try-except here? AddButton does not seem to throw exceptions if it fails.
- AddButton(300 + I*250, 140, 200, 200, Skin.GetTextureFileName('SongCover'), TEXTURE_TYPE_PLAIN, Theme.Song.Cover.Reflections)
- except
- // NoSong Cover is damaged
- Log.LogError('NoCover Cover is damaged!');
- // set a dummy cover and start loading next Song
- try
- // FIXME: do we really need try-except here? AddButton does not seem to throw exceptions if it fails.
- AddButton(300 + I*250, 140, 200, 200, '', TEXTURE_TYPE_PLAIN, Theme.Song.Cover.Reflections);
- except
- ShowMessage('"No Cover" image is damaged. Ultrastar will exit now.');
- Halt;
- end;
- end;
- end;
- end;
-
- // restore texture limit
- Texture.Limit := OldTextureLimit;
-end;
-
-procedure TScreenSong.SetScroll;
-var
- VS, B: Integer;
-begin
- VS := CatSongs.VisibleSongs;
- if VS > 0 then
- begin
- //Set Positions
- Case Theme.Song.Cover.Style of
- 3: SetScroll3;
- 5:begin
- if VS > 5 then
- SetScroll5
- else
- SetScroll4;
- end;
- 6: SetScroll6;
- else SetScroll4;
- end;
- //Set Visibility of Video Icon
- Static[VideoIcon].Visible := (CatSongs.Song[Interaction].Video <> '');
-
- //Set Texts:
- Text[TextArtist].Text := CatSongs.Song[Interaction].Artist;
- Text[TextTitle].Text := CatSongs.Song[Interaction].Title;
- if (Ini.Tabs_at_startup = 1) And (CatSongs.CatNumShow = -1) then
- begin
- Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].OrderNum) + '/' + IntToStr(CatSongs.CatCount);
- Text[TextTitle].Text := '(' + IntToStr(CatSongs.Song[Interaction].CatNumber) + ' ' + Language.Translate('SING_SONGS_IN_CAT') + ')';
- end
- else if (CatSongs.CatNumShow = -2) then
- Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS)
- else if (CatSongs.CatNumShow = -3) then
- Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS)
- else if (Ini.Tabs_at_startup = 1) then
- Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].CatNumber) + '/' + IntToStr(CatSongs.Song[Interaction - CatSongs.Song[Interaction].CatNumber].CatNumber)
- else
- Text[TextNumber].Text := IntToStr(Interaction+1) + '/' + IntToStr(Length(CatSongs.Song));
- end
- else
- begin
- Text[TextNumber].Text := '0/0';
- Text[TextArtist].Text := '';
- Text[TextTitle].Text := '';
- for B := 0 to High(Button) do
- Button[B].Visible := False;
-
- end;
-end;
-
-procedure TScreenSong.SetScroll1;
-var
- B: integer; // button
- //BMin: integer; // button min // Auto Removed, Unused Variable
- //BMax: integer; // button max // Auto Removed, Unused Variable
- Src: integer;
- //Dst: integer;
- Count: integer; // Dst is not used. Count is used.
- Ready: boolean;
-
- VisCount: integer; // count of visible (or selectable) buttons
- VisInt: integer; // visible position of interacted button
- Typ: integer; // 0 when all songs fits the screen
- Placed: integer; // number of placed visible buttons
-begin
- //Src := 0;
- //Dst := -1;
- Count := 1;
- Typ := 0;
- Ready := false;
- Placed := 0;
-
- VisCount := 0;
- for B := 0 to High(Button) do
- if CatSongs.Song[B].Visible then Inc(VisCount);
-
- VisInt := 0;
- for B := 0 to Interaction-1 do
- if CatSongs.Song[B].Visible then Inc(VisInt);
-
-
- if VisCount <= 6 then begin
- Typ := 0;
- end else begin
- if VisInt <= 3 then begin
- Typ := 1;
- Count := 7;
- Ready := true;
- end;
-
- if (VisCount - VisInt) <= 3 then begin
- Typ := 2;
- Count := 7;
- Ready := true;
- end;
-
- if not Ready then begin
- Typ := 3;
- Src := Interaction;
- end;
- end;
-
-
-
- // hide all buttons
- for B := 0 to High(Button) do begin
- Button[B].Visible := false;
- Button[B].Selectable := CatSongs.Song[B].Visible;
- end;
-
- {
- for B := Src to Dst do begin
- //Button[B].Visible := true;
- Button[B].Visible := CatSongs.Song[B].Visible;
- Button[B].Selectable := Button[B].Visible;
- Button[B].Y := 140 + (B-Src) * 60;
- end;
- }
-
-
- if Typ = 0 then begin
- for B := 0 to High(Button) do begin
- if CatSongs.Song[B].Visible then begin
- Button[B].Visible := true;
- Button[B].Y := 140 + (Placed) * 60;
- Inc(Placed);
- end;
- end;
- end;
-
- if Typ = 1 then begin
- B := 0;
- while (Count > 0) do begin
- if CatSongs.Song[B].Visible then begin
- Button[B].Visible := true;
- Button[B].Y := 140 + (Placed) * 60;
- Inc(Placed);
- Dec(Count);
- end;
- Inc(B);
- end;
- end;
-
- if Typ = 2 then begin
- B := High(Button);
- while (Count > 0) do begin
- if CatSongs.Song[B].Visible then begin
- Button[B].Visible := true;
- Button[B].Y := 140 + (6-Placed) * 60;
- Inc(Placed);
- Dec(Count);
- end;
- Dec(B);
- end;
- end;
-
- if Typ = 3 then begin
- B := Src;
- Count := 4;
- while (Count > 0) do begin
- if CatSongs.Song[B].Visible then begin
- Button[B].Visible := true;
- Button[B].Y := 140 + (3+Placed) * 60;
- Inc(Placed);
- Dec(Count);
- end;
- Inc(B);
- end;
-
- B := Src-1;
- Placed := 0;
- Count := 3;
- while (Count > 0) do begin
- if CatSongs.Song[B].Visible then begin
- Button[B].Visible := true;
- Button[B].Y := 140 + (2-Placed) * 60;
- Inc(Placed);
- Dec(Count);
- end;
- Dec(B);
- end;
-
- end;
-
- if Length(Button) > 0 then
- Static[1].Texture.Y := Button[Interaction].Y - 5; // selection texture
-end;
-
-procedure TScreenSong.SetScroll2;
-var
- B: integer;
- //Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu
- //Wsp2: real;
-begin
- // liniowe
- for B := 0 to High(Button) do
- Button[B].X := 300 + (B - Interaction) * 260;
-
- if Length(Button) >= 3 then begin
- if Interaction = 0 then
- Button[High(Button)].X := 300 - 260;
-
- if Interaction = High(Button) then
- Button[0].X := 300 + 260;
- end;
-
- // kolowe
- {
- for B := 0 to High(Button) do begin
- Wsp := (B - Interaction); // 0 dla srodka, -1 dla lewego, +1 dla prawego itd.
- Wsp2 := Wsp / Length(Button);
- Button[B].X := 300 + 10000 * sin(2*pi*Wsp2);
- //Button[B].Y := 140 + 50 * ;
- end;
- }
-end;
-
-procedure TScreenSong.SetScroll3; // with slide
-var
- B: integer;
- //Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu
- //Wsp2: real;
-begin
- SongTarget := Interaction;
-
- // liniowe
- for B := 0 to High(Button) do
- begin
- Button[B].X := 300 + (B - SongCurrent) * 260;
- if (Button[B].X < -Button[B].W) OR (Button[B].X > 800) then
- Button[B].Visible := False
- else
- Button[B].Visible := True;
- end;
-
- {
- if Length(Button) >= 3 then begin
- if Interaction = 0 then
- Button[High(Button)].X := 300 - 260;
-
- if Interaction = High(Button) then
- Button[0].X := 300 + 260;
- end;
- }
-
- // kolowe
- {
- for B := 0 to High(Button) do begin
- Wsp := (B - Interaction); // 0 dla srodka, -1 dla lewego, +1 dla prawego itd.
- Wsp2 := Wsp / Length(Button);
- Button[B].X := 300 + 10000 * sin(2*pi*Wsp2);
- //Button[B].Y := 140 + 50 * ;
- end;
- }
-end;
-
-procedure TScreenSong.SetScroll4; // rotate
-var
- B: integer;
- Wsp: real;
- Z, Z2: real;
- VS: integer;
-begin
- VS := CatSongs.VisibleSongs; // 0.5.0 (I): cached, very important
-
- // kolowe
- for B := 0 to High(Button) do begin
- Button[B].Visible := CatSongs.Song[B].Visible; // nowe
- if Button[B].Visible then begin // 0.5.0 optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed
-
- Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / VS {CatSongs.VisibleSongs};// 0.5.0 (II): takes another 16ms
-
- Z := (1 + cos(Wsp)) / 2;
- Z2 := (1 + 2*Z) / 3;
-
-
- Button[B].X := Theme.Song.Cover.X + (0.185 * Theme.Song.Cover.H * VS * sin(Wsp)) * Z2 - ((Button[B].H - Theme.Song.Cover.H)/2); // 0.5.0 (I): 2 times faster by not calling CatSongs.VisibleSongs
- Button[B].Z := Z / 2 + 0.3;
-
- Button[B].W := Theme.Song.Cover.H * Z2;
-
- //Button[B].Y := {50 +} 140 + 50 - 50 * Z2;
- Button[B].Y := Theme.Song.Cover.Y + (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7 ;
- Button[B].H := Button[B].W;
- end;
- end;
-end;
-
-(*
-procedure TScreenSong.SetScroll4; // rotate
-var
- B: integer;
- Wsp: real;
- Z: real;
- Z2, Z3: real;
- VS: integer;
- function modreal (const X, Y: real):real;
- begin
- Result := Frac(x / y) * y;
- if Result < -3 then
- Result := Result + Y
- else if Result > 3 then
- Result := Result - Y;
- end;
-begin
- VS := CatSongs.VisibleSongs; // 0.5.0 (I): cached, very important
- Z3 := 1;
- if VS < 12 then
- Z2 := VS
- else
- Z2 := 12;
-
- // kolowe
- for B := 0 to High(Button) do begin
- Button[B].Visible := CatSongs.Song[B].Visible; // nowe
- if Button[B].Visible then begin // 0.5.0 optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed
- if ((ModReal(CatSongs.VisibleIndex(B) - SongCurrent, VS)>-3) and (ModReal(CatSongs.VisibleIndex(B) - SongCurrent, VS)<3)) then
- begin
- if CatSongs.VisibleIndex(B)> SongCurrent then
- Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / Z2
- else
- Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / Z2;
-
- Z3 := 2;
- Z := (1 + cos(Wsp)) / 2;
- //Z2 := (1 + 2*Z) / 3;
- //Z2 := (0.5 + Z/2);
- //Z2 := sin(Wsp);
-
- //Z2 := Power (Z2,Z3);
-
- Button[B].W := Theme.Song.CoverW * Power(cos(Wsp), Z3);//Power(Z2, 3);
-
- //Button[B].X := Theme.Song.CoverX + ({Theme.Song.CoverX + Theme.Song.CoverW/2 + Theme.Song.CoverW*0.18 * VS {CatSongs.VisibleSongs {Length(Button) * sin(Wsp) {- Theme.Song.CoverX - Theme.Song.CoverW) * Z2; // 0.5.0 (I): 2 times faster by not calling CatSongs.VisibleSongs
- if (sin(Wsp)<0) then
- Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX + Theme.Song.CoverW - Button[B].W
- else //*Theme.Song.CoverW*0.004*Z3
- Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX;
- Button[B].Z := Z-0.00001;
-
- //Button[B].Y := {50 + 140 + 50 - 50 * Z2;
- //Button[B].Y := (Theme.Song.CoverY + 40 + 50 - 50 * Z2);
- Button[B].Y := (Theme.Song.CoverY + Theme.Song.CoverW - Button[B].W);
- Button[B].H := Button[B].W;
- Button[B].Visible := True;
- end
- {else if (((CatSongs.VisibleIndex(B) - SongCurrent)>-3) and ((CatSongs.VisibleIndex(B) - SongCurrent)<3)) OR ((round (CatSongs.VisibleIndex(B) - SongCurrent) mod VS > -3) and ((CatSongs.VisibleIndex(B) - SongCurrent)<3)) then
- begin
- Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / 12 ;// 0.5.0 (II): takes another 16ms
-
- Z := (1 + cos(Wsp)) / 2 -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
-
- Button[B].W := Theme.Song.CoverW * Power(cos(Wsp), Z3);//Power(Z2, 3);
-
- if (sin(Wsp)<0) then
- Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX + Theme.Song.CoverW - Button[B].W
- else
- Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX;
-
- Button[B].Z := Z;
-
- Button[B].Y := (Theme.Song.CoverY + Theme.Song.CoverW - Button[B].W);
-
- Button[B].H := Button[B].W;
- Button[B].Visible := True;
- end
- else Button[B].Visible := False;
- end;
- end;
-end; *)
-
-procedure TScreenSong.SetScroll5; // rotate
-var
- B: integer;
- Angle: real;
- Pos: Real;
- VS: integer;
- diff: real;
- X: Real;
- helper: real;
-begin
- VS := CatSongs.VisibleSongs; // cache Visible Songs
- {
- //Vars
- Theme.Song.CoverW: Radius des Kreises
- Theme.Song.CoverX: X Pos Linke Kante des gewählten Covers
- Theme.Song.CoverX: Y Pos Obere Kante des gewählten Covers
- Theme.Song.CoverH: Höhe der Cover
-
- (CatSongs.VisibleIndex(B) - SongCurrent)/VS = Distance to middle Cover in %
- }
-
- //Change Pos of all Buttons
- for B := low(Button) to high(Button) do
- begin
- Button[B].Visible := CatSongs.Song[B].Visible; //Adjust Visibility
- if Button[B].Visible then //Only Change Pos for Visible Buttons
- begin
- Pos := (CatSongs.VisibleIndex(B) - SongCurrent);
- if (Pos < -VS/2) then
- Pos := Pos + VS
- else if (Pos > VS/2) then
- Pos := Pos - VS;
-
- if (Abs(Pos) < 2.5) then {fixed Positions}
- begin
- Angle := Pi * (Pos / 5);
- //Button[B].Visible := False;
-
- Button[B].H := Abs(Theme.Song.Cover.H * cos(Angle*0.8));//Power(Z2, 3);
-
- //Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
- Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
-
- Button[B].Z := 0.95 - Abs(Pos) * 0.01;
-
- Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Abs(Theme.Song.Cover.H * cos(Angle))) * 0.5);
-
- Button[B].W := Button[B].H;
-
- Diff := (Button[B].H - Theme.Song.Cover.H)/2;
-
-
- X := Sin(Angle*1.3)*0.9;
-
- Button[B].X := Theme.Song.Cover.X + Theme.Song.Cover.W * X - Diff;
-
- end
- else
- begin {Behind the Front Covers}
-
- // limit-bg-covers hack
- if (abs(abs(Pos)-VS/2)>10) then Button[B].Visible:=False;
- // end of limit-bg-covers hack
-
- if Pos < 0 then
- Pos := (Pos - VS/2)/VS
- else
- Pos := (Pos + VS/2)/VS;
-
- Angle := pi * Pos*2;
- if VS > 24 then
- begin
- if Angle < 0 then helper:=-1 else helper:=1;
- Angle:=2*pi-abs(Angle);
- Angle:=Angle*(VS/24);
- Angle:=(2*pi-Angle)*helper;
- end;
-
- Button[B].Z := (0.4 - Abs(Pos/4)) -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
-
- Button[B].H :=0.6*(Theme.Song.Cover.H-Abs(Theme.Song.Cover.H * cos(Angle/2)*0.8));//Power(Z2, 3);
-
- Button[B].W := Button[B].H;
-
- Button[B].Y := Theme.Song.Cover.Y - (Button[B].H - Theme.Song.Cover.H)*0.75;
-
- //Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
- Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
-
- Diff := (Button[B].H - Theme.Song.Cover.H)/2;
-
- Button[B].X := Theme.Song.Cover.X+Theme.Song.Cover.H/2-Button[b].H/2+Theme.Song.Cover.W/320*((Theme.Song.Cover.H)*sin(Angle/2)*1.52);
-
- end;
-
- //Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Button[B].H)/1.5); //Cover at down border of the change field
- //Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Button[B].H) * 0.7);
-
- end;
- end;
-end;
-
-procedure TScreenSong.SetScroll6; // rotate (slotmachine style)
-var
- B: integer;
- Angle: real;
- Pos: Real;
- VS: integer;
- diff: real;
- X: Real;
- Wsp: real;
- Z, Z2: real;
-begin
- VS := CatSongs.VisibleSongs; // cache Visible Songs
- if VS <=5 then begin
- // kolowe
- for B := 0 to High(Button) do
- begin
- Button[B].Visible := CatSongs.Song[B].Visible; // nowe
- if Button[B].Visible then begin // 0.5.0 optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed
-
- Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / VS {CatSongs.VisibleSongs};// 0.5.0 (II): takes another 16ms
-
- Z := (1 + cos(Wsp)) / 2;
- Z2 := (1 + 2*Z) / 3;
-
-
- Button[B].Y := Theme.Song.Cover.Y + (0.185 * Theme.Song.Cover.H * VS * sin(Wsp)) * Z2 - ((Button[B].H - Theme.Song.Cover.H)/2); // 0.5.0 (I): 2 times faster by not calling CatSongs.VisibleSongs
- Button[B].Z := Z / 2 + 0.3;
-
- Button[B].W := Theme.Song.Cover.H * Z2;
-
- //Button[B].Y := {50 +} 140 + 50 - 50 * Z2;
- Button[B].X := Theme.Song.Cover.X + (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7 ;
- Button[B].H := Button[B].W;
- end;
- end;
- end
- else begin
-
- //Change Pos of all Buttons
- for B := low(Button) to high(Button) do
- begin
- Button[B].Visible := CatSongs.Song[B].Visible; //Adjust Visibility
- if Button[B].Visible then //Only Change Pos for Visible Buttons
- begin
- Pos := (CatSongs.VisibleIndex(B) - SongCurrent);
- if (Pos < -VS/2) then
- Pos := Pos + VS
- else if (Pos > VS/2) then
- Pos := Pos - VS;
-
- if (Abs(Pos) < 2.5) then {fixed Positions}
- begin
- Angle := Pi * (Pos / 5);
- //Button[B].Visible := False;
-
- Button[B].H := Abs(Theme.Song.Cover.H * cos(Angle*0.8));//Power(Z2, 3);
-
- Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
-
- Button[B].Z := 0.95 - Abs(Pos) * 0.01;
-
- Button[B].X := (Theme.Song.Cover.X + (Theme.Song.Cover.H - Abs(Theme.Song.Cover.H * cos(Angle))) * 0.5);
-
- Button[B].W := Button[B].H;
-
- Diff := (Button[B].H - Theme.Song.Cover.H)/2;
-
-
- X := Sin(Angle*1.3)*0.9;
-
- Button[B].Y := Theme.Song.Cover.Y + Theme.Song.Cover.W * X - Diff;
- end
- else
- begin {Behind the Front Covers}
-
- // limit-bg-covers hack
- if (abs(VS/2-abs(Pos))>10) then Button[B].Visible:=False;
- if VS > 25 then VS:=25;
- // end of limit-bg-covers hack
-
- if Pos < 0 then
- Pos := (Pos - VS/2)/VS
- else
- Pos := (Pos + VS/2)/VS;
-
- Angle := Pi * Pos*2;
-
- Button[B].Z := (0.4 - Abs(Pos/4)) -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
-
- Button[B].H :=0.6*(Theme.Song.Cover.H-Abs(Theme.Song.Cover.H * cos(Angle/2)*0.8));//Power(Z2, 3);
-
- Button[B].W := Button[B].H;
-
- Button[B].X := Theme.Song.Cover.X - (Button[B].H - Theme.Song.Cover.H)*0.5;
-
-
- Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
-
- Button[B].Y := Theme.Song.Cover.Y+Theme.Song.Cover.H/2-Button[b].H/2+Theme.Song.Cover.W/320*(Theme.Song.Cover.H*sin(Angle/2)*1.52);
- end;
- end;
- end;
- end;
-end;
-
-
-procedure TScreenSong.onShow;
-begin
- inherited;
-
- AudioPlayback.Stop;
-
- if Ini.Players <= 3 then PlayersPlay := Ini.Players + 1;
- if Ini.Players = 4 then PlayersPlay := 6;
-
- //Cat Mod etc
- if (Ini.Tabs_at_startup = 1) and (CatSongs.CatNumShow = -1) then
- begin
- CatSongs.ShowCategoryList;
- FixSelected;
- //Show Cat in Top Left Mod
- HideCatTL;
- end;
-
- if Length(CatSongs.Song) > 0 then
- begin
- //Load Music only when Song Preview is activated
- if ( Ini.PreviewVolume <> 0 ) then
- begin // to - do : new Song management
- StartMusicPreview(CatSongs.Song[Interaction]);
- end;
-
- SetScroll;
- //UpdateLCD; //TODO: maybe LCD Support as Plugin?
- end;
-
- //Playlist Mode
- if (Mode = smNormal) then
- begin
- //If Playlist Shown -> Select Next automatically
- if (CatSongs.CatNumShow = -3) then
- begin
- SelectNext;
- ChangeMusic;
- end;
- end
- //Party Mode
- else if (Mode = smPartyMode) then
- begin
- SelectRandomSong;
- //Show Menu directly in PartyMode
- //But only if selected in Options
- if (Ini.PartyPopup = 1) then
- begin
- ScreenSongMenu.MenuShow(SM_Party_Main);
- end;
- end;
-
- SetJoker;
- SetStatics;
-end;
-
-procedure TScreenSong.onHide;
-begin
- // if music fading is activated, turn music to 100%
- If (IPreviewVolumeVals[Ini.PreviewVolume] <> 1.0) or (Ini.PreviewFading <> 0) then
- AudioPlayback.SetVolume(1.0);
-
- // if preview is deactivated: load musicfile now
- If (IPreviewVolumeVals[Ini.PreviewVolume] = 0) then
- AudioPlayback.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3);
-
- // if hide then stop music (for party mode popup on exit)
- if (Display.NextScreen <> @ScreenSing) and
- (Display.NextScreen <> @ScreenSingModi) then
- begin
- if (AudioPlayback <> nil) then
- AudioPlayback.Stop;
- end;
-end;
-
-procedure TScreenSong.DrawExtensions;
-begin
- //Draw Song Menu
- if (ScreenSongMenu.Visible) then
- begin
- ScreenSongMenu.Draw;
- end
- else if (ScreenSongJumpto.Visible) then
- begin
- ScreenSongJumpto.Draw;
- end
-end;
-
-function TScreenSong.Draw: boolean;
-var
- dx: real;
- dt: real;
- I: Integer;
-begin
- dx := SongTarget-SongCurrent;
- dt := TimeSkip * 7;
-
- if dt > 1 then
- dt := 1;
-
- SongCurrent := SongCurrent + dx*dt;
-
- {
- if SongCurrent > Catsongs.VisibleSongs then begin
- SongCurrent := SongCurrent - Catsongs.VisibleSongs;
- SongTarget := SongTarget - Catsongs.VisibleSongs;
- end;
- }
-
- //Log.BenchmarkStart(5);
-
- SetScroll;
-
- //Log.BenchmarkEnd(5);
- //Log.LogBenchmark('SetScroll4', 5);
-
- //Fading Functions, Only if Covertime is under 5 Seconds
- if (CoverTime < 5) then
- begin
- // cover fade
- if (CoverTime < 1) and (CoverTime + TimeSkip >= 1) then
- begin
- // load new texture
- Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
- Button[Interaction].Texture.Alpha := 1;
- Button[Interaction].Texture2 := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
- Button[Interaction].Texture2.Alpha := 1;
- end;
-
- //Song Fade
- if (CatSongs.VisibleSongs > 0) and
- (not CatSongs.Song[Interaction].Main) and
- (Ini.PreviewVolume <> 0) and
- (Ini.PreviewFading <> 0) then
- begin
- //Start Song Fade after a little Time, to prevent Song to be Played on Scrolling
- if ((MusicStartTime > 0) and (SDL_GetTicks() >= MusicStartTime)) then
- begin
- MusicStartTime := 0;
- StartMusicPreview(CatSongs.Song[Interaction]);
- end;
- end;
-
-
- //Update Fading Time
- CoverTime := CoverTime + TimeSkip;
-
- //Update Fading Texture
- Button[Interaction].Texture2.Alpha := (CoverTime - 1) * 1.5;
- if Button[Interaction].Texture2.Alpha > 1 then
- Button[Interaction].Texture2.Alpha := 1;
-
- end;
-
- //inherited Draw;
- //heres a little Hack, that causes the Statics
- //are Drawn after the Buttons because of some Blending Problems.
- //This should cause no Problems because all Buttons on this screen
- //Has Z Position.
- //Draw BG
- DrawBG;
-
- //Instead of Draw FG Procedure:
- //We draw Buttons for our own
- for I := 0 to Length(Button) - 1 do
- Button[I].Draw;
-
- // Statics
- for I := 0 to Length(Static) - 1 do
- Static[I].Draw;
-
- // and texts
- for I := 0 to Length(Text) - 1 do
- Text[I].Draw;
-
-
- //Draw Equalizer
- if Theme.Song.Equalizer.Visible then
- DrawEqualizer;
-
- DrawExtensions;
-
- Result := true;
-end;
-
-procedure TScreenSong.SelectNext;
-var
- Skip: integer;
- VS: Integer;
-begin
- VS := CatSongs.VisibleSongs;
-
- if VS > 0 then
- begin
- UnLoadDetailedCover;
-
- Skip := 1;
-
- // this 1 could be changed by CatSongs.FindNextVisible
- while (not CatSongs.Song[(Interaction + Skip) mod Length(Interactions)].Visible) do
- Inc(Skip);
-
- SongTarget := SongTarget + 1;//Skip;
-
- Interaction := (Interaction + Skip) mod Length(Interactions);
-
- // try to keep all at the beginning
- if SongTarget > VS-1 then begin
- SongTarget := SongTarget - VS;
- SongCurrent := SongCurrent - VS;
- end;
-
- end;
-
- // Interaction -> Button, ktorego okladke przeczytamy
- //Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false); // 0.5.0: show uncached texture
-end;
-
-procedure TScreenSong.SelectPrev;
-var
- Skip: integer;
- VS: Integer;
-begin
- VS := CatSongs.VisibleSongs;
-
- if VS > 0 then
- begin
- UnLoadDetailedCover;
-
- Skip := 1;
-
- while (not CatSongs.Song[(Interaction - Skip + Length(Interactions)) mod Length(Interactions)].Visible) do Inc(Skip);
- SongTarget := SongTarget - 1;//Skip;
-
- Interaction := (Interaction - Skip + Length(Interactions)) mod Length(Interactions);
-
- // try to keep all at the beginning
- if SongTarget < 0 then begin
- SongTarget := SongTarget + CatSongs.VisibleSongs;
- SongCurrent := SongCurrent + CatSongs.VisibleSongs;
- end;
-
- // Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false); // 0.5.0: show uncached texture
- end;
-end;
-
-(*
-procedure TScreenSong.UpdateLCD; //TODO: maybe LCD Support as Plugin?
-begin
- LCD.HideCursor;
- LCD.Clear;
- LCD.WriteText(1, Text[TextArtist].Text);
- LCD.WriteText(2, Text[TextTitle].Text);
-
-end;
-*)
-
-procedure TScreenSong.StartMusicPreview(Song: TSong);
-begin
- AudioPlayback.Close();
-
- if not assigned(Song) then
- Exit;
-
- if AudioPlayback.Open(Song.Path + Song.Mp3) then
- begin
- AudioPlayback.Position := AudioPlayback.Length / 4;
- // set preview volume
- if (Ini.PreviewFading = 0) then
- begin
- // music fade disabled: start with full volume
- AudioPlayback.SetVolume(IPreviewVolumeVals[Ini.PreviewVolume]);
- AudioPlayback.Play()
- end
- else
- begin
- // music fade enabled: start muted and fade-in
- AudioPlayback.SetVolume(0);
- AudioPlayback.FadeIn(Ini.PreviewFading, IPreviewVolumeVals[Ini.PreviewVolume]);
- end;
- end;
-end;
-
-//Procedure Change current played Preview
-procedure TScreenSong.ChangeMusic;
-begin
- //When Music Preview is avtivated -> then Change Music
- if (Ini.PreviewVolume <> 0) then
- begin
- // Stop previous song
- AudioPlayback.Stop;
- // Disable music start delay
- MusicStartTime := 0;
-
- if (CatSongs.VisibleSongs > 0) then
- begin
- // delay start of music for 200ms (see Draw())
- MusicStartTime := SDL_GetTicks() + 200;
- end;
- end;
-end;
-
-procedure TScreenSong.SkipTo(Target: Cardinal);
-var
- i: integer;
-begin
- UnLoadDetailedCover;
-
- Interaction := High(CatSongs.Song);
- SongTarget := 0;
-
- for i := 1 to Target+1 do
- SelectNext;
-
- FixSelected2;
-end;
-
-procedure TScreenSong.DrawEqualizer;
-var
- I, J: Integer;
- ChansPerBand: byte; // channels per band
- MaxChannel: Integer;
- CurBand: Integer; // current band
- CurTime: Cardinal;
- PosX, PosY: Integer;
- Pos: Real;
-begin
- // Nothing to do if no music is played or an equalizer bar consists of no block
- if (AudioPlayback.Finished or (Theme.Song.Equalizer.Length <= 0)) then
- Exit;
-
- CurTime := SDL_GetTicks();
-
- // Evaluate FFT-data every 44 ms
- if (CurTime >= EqualizerTime) then
- begin
- EqualizerTime := CurTime + 44;
- AudioPlayback.GetFFTData(EqualizerData);
-
- Pos := 0;
- // use only the first approx. 92 of 256 FFT-channels (approx. up to 8kHz
- ChansPerBand := ceil(92 / Theme.Song.Equalizer.Bands); // How much channels are used for one Band
- MaxChannel := ChansPerBand * Theme.Song.Equalizer.Bands - 1;
-
- // Change Lengths
- for i := 0 to MaxChannel do
- begin
- // Gain higher freq. data so that the bars are visible
- if i > 35 then
- EqualizerData[i] := EqualizerData[i] * 8
- else if i > 11 then
- EqualizerData[i] := EqualizerData[i] * 4.5
- else
- EqualizerData[i] := EqualizerData[i] * 1.1;
-
- // clamp data
- if (EqualizerData[i] > 1) then
- EqualizerData[i] := 1;
-
- // Get max. pos
- if (EqualizerData[i] * Theme.Song.Equalizer.Length > Pos) then
- Pos := EqualizerData[i] * Theme.Song.Equalizer.Length;
-
- // Check if this is the last channel in the band
- if ((i+1) mod ChansPerBand = 0) then
- begin
- CurBand := i div ChansPerBand;
-
- // Smooth delay if new equalizer is lower than the old one
- if ((EqualizerBands[CurBand] > Pos) and (EqualizerBands[CurBand] > 1)) then
- EqualizerBands[CurBand] := EqualizerBands[CurBand] - 1
- else
- EqualizerBands[CurBand] := Round(Pos);
-
- Pos := 0;
- end;
- end;
-
- end;
-
- // Draw equalizer bands
-
- // Setup OpenGL
- glColor4f(Theme.Song.Equalizer.ColR, Theme.Song.Equalizer.ColG, Theme.Song.Equalizer.ColB, Theme.Song.Equalizer.Alpha);
- glDisable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
-
- // Set position of the first equalizer bar
- PosY := Theme.Song.Equalizer.Y;
- PosX := Theme.Song.Equalizer.X;
-
- // Draw bars for each band
- for I := 0 to High(EqualizerBands) do
- begin
- // Reset to lower or left position depending on the drawing-direction
- if Theme.Song.Equalizer.Direction then // Vertical bars
- // FIXME: Is Theme.Song.Equalizer.Y the upper or lower coordinate?
- PosY := Theme.Song.Equalizer.Y //+ (Theme.Song.Equalizer.H + Theme.Song.Equalizer.Space) * Theme.Song.Equalizer.Length
- else // Horizontal bars
- PosX := Theme.Song.Equalizer.X;
-
- // Draw the bar as a stack of blocks
- for J := 1 to EqualizerBands[I] do
- begin
- // Draw block
- glBegin(GL_QUADS);
- glVertex3f(PosX, PosY, Theme.Song.Equalizer.Z);
- glVertex3f(PosX, PosY+Theme.Song.Equalizer.H, Theme.Song.Equalizer.Z);
- glVertex3f(PosX+Theme.Song.Equalizer.W, PosY+Theme.Song.Equalizer.H, Theme.Song.Equalizer.Z);
- glVertex3f(PosX+Theme.Song.Equalizer.W, PosY, Theme.Song.Equalizer.Z);
- glEnd;
-
- // Calc position of the bar's next block
- if Theme.Song.Equalizer.Direction then // Vertical bars
- PosY := PosY - Theme.Song.Equalizer.H - Theme.Song.Equalizer.Space
- else // Horizontal bars
- PosX := PosX + Theme.Song.Equalizer.W + Theme.Song.Equalizer.Space;
- end;
-
- // Calc position of the next bar
- if Theme.Song.Equalizer.Direction then // Vertical bars
- PosX := PosX + Theme.Song.Equalizer.W + Theme.Song.Equalizer.Space
- else // Horizontal bars
- PosY := PosY + Theme.Song.Equalizer.H + Theme.Song.Equalizer.Space;
- end;
-end;
-
-procedure TScreenSong.SelectRandomSong;
-var
- I, I2: Integer;
-begin
- case PlaylistMan.Mode of
- smNormal: //All Songs Just Select Random Song
- begin
- //When Tabs are activated then use Tab Method
- if (Ini.Tabs_at_startup = 1) then
- begin
- repeat
- I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1;
- until CatSongs.Song[I2].Main = false;
-
- //Search Cat
- for I := I2 downto low(CatSongs.Song) do
- begin
- if CatSongs.Song[I].Main then
- break;
- end;
- //In I ist jetzt die Kategorie in I2 der Song
- //I is the CatNum, I2 is the No of the Song within this Cat
-
- //Choose Cat
- CatSongs.ShowCategoryList;
-
- //Show Cat in Top Left Mod
- ShowCatTL (I);
-
- CatSongs.ClickCategoryButton(I);
- SelectNext;
-
- //Choose Song
- SkipTo(I2-I);
- end
- //When Tabs are deactivated use easy Method
- else
- SkipTo(Random(CatSongs.VisibleSongs));
- end;
- smPartyMode: //One Category Select Category and Select Random Song
- begin
- CatSongs.ShowCategoryList;
- CatSongs.ClickCategoryButton(PlaylistMan.CurPlayList);
- ShowCatTL(PlaylistMan.CurPlayList);
-
- SelectNext;
- FixSelected2;
-
- SkipTo(Random(CatSongs.VisibleSongs));
- end;
- smPlaylistRandom: //Playlist: Select Playlist and Select Random Song
- begin
- PlaylistMan.SetPlayList(PlaylistMan.CurPlayList);
-
- SkipTo(Random(CatSongs.VisibleSongs));
- FixSelected2;
- end;
- end;
-
- AudioPlayback.PlaySound(SoundLib.Change);
- ChangeMusic;
- SetScroll;
- //UpdateLCD; //TODO: maybe LCD Support as Plugin?
-end;
-
-procedure TScreenSong.SetJoker;
-begin
- // If Party Mode
- // to-do : Party
- if Mode = smPartyMode then //Show Joker that are available
- begin
- (*
- if (PartySession.Teams.NumTeams >= 1) then
- begin
- Static[StaticTeam1Joker1].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 1);
- Static[StaticTeam1Joker2].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 2);
- Static[StaticTeam1Joker3].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 3);
- Static[StaticTeam1Joker4].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 4);
- Static[StaticTeam1Joker5].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 5);
- end
- else
- begin
- Static[StaticTeam1Joker1].Visible := False;
- Static[StaticTeam1Joker2].Visible := False;
- Static[StaticTeam1Joker3].Visible := False;
- Static[StaticTeam1Joker4].Visible := False;
- Static[StaticTeam1Joker5].Visible := False;
- end;
-
- if (PartySession.Teams.NumTeams >= 2) then
- begin
- Static[StaticTeam2Joker1].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 1);
- Static[StaticTeam2Joker2].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 2);
- Static[StaticTeam2Joker3].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 3);
- Static[StaticTeam2Joker4].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 4);
- Static[StaticTeam2Joker5].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 5);
- end
- else
- begin
- Static[StaticTeam2Joker1].Visible := False;
- Static[StaticTeam2Joker2].Visible := False;
- Static[StaticTeam2Joker3].Visible := False;
- Static[StaticTeam2Joker4].Visible := False;
- Static[StaticTeam2Joker5].Visible := False;
- end;
-
- if (PartySession.Teams.NumTeams >= 3) then
- begin
- Static[StaticTeam3Joker1].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 1);
- Static[StaticTeam3Joker2].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 2);
- Static[StaticTeam3Joker3].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 3);
- Static[StaticTeam3Joker4].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 4);
- Static[StaticTeam3Joker5].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 5);
- end
- else
- begin
- Static[StaticTeam3Joker1].Visible := False;
- Static[StaticTeam3Joker2].Visible := False;
- Static[StaticTeam3Joker3].Visible := False;
- Static[StaticTeam3Joker4].Visible := False;
- Static[StaticTeam3Joker5].Visible := False;
- end;
- *)
- end
- else
- begin //Hide all
- Static[StaticTeam1Joker1].Visible := False;
- Static[StaticTeam1Joker2].Visible := False;
- Static[StaticTeam1Joker3].Visible := False;
- Static[StaticTeam1Joker4].Visible := False;
- Static[StaticTeam1Joker5].Visible := False;
-
- Static[StaticTeam2Joker1].Visible := False;
- Static[StaticTeam2Joker2].Visible := False;
- Static[StaticTeam2Joker3].Visible := False;
- Static[StaticTeam2Joker4].Visible := False;
- Static[StaticTeam2Joker5].Visible := False;
-
- Static[StaticTeam3Joker1].Visible := False;
- Static[StaticTeam3Joker2].Visible := False;
- Static[StaticTeam3Joker3].Visible := False;
- Static[StaticTeam3Joker4].Visible := False;
- Static[StaticTeam3Joker5].Visible := False;
- end;
-end;
-
-procedure TScreenSong.SetStatics;
-var
- I: Integer;
- Visible: Boolean;
-begin
- //Set Visibility of Party Statics and Text
- Visible := (Mode = smPartyMode);
-
- for I := 0 to high(StaticParty) do
- Static[StaticParty[I]].Visible := Visible;
-
- for I := 0 to high(TextParty) do
- Text[TextParty[I]].Visible := Visible;
-
- //Set Visibility of Non Party Statics and Text
- Visible := not Visible;
-
- for I := 0 to high(StaticNonParty) do
- Static[StaticNonParty[I]].Visible := Visible;
-
- for I := 0 to high(TextNonParty) do
- Text[TextNonParty[I]].Visible := Visible;
-end;
-
-//Procedures for Menu
-
-procedure TScreenSong.StartSong;
-begin
- CatSongs.Selected := Interaction;
- AudioPlayback.Stop;
- //Party Mode
- if (Mode = smPartyMode) then
- begin
- FadeTo(@ScreenSingModi);
- end
- else
- begin
- FadeTo(@ScreenSing);
- end;
-end;
-
-procedure TScreenSong.SelectPlayers;
-begin
- CatSongs.Selected := Interaction;
- AudioPlayback.Stop;
-
- ScreenName.Goto_SingScreen := True;
- FadeTo(@ScreenName);
-end;
-
-procedure TScreenSong.OpenEditor;
-begin
- if (Songs.SongList.Count > 0) and
- (not CatSongs.Song[Interaction].Main) and
- (Mode = smNormal) then
- begin
- AudioPlayback.Stop;
- AudioPlayback.PlaySound(SoundLib.Start);
- CurrentSong := CatSongs.Song[Interaction];
- FadeTo(@ScreenEditSub);
- end;
-end;
-
-//Team No of Team (0-5)
-procedure TScreenSong.DoJoker (Team: Byte);
-begin
- {
- if (Mode = smPartyMode) and
- (PartySession.Teams.NumTeams >= Team + 1) and
- (PartySession.Teams.Teaminfo[Team].Joker > 0) then
- begin
- //Use Joker
- Dec(PartySession.Teams.Teaminfo[Team].Joker);
- SelectRandomSong;
- SetJoker;
- end;
- }
-end;
-
-//Detailed Cover Unloading. Unloads the Detailed, uncached Cover of the cur. Song
-procedure TScreenSong.UnLoadDetailedCover;
-begin
- CoverTime := 0;
-
- // show cached texture
- Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, true);
- Button[Interaction].Texture2.Alpha := 0;
-
- if Button[Interaction].Texture.Name <> Skin.GetTextureFileName('SongCover') then
- Texture.UnloadTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
-end;
-
-procedure TScreenSong.Refresh;
-begin
- {
- CatSongs.Refresh;
- CatSongs.ShowCategoryList;
- Interaction := 0;
- SelectNext;
- FixSelected;
- }
-end;
-
-end.
+unit UScreenSong;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+
+uses
+ UMenu,
+ SDL,
+ UMusic,
+ UFiles,
+ UTime,
+ UDisplay,
+ USongs,
+ SysUtils,
+ UCommon,
+ ULog,
+ UThemes,
+ UTexture,
+ ULanguage,
+ //ULCD, //TODO: maybe LCD Support as Plugin?
+ //ULight, //TODO: maybe Light Support as Plugin?
+ USong,
+ UIni;
+
+type
+ TScreenSong = class(TMenu)
+ private
+ EqualizerData: TFFTData; // moved here to avoid stack overflows
+ EqualizerBands: array of Byte;
+ EqualizerTime: Cardinal;
+
+ procedure StartMusicPreview(Song: TSong);
+ public
+ TextArtist: integer;
+ TextTitle: integer;
+ TextNumber: integer;
+
+ //Video Icon Mod
+ VideoIcon: Cardinal;
+
+ TextCat: integer;
+ StaticCat: integer;
+
+ SongCurrent: real;
+ SongTarget: real;
+
+ HighSpeed: boolean;
+ CoverFull: boolean;
+ CoverTime: real;
+ MusicStartTime: cardinal;
+
+ CoverX: integer;
+ CoverY: integer;
+ CoverW: integer;
+ is_jump: boolean; // Jump to Song Mod
+ is_jump_title:boolean; //Jump to SOng MOd-YTrue if search for Title
+
+ //Party Mod
+ Mode: TSingMode;
+
+ //party Statics (Joker)
+ StaticTeam1Joker1: Cardinal;
+ StaticTeam1Joker2: Cardinal;
+ StaticTeam1Joker3: Cardinal;
+ StaticTeam1Joker4: Cardinal;
+ StaticTeam1Joker5: Cardinal;
+
+ StaticTeam2Joker1: Cardinal;
+ StaticTeam2Joker2: Cardinal;
+ StaticTeam2Joker3: Cardinal;
+ StaticTeam2Joker4: Cardinal;
+ StaticTeam2Joker5: Cardinal;
+
+ StaticTeam3Joker1: Cardinal;
+ StaticTeam3Joker2: Cardinal;
+ StaticTeam3Joker3: Cardinal;
+ StaticTeam3Joker4: Cardinal;
+ StaticTeam3Joker5: Cardinal;
+
+ StaticParty: array of Cardinal;
+ TextParty: array of Cardinal;
+ StaticNonParty: array of Cardinal;
+ TextNonParty: array of Cardinal;
+
+
+ constructor Create; override;
+ procedure SetScroll;
+ procedure SetScroll1;
+ procedure SetScroll2;
+ procedure SetScroll3;
+ procedure SetScroll4;
+ procedure SetScroll5;
+ procedure SetScroll6;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+ procedure GenerateThumbnails();
+ procedure onShow; override;
+ procedure onHide; override;
+ procedure SelectNext;
+ procedure SelectPrev;
+ //procedure UpdateLCD; //TODO: maybe LCD Support as Plugin?
+ procedure SkipTo(Target: Cardinal);
+ procedure FixSelected; //Show Wrong Song when Tabs on Fix
+ procedure FixSelected2; //Show Wrong Song when Tabs on Fix
+ procedure ShowCatTL(Cat: Integer);// Show Cat in Top left
+ procedure ShowCatTLCustom(Caption: String);// Show Custom Text in Top left
+ procedure HideCatTL;// Show Cat in Tob left
+ procedure Refresh; //Refresh Song Sorting
+ procedure DrawEqualizer;
+ procedure ChangeMusic;
+ //Party Mode
+ procedure SelectRandomSong;
+ procedure SetJoker;
+ procedure SetStatics;
+ //procedures for Menu
+ procedure StartSong;
+ procedure OpenEditor;
+ procedure DoJoker(Team: Byte);
+ procedure SelectPlayers;
+
+ procedure UnLoadDetailedCover;
+
+ //Extensions
+ procedure DrawExtensions;
+ end;
+
+implementation
+
+uses
+ UGraphic,
+ UMain,
+ UCovers,
+ math,
+ gl,
+ USkins,
+ UDLLManager,
+ UParty,
+ UPlaylist,
+ UScreenSongMenu;
+
+// ***** Public methods ****** //
+
+//Show Wrong Song when Tabs on Fix
+procedure TScreenSong.FixSelected;
+var I, I2: Integer;
+begin
+ if CatSongs.VisibleSongs > 0 then
+ begin
+ I2:= 0;
+ for I := low(CatSongs.Song) to High(Catsongs.Song) do
+ begin
+ if CatSongs.Song[I].Visible then
+ inc(I2);
+
+ if I = Interaction - 1 then
+ break;
+ end;
+
+ SongCurrent := I2;
+ SongTarget := I2;
+ end;
+end;
+
+procedure TScreenSong.FixSelected2;
+var I, I2: Integer;
+begin
+ if CatSongs.VisibleSongs > 0 then
+ begin
+ I2:= 0;
+ for I := low(CatSongs.Song) to High(Catsongs.Song) do
+ begin
+ if CatSongs.Song[I].Visible then
+ inc(I2);
+
+ if I = Interaction - 1 then
+ break;
+ end;
+
+ SongTarget := I2;
+ end;
+end;
+//Show Wrong Song when Tabs on Fix End
+
+procedure TScreenSong.ShowCatTLCustom(Caption: String);// Show Custom Text in Top left
+begin
+ Text[TextCat].Text := Caption;
+ Text[TextCat].Visible := true;
+ Static[StaticCat].Visible := False;
+end;
+
+//Show Cat in Top Left Mod
+procedure TScreenSong.ShowCatTL(Cat: Integer);
+begin
+ //Change
+ Text[TextCat].Text := CatSongs.Song[Cat].Artist;
+ //showmessage(CatSongs.Song[Cat].Path + CatSongs.Song[Cat].Cover);
+ //Static[StaticCat].Texture := Texture.GetTexture(Button[Cat].Texture.Name, TEXTURE_TYPE_PLAIN, true);
+
+ Static[StaticCat].Texture := Texture.GetTexture(Button[Cat].Texture.Name, TEXTURE_TYPE_PLAIN, true);
+ //Texture.GetTexture(Button[Cat].Texture.Name, TEXTURE_TYPE_PLAIN, false);
+
+ //Show
+ Text[TextCat].Visible := true;
+ Static[StaticCat].Visible := True;
+end;
+
+procedure TScreenSong.HideCatTL;
+begin
+ //Hide
+ //Text[TextCat].Visible := false;
+ Static[StaticCat].Visible := false;
+ //New -> Show Text specified in Theme
+ Text[TextCat].Visible := True;
+ Text[TextCat].Text := Theme.Song.TextCat.Text;
+end;
+//Show Cat in Top Left Mod End
+
+
+// Method for input parsing. If False is returned, GetNextWindow
+// should be checked to know the next window to load;
+function TScreenSong.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+var
+ I: integer;
+ I2: integer;
+ SDL_ModState: Word;
+ Letter: WideChar;
+begin
+ Result := true;
+
+ //Song Screen Extensions (Jumpto + Menu)
+ if (ScreenSongMenu.Visible) then
+ begin
+ Result := ScreenSongMenu.ParseInput(PressedKey, CharCode, PressedDown);
+ Exit;
+ end
+ else if (ScreenSongJumpto.Visible) then
+ begin
+ Result := ScreenSongJumpto.ParseInput(PressedKey, CharCode, PressedDown);
+ Exit;
+ end;
+
+ if (PressedDown) then
+ begin // Key Down
+
+ SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT);
+
+ //Jump to Artist/Titel
+ if ((SDL_ModState and KMOD_LALT <> 0) and (Mode = smNormal)) then
+ begin
+ if (WideCharUpperCase(CharCode)[1] in ([WideChar('A')..WideChar('Z')]) ) then
+ begin
+ Letter := WideCharUpperCase(CharCode)[1];
+ I2 := Length(CatSongs.Song);
+
+ //Jump To Titel
+ if (SDL_ModState = (KMOD_LALT or KMOD_LSHIFT)) then
+ begin
+ for I := 1 to high(CatSongs.Song) do
+ begin
+ if (CatSongs.Song[(I + Interaction) mod I2].Visible) and
+ (Length(CatSongs.Song[(I + Interaction) mod I2].Title)>0) and
+ (WideStringUpperCase(CatSongs.Song[(I + Interaction) mod I2].Title)[1] = Letter) then
+ begin
+ SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2));
+
+ AudioPlayback.PlaySound(SoundLib.Change);
+
+ ChangeMusic;
+ SetScroll4;
+ //UpdateLCD; //TODO: maybe LCD Support as Plugin?
+ //Break and Exit
+ Exit;
+ end;
+ end;
+ end
+ //Jump to Artist
+ else if (SDL_ModState = KMOD_LALT) then
+ begin
+ for I := 1 to high(CatSongs.Song) do
+ begin
+ if (CatSongs.Song[(I + Interaction) mod I2].Visible) and
+ (Length(CatSongs.Song[(I + Interaction) mod I2].Artist)>0) and
+ (WideStringUpperCase(CatSongs.Song[(I + Interaction) mod I2].Artist)[1] = Letter) then
+ begin
+ SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2));
+
+ AudioPlayback.PlaySound(SoundLib.Change);
+
+ ChangeMusic;
+ SetScroll4;
+ //UpdateLCD; //TODO: maybe LCD Support as Plugin?
+
+ //Break and Exit
+ Exit;
+ end;
+ end;
+ end;
+ end;
+
+ Exit;
+ end;
+
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+
+ 'M': //Show SongMenu
+ begin
+ if (Songs.SongList.Count > 0) then
+ begin
+ if (Mode = smNormal) then
+ begin
+ if (not CatSongs.Song[Interaction].Main) then // clicked on Song
+ begin
+ if CatSongs.CatNumShow = -3 then
+ ScreenSongMenu.MenuShow(SM_Playlist)
+ else
+ ScreenSongMenu.MenuShow(SM_Main);
+ end
+ else
+ begin
+ ScreenSongMenu.MenuShow(SM_Playlist_Load);
+ end;
+ end //Party Mode -> Show Party Menu
+ else
+ begin
+ ScreenSongMenu.MenuShow(SM_Party_Main);
+ end;
+ end;
+ Exit;
+ end;
+
+ 'P': //Show Playlist Menu
+ begin
+ if (Songs.SongList.Count > 0) and (Mode = smNormal) then
+ begin
+ ScreenSongMenu.MenuShow(SM_Playlist_Load);
+ end;
+ Exit;
+ end;
+
+ 'J': //Show Jumpto Menu
+ begin
+ if (Songs.SongList.Count > 0) and (Mode = smNormal) then
+ begin
+ ScreenSongJumpto.Visible := True;
+ end;
+ Exit;
+ end;
+
+ 'E':
+ begin
+ OpenEditor;
+ Exit;
+ end;
+
+ 'R':
+ begin
+ if (Songs.SongList.Count > 0) and (Mode = smNormal) then
+ begin
+ if (SDL_ModState = KMOD_LSHIFT) and (Ini.Tabs_at_startup = 1) then //Random Category
+ begin
+ I2 := 0; //Count Cats
+ for I:= low(CatSongs.Song) to high (CatSongs.Song) do
+ begin
+ if CatSongs.Song[I].Main then
+ Inc(I2);
+ end;
+
+ I2 := Random (I2)+1; //Zufall
+
+ //Find Cat:
+ for I:= low(CatSongs.Song) to high (CatSongs.Song) do
+ begin
+ if CatSongs.Song[I].Main then
+ Dec(I2);
+ if (I2<=0) then
+ begin
+ //Show Cat in Top Left Mod
+ ShowCatTL (I);
+
+ Interaction := I;
+
+ CatSongs.ShowCategoryList;
+ CatSongs.ClickCategoryButton(I);
+ SelectNext;
+ FixSelected;
+ break;
+ end;
+ end;
+ end
+ else if (SDL_ModState = KMOD_LCTRL) and (Ini.Tabs_at_startup = 1) then //random in All Categorys
+ begin
+ repeat
+ I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1;
+ until CatSongs.Song[I2].Main = false;
+
+ //Search Cat
+ for I := I2 downto low(CatSongs.Song) do
+ begin
+ if CatSongs.Song[I].Main then
+ break;
+ end;
+
+ //In I is now the categorie in I2 the song
+
+ //Choose Cat
+ CatSongs.ShowCategoryList;
+
+ //Show Cat in Top Left Mod
+ ShowCatTL (I);
+
+ CatSongs.ClickCategoryButton(I);
+ SelectNext;
+
+ //Fix: Not Existing Song selected:
+ //if (I+1=I2) then Inc(I2);
+
+ //Choose Song
+ SkipTo(I2-I);
+ end
+ else //Random in one Category
+ begin
+ SkipTo(Random(CatSongs.VisibleSongs));
+ end;
+ AudioPlayback.PlaySound(SoundLib.Change);
+
+ ChangeMusic;
+ SetScroll4;
+ //UpdateLCD; //TODO: maybe LCD Support as Plugin?
+ end;
+ Exit;
+ end;
+ end; // normal keys
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ if (Mode = smNormal) then
+ begin
+ //On Escape goto Cat-List Hack
+ if (Ini.Tabs_at_startup = 1) and (CatSongs.CatNumShow <> -1) then
+ begin
+ //Find Category
+ I := Interaction;
+ while not catsongs.Song[I].Main do
+ begin
+ Dec (I);
+ if (I < low(catsongs.Song)) then
+ break;
+ end;
+ if (I<= 1) then
+ Interaction := high(catsongs.Song)
+ else
+ Interaction := I - 1;
+
+ //Stop Music
+ AudioPlayback.Stop;
+
+ CatSongs.ShowCategoryList;
+
+ //Show Cat in Top Left Mod
+ HideCatTL;
+
+
+ //Show Wrong Song when Tabs on Fix
+ SelectNext;
+ FixSelected;
+ //SelectPrev;
+ //CatSongs.Song[0].Visible := False;
+ end
+ else
+ begin
+ //On Escape goto Cat-List Hack End
+ //Tabs off and in Search or Playlist -> Go back to Song view
+ if (CatSongs.CatNumShow < -1) then
+ begin
+ //Atm: Set Empty Filter
+ CatSongs.SetFilter('', 0);
+
+ //Show Cat in Top Left Mod
+ HideCatTL;
+ Interaction := 0;
+
+ //Show Wrong Song when Tabs on Fix
+ SelectNext;
+ FixSelected;
+
+ ChangeMusic;
+ end
+ else
+ begin
+ AudioPlayback.Stop;
+ AudioPlayback.PlaySound(SoundLib.Back);
+
+ FadeTo(@ScreenMain);
+ end;
+
+ end;
+ end
+ //When in party Mode then Ask before Close
+ else if (Mode = smPartyMode) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ CheckFadeTo(@ScreenMain,'MSG_END_PARTY');
+ end;
+ end;
+ SDLK_RETURN:
+ begin
+ if Songs.SongList.Count > 0 then
+ begin
+ {$IFDEF UseSerialPort}
+ // PortWriteB($378, 0);
+ {$ENDIF}
+ if CatSongs.Song[Interaction].Main then
+ begin // clicked on Category Button
+ //Show Cat in Top Left Mod
+ ShowCatTL (Interaction);
+
+ //I := CatSongs.VisibleIndex(Interaction);
+ CatSongs.ClickCategoryButton(Interaction);
+ {I2 := CatSongs.VisibleIndex(Interaction);
+ SongCurrent := SongCurrent - I + I2;
+ SongTarget := SongTarget - I + I2; }
+
+ // SetScroll4;
+
+ //Show Wrong Song when Tabs on Fix
+ SelectNext;
+ FixSelected;
+
+ //Play Music:
+ ChangeMusic;
+ end
+ else
+ begin // clicked on song
+ if (Mode = smNormal) then //Normal Mode -> Start Song
+ begin
+ //Do the Action that is specified in Ini
+ case Ini.OnSongClick of
+ 0: StartSong;
+ 1: SelectPlayers;
+ 2:begin
+ if (CatSongs.CatNumShow = -3) then
+ ScreenSongMenu.MenuShow(SM_Playlist)
+ else
+ ScreenSongMenu.MenuShow(SM_Main);
+ end;
+ end;
+ end
+ else if (Mode = smPartyMode) then //PartyMode -> Show Menu
+ begin
+ if (Ini.PartyPopup = 1) then
+ ScreenSongMenu.MenuShow(SM_Party_Main)
+ else
+ ScreenSong.StartSong;
+ end;
+ end;
+ end;
+ end;
+
+ SDLK_DOWN:
+ begin
+ if (Mode = smNormal) then
+ begin
+ //Only Change Cat when not in Playlist or Search Mode
+ if (CatSongs.CatNumShow > -2) then
+ begin
+ //Cat Change Hack
+ if Ini.Tabs_at_startup = 1 then
+ begin
+ I := Interaction;
+ if I <= 0 then I := 1;
+
+ while not catsongs.Song[I].Main do
+ begin
+ Inc (I);
+ if (I > high(catsongs.Song)) then
+ I := low(catsongs.Song);
+ end;
+
+ Interaction := I;
+
+ //Show Cat in Top Left Mod
+ ShowCatTL (Interaction);
+
+ CatSongs.ClickCategoryButton(Interaction);
+ SelectNext;
+ FixSelected;
+
+ //Play Music:
+ AudioPlayback.PlaySound(SoundLib.Change);
+ ChangeMusic;
+
+ end;
+
+ //
+ //Cat Change Hack End}
+ end;
+ end;
+ end;
+ SDLK_UP:
+ begin
+ if (Mode = smNormal) then
+ begin
+ //Only Change Cat when not in Playlist or Search Mode
+ if (CatSongs.CatNumShow > -2) then
+ begin
+ //Cat Change Hack
+ if Ini.Tabs_at_startup = 1 then
+ begin
+ I := Interaction;
+ I2 := 0;
+ if I <= 0 then I := 1;
+
+ while not catsongs.Song[I].Main or (I2 = 0) do
+ begin
+ if catsongs.Song[I].Main then
+ Inc(I2);
+ Dec (I);
+ if (I < low(catsongs.Song)) then
+ I := high(catsongs.Song);
+ end;
+
+ Interaction := I;
+
+ //Show Cat in Top Left Mod
+ ShowCatTL (I);
+
+ CatSongs.ClickCategoryButton(I);
+ SelectNext;
+ FixSelected;
+
+ //Play Music:
+ AudioPlayback.PlaySound(SoundLib.Change);
+ ChangeMusic;
+ end;
+ end;
+ //Cat Change Hack End}
+ end;
+ end;
+
+ SDLK_RIGHT:
+ begin
+ if (Songs.SongList.Count > 0) and (Mode = smNormal) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Change);
+ SelectNext;
+ //InteractNext;
+ //SongTarget := Interaction;
+ ChangeMusic;
+ SetScroll4;
+ //UpdateLCD; //TODO: maybe LCD Support as Plugin?
+ //Light.LightOne(1, 200); //TODO: maybe Light Support as Plugin?
+ end;
+ end;
+
+ SDLK_LEFT:
+ begin
+ if (Songs.SongList.Count > 0)and (Mode = smNormal) then
+ begin
+ AudioPlayback.PlaySound(SoundLib.Change);
+ SelectPrev;
+ ChangeMusic;
+ SetScroll4;
+ //UpdateLCD; //TODO: maybe LCD Support as Plugin?
+ //Light.LightOne(0, 200); //TODO: maybe Light Support as Plugin?
+ end;
+ end;
+
+ SDLK_1:
+ begin //Joker // to-do : Party
+ {if (Mode = smPartyMode) and (PartySession.Teams.NumTeams >= 1) and (PartySession.Teams.Teaminfo[0].Joker > 0) then
+ begin
+ //Use Joker
+ Dec(PartySession.Teams.Teaminfo[0].Joker);
+ SelectRandomSong;
+ SetJoker;
+ end; }
+ end;
+
+ SDLK_2:
+ begin //Joker
+ {if (Mode = smPartyMode) and (PartySession.Teams.NumTeams >= 2) and (PartySession.Teams.Teaminfo[1].Joker > 0) then
+ begin
+ //Use Joker
+ Dec(PartySession.Teams.Teaminfo[1].Joker);
+ SelectRandomSong;
+ SetJoker;
+ end; }
+ end;
+
+ SDLK_3:
+ begin //Joker
+ {if (Mode = smPartyMode) and (PartySession.Teams.NumTeams >= 3) and (PartySession.Teams.Teaminfo[2].Joker > 0) then
+ begin
+ //Use Joker
+ Dec(PartySession.Teams.Teaminfo[2].Joker);
+ SelectRandomSong;
+ SetJoker;
+ end; }
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenSong.Create;
+var
+ i: integer;
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.Song);
+
+ TextArtist := AddText(Theme.Song.TextArtist);
+ TextTitle := AddText(Theme.Song.TextTitle);
+ TextNumber := AddText(Theme.Song.TextNumber);
+
+ //Show Cat in Top Left mod
+ TextCat := AddText(Theme.Song.TextCat);
+ StaticCat := AddStatic(Theme.Song.StaticCat);
+
+ //Show Video Icon Mod
+ VideoIcon := AddStatic(Theme.Song.VideoIcon);
+
+ //Party Mode
+ StaticTeam1Joker1 := AddStatic(Theme.Song.StaticTeam1Joker1);
+ StaticTeam1Joker2 := AddStatic(Theme.Song.StaticTeam1Joker2);
+ StaticTeam1Joker3 := AddStatic(Theme.Song.StaticTeam1Joker3);
+ StaticTeam1Joker4 := AddStatic(Theme.Song.StaticTeam1Joker4);
+ StaticTeam1Joker5 := AddStatic(Theme.Song.StaticTeam1Joker5);
+
+ StaticTeam2Joker1 := AddStatic(Theme.Song.StaticTeam2Joker1);
+ StaticTeam2Joker2 := AddStatic(Theme.Song.StaticTeam2Joker2);
+ StaticTeam2Joker3 := AddStatic(Theme.Song.StaticTeam2Joker3);
+ StaticTeam2Joker4 := AddStatic(Theme.Song.StaticTeam2Joker4);
+ StaticTeam2Joker5 := AddStatic(Theme.Song.StaticTeam2Joker5);
+
+ StaticTeam3Joker1 := AddStatic(Theme.Song.StaticTeam3Joker1);
+ StaticTeam3Joker2 := AddStatic(Theme.Song.StaticTeam3Joker2);
+ StaticTeam3Joker3 := AddStatic(Theme.Song.StaticTeam3Joker3);
+ StaticTeam3Joker4 := AddStatic(Theme.Song.StaticTeam3Joker4);
+ StaticTeam3Joker5 := AddStatic(Theme.Song.StaticTeam3Joker5);
+
+ //Load Party or NonParty specific Statics and Texts
+ SetLength(StaticParty, Length(Theme.Song.StaticParty));
+ for i := 0 to High(Theme.Song.StaticParty) do
+ StaticParty[i] := AddStatic(Theme.Song.StaticParty[i]);
+
+ SetLength(TextParty, Length(Theme.Song.TextParty));
+ for i := 0 to High(Theme.Song.TextParty) do
+ TextParty[i] := AddText(Theme.Song.TextParty[i]);
+
+ SetLength(StaticNonParty, Length(Theme.Song.StaticNonParty));
+ for i := 0 to High(Theme.Song.StaticNonParty) do
+ StaticNonParty[i] := AddStatic(Theme.Song.StaticNonParty[i]);
+
+ SetLength(TextNonParty, Length(Theme.Song.TextNonParty));
+ for i := 0 to High(Theme.Song.TextNonParty) do
+ TextNonParty[i] := AddText(Theme.Song.TextNonParty[i]);
+
+ // Song List
+ //Songs.LoadSongList; // moved to the UltraStar unit
+ CatSongs.Refresh;
+
+ GenerateThumbnails();
+
+
+ // Randomize Patch
+ Randomize;
+ //Equalizer
+ SetLength(EqualizerBands, Theme.Song.Equalizer.Bands);
+ //ClearArray
+ For I := low(EqualizerBands) to high(EqualizerBands) do
+ EqualizerBands[I] := 3;
+
+ if (Length(CatSongs.Song) > 0) then
+ Interaction := 0;
+end;
+
+procedure TScreenSong.GenerateThumbnails();
+var
+ I: Integer;
+ LoadNoCover: boolean;
+ OldTextureLimit: integer;
+begin
+ if (Length(CatSongs.Song) <= 0) then
+ Exit;
+
+ // set length of button array once instead for every song
+ SetButtonLength(Length(CatSongs.Song));
+
+ // backup and set texture limit
+ OldTextureLimit := Texture.Limit;
+ Texture.Limit := 512;
+
+ // create all buttons
+ for I := 0 to High(CatSongs.Song) do
+ begin
+ // if cover not found then show 'no cover'
+ if (not FileExists(CatSongs.Song[I].Path + CatSongs.Song[I].Cover)) then
+ CatSongs.Song[I].Cover := '';
+
+ if (CatSongs.Song[I].Cover = '') then
+ begin
+ LoadNoCover := true;
+ end
+ else
+ begin
+ // cache texture if there is a need to this
+ if (not Covers.CoverExists(CatSongs.Song[I].Path + CatSongs.Song[I].Cover)) then
+ begin
+ Texture.CreateCacheMipmap := true;
+ Texture.GetTexture(CatSongs.Song[I].Path + CatSongs.Song[I].Cover, TEXTURE_TYPE_PLAIN, true); // preloads textures and creates cache mipmap
+ Texture.CreateCacheMipmap := false;
+
+ // puts this texture to the cache file
+ Covers.AddCover(CatSongs.Song[I].Path + CatSongs.Song[I].Cover);
+
+ // unload full size texture
+ Texture.UnloadTexture(CatSongs.Song[I].Path + CatSongs.Song[I].Cover, TEXTURE_TYPE_PLAIN, false);
+
+ // TODO: we should also add mipmap texture by calling createtexture and use mipmap cache as data source
+ end;
+
+ // and now load it from cache file (small place for the optimization by eliminating reading it from file, but not here)
+ try
+ // FIXME: do we really need try-except here? AddButton does not seem to throw exceptions if it fails.
+ AddButton(300 + I*250, 140, 200, 200, CatSongs.Song[I].Path + CatSongs.Song[I].Cover, TEXTURE_TYPE_PLAIN, Theme.Song.Cover.Reflections);
+ LoadNoCover := false;
+ except
+ // report error and change cover to NoCover
+ Log.LogError('Could not load Cover: ' + CatSongs.Song[I].Cover);
+ LoadNoCover := true;
+ end;
+ end;
+
+ if (LoadNoCover) then
+ begin
+ try
+ // FIXME: do we really need try-except here? AddButton does not seem to throw exceptions if it fails.
+ AddButton(300 + I*250, 140, 200, 200, Skin.GetTextureFileName('SongCover'), TEXTURE_TYPE_PLAIN, Theme.Song.Cover.Reflections)
+ except
+ // NoSong Cover is damaged
+ Log.LogError('NoCover Cover is damaged!');
+ // set a dummy cover and start loading next Song
+ try
+ // FIXME: do we really need try-except here? AddButton does not seem to throw exceptions if it fails.
+ AddButton(300 + I*250, 140, 200, 200, '', TEXTURE_TYPE_PLAIN, Theme.Song.Cover.Reflections);
+ except
+ ShowMessage('"No Cover" image is damaged. Ultrastar will exit now.');
+ Halt;
+ end;
+ end;
+ end;
+ end;
+
+ // restore texture limit
+ Texture.Limit := OldTextureLimit;
+end;
+
+procedure TScreenSong.SetScroll;
+var
+ VS, B: Integer;
+begin
+ VS := CatSongs.VisibleSongs;
+ if VS > 0 then
+ begin
+ //Set Positions
+ Case Theme.Song.Cover.Style of
+ 3: SetScroll3;
+ 5:begin
+ if VS > 5 then
+ SetScroll5
+ else
+ SetScroll4;
+ end;
+ 6: SetScroll6;
+ else SetScroll4;
+ end;
+ //Set Visibility of Video Icon
+ Static[VideoIcon].Visible := (CatSongs.Song[Interaction].Video <> '');
+
+ //Set Texts:
+ Text[TextArtist].Text := CatSongs.Song[Interaction].Artist;
+ Text[TextTitle].Text := CatSongs.Song[Interaction].Title;
+ if (Ini.Tabs_at_startup = 1) And (CatSongs.CatNumShow = -1) then
+ begin
+ Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].OrderNum) + '/' + IntToStr(CatSongs.CatCount);
+ Text[TextTitle].Text := '(' + IntToStr(CatSongs.Song[Interaction].CatNumber) + ' ' + Language.Translate('SING_SONGS_IN_CAT') + ')';
+ end
+ else if (CatSongs.CatNumShow = -2) then
+ Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS)
+ else if (CatSongs.CatNumShow = -3) then
+ Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS)
+ else if (Ini.Tabs_at_startup = 1) then
+ Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].CatNumber) + '/' + IntToStr(CatSongs.Song[Interaction - CatSongs.Song[Interaction].CatNumber].CatNumber)
+ else
+ Text[TextNumber].Text := IntToStr(Interaction+1) + '/' + IntToStr(Length(CatSongs.Song));
+ end
+ else
+ begin
+ Text[TextNumber].Text := '0/0';
+ Text[TextArtist].Text := '';
+ Text[TextTitle].Text := '';
+ for B := 0 to High(Button) do
+ Button[B].Visible := False;
+
+ end;
+end;
+
+procedure TScreenSong.SetScroll1;
+var
+ B: integer; // button
+ //BMin: integer; // button min // Auto Removed, Unused Variable
+ //BMax: integer; // button max // Auto Removed, Unused Variable
+ Src: integer;
+ //Dst: integer;
+ Count: integer; // Dst is not used. Count is used.
+ Ready: boolean;
+
+ VisCount: integer; // count of visible (or selectable) buttons
+ VisInt: integer; // visible position of interacted button
+ Typ: integer; // 0 when all songs fits the screen
+ Placed: integer; // number of placed visible buttons
+begin
+ //Src := 0;
+ //Dst := -1;
+ Count := 1;
+ Typ := 0;
+ Ready := false;
+ Placed := 0;
+
+ VisCount := 0;
+ for B := 0 to High(Button) do
+ if CatSongs.Song[B].Visible then Inc(VisCount);
+
+ VisInt := 0;
+ for B := 0 to Interaction-1 do
+ if CatSongs.Song[B].Visible then Inc(VisInt);
+
+
+ if VisCount <= 6 then begin
+ Typ := 0;
+ end else begin
+ if VisInt <= 3 then begin
+ Typ := 1;
+ Count := 7;
+ Ready := true;
+ end;
+
+ if (VisCount - VisInt) <= 3 then begin
+ Typ := 2;
+ Count := 7;
+ Ready := true;
+ end;
+
+ if not Ready then begin
+ Typ := 3;
+ Src := Interaction;
+ end;
+ end;
+
+
+
+ // hide all buttons
+ for B := 0 to High(Button) do begin
+ Button[B].Visible := false;
+ Button[B].Selectable := CatSongs.Song[B].Visible;
+ end;
+
+ {
+ for B := Src to Dst do begin
+ //Button[B].Visible := true;
+ Button[B].Visible := CatSongs.Song[B].Visible;
+ Button[B].Selectable := Button[B].Visible;
+ Button[B].Y := 140 + (B-Src) * 60;
+ end;
+ }
+
+
+ if Typ = 0 then begin
+ for B := 0 to High(Button) do begin
+ if CatSongs.Song[B].Visible then begin
+ Button[B].Visible := true;
+ Button[B].Y := 140 + (Placed) * 60;
+ Inc(Placed);
+ end;
+ end;
+ end;
+
+ if Typ = 1 then begin
+ B := 0;
+ while (Count > 0) do begin
+ if CatSongs.Song[B].Visible then begin
+ Button[B].Visible := true;
+ Button[B].Y := 140 + (Placed) * 60;
+ Inc(Placed);
+ Dec(Count);
+ end;
+ Inc(B);
+ end;
+ end;
+
+ if Typ = 2 then begin
+ B := High(Button);
+ while (Count > 0) do begin
+ if CatSongs.Song[B].Visible then begin
+ Button[B].Visible := true;
+ Button[B].Y := 140 + (6-Placed) * 60;
+ Inc(Placed);
+ Dec(Count);
+ end;
+ Dec(B);
+ end;
+ end;
+
+ if Typ = 3 then begin
+ B := Src;
+ Count := 4;
+ while (Count > 0) do begin
+ if CatSongs.Song[B].Visible then begin
+ Button[B].Visible := true;
+ Button[B].Y := 140 + (3+Placed) * 60;
+ Inc(Placed);
+ Dec(Count);
+ end;
+ Inc(B);
+ end;
+
+ B := Src-1;
+ Placed := 0;
+ Count := 3;
+ while (Count > 0) do begin
+ if CatSongs.Song[B].Visible then begin
+ Button[B].Visible := true;
+ Button[B].Y := 140 + (2-Placed) * 60;
+ Inc(Placed);
+ Dec(Count);
+ end;
+ Dec(B);
+ end;
+
+ end;
+
+ if Length(Button) > 0 then
+ Static[1].Texture.Y := Button[Interaction].Y - 5; // selection texture
+end;
+
+procedure TScreenSong.SetScroll2;
+var
+ B: integer;
+ //Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu
+ //Wsp2: real;
+begin
+ // liniowe
+ for B := 0 to High(Button) do
+ Button[B].X := 300 + (B - Interaction) * 260;
+
+ if Length(Button) >= 3 then begin
+ if Interaction = 0 then
+ Button[High(Button)].X := 300 - 260;
+
+ if Interaction = High(Button) then
+ Button[0].X := 300 + 260;
+ end;
+
+ // kolowe
+ {
+ for B := 0 to High(Button) do begin
+ Wsp := (B - Interaction); // 0 dla srodka, -1 dla lewego, +1 dla prawego itd.
+ Wsp2 := Wsp / Length(Button);
+ Button[B].X := 300 + 10000 * sin(2*pi*Wsp2);
+ //Button[B].Y := 140 + 50 * ;
+ end;
+ }
+end;
+
+procedure TScreenSong.SetScroll3; // with slide
+var
+ B: integer;
+ //Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu
+ //Wsp2: real;
+begin
+ SongTarget := Interaction;
+
+ // liniowe
+ for B := 0 to High(Button) do
+ begin
+ Button[B].X := 300 + (B - SongCurrent) * 260;
+ if (Button[B].X < -Button[B].W) OR (Button[B].X > 800) then
+ Button[B].Visible := False
+ else
+ Button[B].Visible := True;
+ end;
+
+ {
+ if Length(Button) >= 3 then begin
+ if Interaction = 0 then
+ Button[High(Button)].X := 300 - 260;
+
+ if Interaction = High(Button) then
+ Button[0].X := 300 + 260;
+ end;
+ }
+
+ // kolowe
+ {
+ for B := 0 to High(Button) do begin
+ Wsp := (B - Interaction); // 0 dla srodka, -1 dla lewego, +1 dla prawego itd.
+ Wsp2 := Wsp / Length(Button);
+ Button[B].X := 300 + 10000 * sin(2*pi*Wsp2);
+ //Button[B].Y := 140 + 50 * ;
+ end;
+ }
+end;
+
+procedure TScreenSong.SetScroll4; // rotate
+var
+ B: integer;
+ Wsp: real;
+ Z, Z2: real;
+ VS: integer;
+begin
+ VS := CatSongs.VisibleSongs; // 0.5.0 (I): cached, very important
+
+ // kolowe
+ for B := 0 to High(Button) do begin
+ Button[B].Visible := CatSongs.Song[B].Visible; // nowe
+ if Button[B].Visible then begin // 0.5.0 optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed
+
+ Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / VS {CatSongs.VisibleSongs};// 0.5.0 (II): takes another 16ms
+
+ Z := (1 + cos(Wsp)) / 2;
+ Z2 := (1 + 2*Z) / 3;
+
+
+ Button[B].X := Theme.Song.Cover.X + (0.185 * Theme.Song.Cover.H * VS * sin(Wsp)) * Z2 - ((Button[B].H - Theme.Song.Cover.H)/2); // 0.5.0 (I): 2 times faster by not calling CatSongs.VisibleSongs
+ Button[B].Z := Z / 2 + 0.3;
+
+ Button[B].W := Theme.Song.Cover.H * Z2;
+
+ //Button[B].Y := {50 +} 140 + 50 - 50 * Z2;
+ Button[B].Y := Theme.Song.Cover.Y + (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7 ;
+ Button[B].H := Button[B].W;
+ end;
+ end;
+end;
+
+(*
+procedure TScreenSong.SetScroll4; // rotate
+var
+ B: integer;
+ Wsp: real;
+ Z: real;
+ Z2, Z3: real;
+ VS: integer;
+ function modreal (const X, Y: real):real;
+ begin
+ Result := Frac(x / y) * y;
+ if Result < -3 then
+ Result := Result + Y
+ else if Result > 3 then
+ Result := Result - Y;
+ end;
+begin
+ VS := CatSongs.VisibleSongs; // 0.5.0 (I): cached, very important
+ Z3 := 1;
+ if VS < 12 then
+ Z2 := VS
+ else
+ Z2 := 12;
+
+ // kolowe
+ for B := 0 to High(Button) do begin
+ Button[B].Visible := CatSongs.Song[B].Visible; // nowe
+ if Button[B].Visible then begin // 0.5.0 optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed
+ if ((ModReal(CatSongs.VisibleIndex(B) - SongCurrent, VS)>-3) and (ModReal(CatSongs.VisibleIndex(B) - SongCurrent, VS)<3)) then
+ begin
+ if CatSongs.VisibleIndex(B)> SongCurrent then
+ Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / Z2
+ else
+ Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / Z2;
+
+ Z3 := 2;
+ Z := (1 + cos(Wsp)) / 2;
+ //Z2 := (1 + 2*Z) / 3;
+ //Z2 := (0.5 + Z/2);
+ //Z2 := sin(Wsp);
+
+ //Z2 := Power (Z2,Z3);
+
+ Button[B].W := Theme.Song.CoverW * Power(cos(Wsp), Z3);//Power(Z2, 3);
+
+ //Button[B].X := Theme.Song.CoverX + ({Theme.Song.CoverX + Theme.Song.CoverW/2 + Theme.Song.CoverW*0.18 * VS {CatSongs.VisibleSongs {Length(Button) * sin(Wsp) {- Theme.Song.CoverX - Theme.Song.CoverW) * Z2; // 0.5.0 (I): 2 times faster by not calling CatSongs.VisibleSongs
+ if (sin(Wsp)<0) then
+ Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX + Theme.Song.CoverW - Button[B].W
+ else //*Theme.Song.CoverW*0.004*Z3
+ Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX;
+ Button[B].Z := Z-0.00001;
+
+ //Button[B].Y := {50 + 140 + 50 - 50 * Z2;
+ //Button[B].Y := (Theme.Song.CoverY + 40 + 50 - 50 * Z2);
+ Button[B].Y := (Theme.Song.CoverY + Theme.Song.CoverW - Button[B].W);
+ Button[B].H := Button[B].W;
+ Button[B].Visible := True;
+ end
+ {else if (((CatSongs.VisibleIndex(B) - SongCurrent)>-3) and ((CatSongs.VisibleIndex(B) - SongCurrent)<3)) OR ((round (CatSongs.VisibleIndex(B) - SongCurrent) mod VS > -3) and ((CatSongs.VisibleIndex(B) - SongCurrent)<3)) then
+ begin
+ Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / 12 ;// 0.5.0 (II): takes another 16ms
+
+ Z := (1 + cos(Wsp)) / 2 -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
+
+ Button[B].W := Theme.Song.CoverW * Power(cos(Wsp), Z3);//Power(Z2, 3);
+
+ if (sin(Wsp)<0) then
+ Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX + Theme.Song.CoverW - Button[B].W
+ else
+ Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX;
+
+ Button[B].Z := Z;
+
+ Button[B].Y := (Theme.Song.CoverY + Theme.Song.CoverW - Button[B].W);
+
+ Button[B].H := Button[B].W;
+ Button[B].Visible := True;
+ end
+ else Button[B].Visible := False;
+ end;
+ end;
+end; *)
+
+procedure TScreenSong.SetScroll5; // rotate
+var
+ B: integer;
+ Angle: real;
+ Pos: Real;
+ VS: integer;
+ diff: real;
+ X: Real;
+ helper: real;
+begin
+ VS := CatSongs.VisibleSongs; // cache Visible Songs
+ {
+ //Vars
+ Theme.Song.CoverW: Radius des Kreises
+ Theme.Song.CoverX: X Pos Linke Kante des gewählten Covers
+ Theme.Song.CoverX: Y Pos Obere Kante des gewählten Covers
+ Theme.Song.CoverH: Höhe der Cover
+
+ (CatSongs.VisibleIndex(B) - SongCurrent)/VS = Distance to middle Cover in %
+ }
+
+ //Change Pos of all Buttons
+ for B := low(Button) to high(Button) do
+ begin
+ Button[B].Visible := CatSongs.Song[B].Visible; //Adjust Visibility
+ if Button[B].Visible then //Only Change Pos for Visible Buttons
+ begin
+ Pos := (CatSongs.VisibleIndex(B) - SongCurrent);
+ if (Pos < -VS/2) then
+ Pos := Pos + VS
+ else if (Pos > VS/2) then
+ Pos := Pos - VS;
+
+ if (Abs(Pos) < 2.5) then {fixed Positions}
+ begin
+ Angle := Pi * (Pos / 5);
+ //Button[B].Visible := False;
+
+ Button[B].H := Abs(Theme.Song.Cover.H * cos(Angle*0.8));//Power(Z2, 3);
+
+ //Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+ Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+
+ Button[B].Z := 0.95 - Abs(Pos) * 0.01;
+
+ Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Abs(Theme.Song.Cover.H * cos(Angle))) * 0.5);
+
+ Button[B].W := Button[B].H;
+
+ Diff := (Button[B].H - Theme.Song.Cover.H)/2;
+
+
+ X := Sin(Angle*1.3)*0.9;
+
+ Button[B].X := Theme.Song.Cover.X + Theme.Song.Cover.W * X - Diff;
+
+ end
+ else
+ begin {Behind the Front Covers}
+
+ // limit-bg-covers hack
+ if (abs(abs(Pos)-VS/2)>10) then Button[B].Visible:=False;
+ // end of limit-bg-covers hack
+
+ if Pos < 0 then
+ Pos := (Pos - VS/2)/VS
+ else
+ Pos := (Pos + VS/2)/VS;
+
+ Angle := pi * Pos*2;
+ if VS > 24 then
+ begin
+ if Angle < 0 then helper:=-1 else helper:=1;
+ Angle:=2*pi-abs(Angle);
+ Angle:=Angle*(VS/24);
+ Angle:=(2*pi-Angle)*helper;
+ end;
+
+ Button[B].Z := (0.4 - Abs(Pos/4)) -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
+
+ Button[B].H :=0.6*(Theme.Song.Cover.H-Abs(Theme.Song.Cover.H * cos(Angle/2)*0.8));//Power(Z2, 3);
+
+ Button[B].W := Button[B].H;
+
+ Button[B].Y := Theme.Song.Cover.Y - (Button[B].H - Theme.Song.Cover.H)*0.75;
+
+ //Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+ Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+
+ Diff := (Button[B].H - Theme.Song.Cover.H)/2;
+
+ Button[B].X := Theme.Song.Cover.X+Theme.Song.Cover.H/2-Button[b].H/2+Theme.Song.Cover.W/320*((Theme.Song.Cover.H)*sin(Angle/2)*1.52);
+
+ end;
+
+ //Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Button[B].H)/1.5); //Cover at down border of the change field
+ //Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Button[B].H) * 0.7);
+
+ end;
+ end;
+end;
+
+procedure TScreenSong.SetScroll6; // rotate (slotmachine style)
+var
+ B: integer;
+ Angle: real;
+ Pos: Real;
+ VS: integer;
+ diff: real;
+ X: Real;
+ Wsp: real;
+ Z, Z2: real;
+begin
+ VS := CatSongs.VisibleSongs; // cache Visible Songs
+ if VS <=5 then begin
+ // kolowe
+ for B := 0 to High(Button) do
+ begin
+ Button[B].Visible := CatSongs.Song[B].Visible; // nowe
+ if Button[B].Visible then begin // 0.5.0 optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed
+
+ Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / VS {CatSongs.VisibleSongs};// 0.5.0 (II): takes another 16ms
+
+ Z := (1 + cos(Wsp)) / 2;
+ Z2 := (1 + 2*Z) / 3;
+
+
+ Button[B].Y := Theme.Song.Cover.Y + (0.185 * Theme.Song.Cover.H * VS * sin(Wsp)) * Z2 - ((Button[B].H - Theme.Song.Cover.H)/2); // 0.5.0 (I): 2 times faster by not calling CatSongs.VisibleSongs
+ Button[B].Z := Z / 2 + 0.3;
+
+ Button[B].W := Theme.Song.Cover.H * Z2;
+
+ //Button[B].Y := {50 +} 140 + 50 - 50 * Z2;
+ Button[B].X := Theme.Song.Cover.X + (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7 ;
+ Button[B].H := Button[B].W;
+ end;
+ end;
+ end
+ else begin
+
+ //Change Pos of all Buttons
+ for B := low(Button) to high(Button) do
+ begin
+ Button[B].Visible := CatSongs.Song[B].Visible; //Adjust Visibility
+ if Button[B].Visible then //Only Change Pos for Visible Buttons
+ begin
+ Pos := (CatSongs.VisibleIndex(B) - SongCurrent);
+ if (Pos < -VS/2) then
+ Pos := Pos + VS
+ else if (Pos > VS/2) then
+ Pos := Pos - VS;
+
+ if (Abs(Pos) < 2.5) then {fixed Positions}
+ begin
+ Angle := Pi * (Pos / 5);
+ //Button[B].Visible := False;
+
+ Button[B].H := Abs(Theme.Song.Cover.H * cos(Angle*0.8));//Power(Z2, 3);
+
+ Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+
+ Button[B].Z := 0.95 - Abs(Pos) * 0.01;
+
+ Button[B].X := (Theme.Song.Cover.X + (Theme.Song.Cover.H - Abs(Theme.Song.Cover.H * cos(Angle))) * 0.5);
+
+ Button[B].W := Button[B].H;
+
+ Diff := (Button[B].H - Theme.Song.Cover.H)/2;
+
+
+ X := Sin(Angle*1.3)*0.9;
+
+ Button[B].Y := Theme.Song.Cover.Y + Theme.Song.Cover.W * X - Diff;
+ end
+ else
+ begin {Behind the Front Covers}
+
+ // limit-bg-covers hack
+ if (abs(VS/2-abs(Pos))>10) then Button[B].Visible:=False;
+ if VS > 25 then VS:=25;
+ // end of limit-bg-covers hack
+
+ if Pos < 0 then
+ Pos := (Pos - VS/2)/VS
+ else
+ Pos := (Pos + VS/2)/VS;
+
+ Angle := Pi * Pos*2;
+
+ Button[B].Z := (0.4 - Abs(Pos/4)) -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
+
+ Button[B].H :=0.6*(Theme.Song.Cover.H-Abs(Theme.Song.Cover.H * cos(Angle/2)*0.8));//Power(Z2, 3);
+
+ Button[B].W := Button[B].H;
+
+ Button[B].X := Theme.Song.Cover.X - (Button[B].H - Theme.Song.Cover.H)*0.5;
+
+
+ Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+
+ Button[B].Y := Theme.Song.Cover.Y+Theme.Song.Cover.H/2-Button[b].H/2+Theme.Song.Cover.W/320*(Theme.Song.Cover.H*sin(Angle/2)*1.52);
+ end;
+ end;
+ end;
+ end;
+end;
+
+
+procedure TScreenSong.onShow;
+begin
+ inherited;
+
+ AudioPlayback.Stop;
+
+ if Ini.Players <= 3 then PlayersPlay := Ini.Players + 1;
+ if Ini.Players = 4 then PlayersPlay := 6;
+
+ //Cat Mod etc
+ if (Ini.Tabs_at_startup = 1) and (CatSongs.CatNumShow = -1) then
+ begin
+ CatSongs.ShowCategoryList;
+ FixSelected;
+ //Show Cat in Top Left Mod
+ HideCatTL;
+ end;
+
+ if Length(CatSongs.Song) > 0 then
+ begin
+ //Load Music only when Song Preview is activated
+ if ( Ini.PreviewVolume <> 0 ) then
+ begin // to - do : new Song management
+ StartMusicPreview(CatSongs.Song[Interaction]);
+ end;
+
+ SetScroll;
+ //UpdateLCD; //TODO: maybe LCD Support as Plugin?
+ end;
+
+ //Playlist Mode
+ if (Mode = smNormal) then
+ begin
+ //If Playlist Shown -> Select Next automatically
+ if (CatSongs.CatNumShow = -3) then
+ begin
+ SelectNext;
+ ChangeMusic;
+ end;
+ end
+ //Party Mode
+ else if (Mode = smPartyMode) then
+ begin
+ SelectRandomSong;
+ //Show Menu directly in PartyMode
+ //But only if selected in Options
+ if (Ini.PartyPopup = 1) then
+ begin
+ ScreenSongMenu.MenuShow(SM_Party_Main);
+ end;
+ end;
+
+ SetJoker;
+ SetStatics;
+end;
+
+procedure TScreenSong.onHide;
+begin
+ // if music fading is activated, turn music to 100%
+ If (IPreviewVolumeVals[Ini.PreviewVolume] <> 1.0) or (Ini.PreviewFading <> 0) then
+ AudioPlayback.SetVolume(1.0);
+
+ // if preview is deactivated: load musicfile now
+ If (IPreviewVolumeVals[Ini.PreviewVolume] = 0) then
+ AudioPlayback.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3);
+
+ // if hide then stop music (for party mode popup on exit)
+ if (Display.NextScreen <> @ScreenSing) and
+ (Display.NextScreen <> @ScreenSingModi) then
+ begin
+ if (AudioPlayback <> nil) then
+ AudioPlayback.Stop;
+ end;
+end;
+
+procedure TScreenSong.DrawExtensions;
+begin
+ //Draw Song Menu
+ if (ScreenSongMenu.Visible) then
+ begin
+ ScreenSongMenu.Draw;
+ end
+ else if (ScreenSongJumpto.Visible) then
+ begin
+ ScreenSongJumpto.Draw;
+ end
+end;
+
+function TScreenSong.Draw: boolean;
+var
+ dx: real;
+ dt: real;
+ I: Integer;
+begin
+ dx := SongTarget-SongCurrent;
+ dt := TimeSkip * 7;
+
+ if dt > 1 then
+ dt := 1;
+
+ SongCurrent := SongCurrent + dx*dt;
+
+ {
+ if SongCurrent > Catsongs.VisibleSongs then begin
+ SongCurrent := SongCurrent - Catsongs.VisibleSongs;
+ SongTarget := SongTarget - Catsongs.VisibleSongs;
+ end;
+ }
+
+ //Log.BenchmarkStart(5);
+
+ SetScroll;
+
+ //Log.BenchmarkEnd(5);
+ //Log.LogBenchmark('SetScroll4', 5);
+
+ //Fading Functions, Only if Covertime is under 5 Seconds
+ if (CoverTime < 5) then
+ begin
+ // cover fade
+ if (CoverTime < 1) and (CoverTime + TimeSkip >= 1) then
+ begin
+ // load new texture
+ Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
+ Button[Interaction].Texture.Alpha := 1;
+ Button[Interaction].Texture2 := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
+ Button[Interaction].Texture2.Alpha := 1;
+ end;
+
+ //Song Fade
+ if (CatSongs.VisibleSongs > 0) and
+ (not CatSongs.Song[Interaction].Main) and
+ (Ini.PreviewVolume <> 0) and
+ (Ini.PreviewFading <> 0) then
+ begin
+ //Start Song Fade after a little Time, to prevent Song to be Played on Scrolling
+ if ((MusicStartTime > 0) and (SDL_GetTicks() >= MusicStartTime)) then
+ begin
+ MusicStartTime := 0;
+ StartMusicPreview(CatSongs.Song[Interaction]);
+ end;
+ end;
+
+
+ //Update Fading Time
+ CoverTime := CoverTime + TimeSkip;
+
+ //Update Fading Texture
+ Button[Interaction].Texture2.Alpha := (CoverTime - 1) * 1.5;
+ if Button[Interaction].Texture2.Alpha > 1 then
+ Button[Interaction].Texture2.Alpha := 1;
+
+ end;
+
+ //inherited Draw;
+ //heres a little Hack, that causes the Statics
+ //are Drawn after the Buttons because of some Blending Problems.
+ //This should cause no Problems because all Buttons on this screen
+ //Has Z Position.
+ //Draw BG
+ DrawBG;
+
+ //Instead of Draw FG Procedure:
+ //We draw Buttons for our own
+ for I := 0 to Length(Button) - 1 do
+ Button[I].Draw;
+
+ // Statics
+ for I := 0 to Length(Static) - 1 do
+ Static[I].Draw;
+
+ // and texts
+ for I := 0 to Length(Text) - 1 do
+ Text[I].Draw;
+
+
+ //Draw Equalizer
+ if Theme.Song.Equalizer.Visible then
+ DrawEqualizer;
+
+ DrawExtensions;
+
+ Result := true;
+end;
+
+procedure TScreenSong.SelectNext;
+var
+ Skip: integer;
+ VS: Integer;
+begin
+ VS := CatSongs.VisibleSongs;
+
+ if VS > 0 then
+ begin
+ UnLoadDetailedCover;
+
+ Skip := 1;
+
+ // this 1 could be changed by CatSongs.FindNextVisible
+ while (not CatSongs.Song[(Interaction + Skip) mod Length(Interactions)].Visible) do
+ Inc(Skip);
+
+ SongTarget := SongTarget + 1;//Skip;
+
+ Interaction := (Interaction + Skip) mod Length(Interactions);
+
+ // try to keep all at the beginning
+ if SongTarget > VS-1 then begin
+ SongTarget := SongTarget - VS;
+ SongCurrent := SongCurrent - VS;
+ end;
+
+ end;
+
+ // Interaction -> Button, ktorego okladke przeczytamy
+ //Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false); // 0.5.0: show uncached texture
+end;
+
+procedure TScreenSong.SelectPrev;
+var
+ Skip: integer;
+ VS: Integer;
+begin
+ VS := CatSongs.VisibleSongs;
+
+ if VS > 0 then
+ begin
+ UnLoadDetailedCover;
+
+ Skip := 1;
+
+ while (not CatSongs.Song[(Interaction - Skip + Length(Interactions)) mod Length(Interactions)].Visible) do Inc(Skip);
+ SongTarget := SongTarget - 1;//Skip;
+
+ Interaction := (Interaction - Skip + Length(Interactions)) mod Length(Interactions);
+
+ // try to keep all at the beginning
+ if SongTarget < 0 then begin
+ SongTarget := SongTarget + CatSongs.VisibleSongs;
+ SongCurrent := SongCurrent + CatSongs.VisibleSongs;
+ end;
+
+ // Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false); // 0.5.0: show uncached texture
+ end;
+end;
+
+(*
+procedure TScreenSong.UpdateLCD; //TODO: maybe LCD Support as Plugin?
+begin
+ LCD.HideCursor;
+ LCD.Clear;
+ LCD.WriteText(1, Text[TextArtist].Text);
+ LCD.WriteText(2, Text[TextTitle].Text);
+
+end;
+*)
+
+procedure TScreenSong.StartMusicPreview(Song: TSong);
+begin
+ AudioPlayback.Close();
+
+ if not assigned(Song) then
+ Exit;
+
+ if AudioPlayback.Open(Song.Path + Song.Mp3) then
+ begin
+ AudioPlayback.Position := AudioPlayback.Length / 4;
+ // set preview volume
+ if (Ini.PreviewFading = 0) then
+ begin
+ // music fade disabled: start with full volume
+ AudioPlayback.SetVolume(IPreviewVolumeVals[Ini.PreviewVolume]);
+ AudioPlayback.Play()
+ end
+ else
+ begin
+ // music fade enabled: start muted and fade-in
+ AudioPlayback.SetVolume(0);
+ AudioPlayback.FadeIn(Ini.PreviewFading, IPreviewVolumeVals[Ini.PreviewVolume]);
+ end;
+ end;
+end;
+
+//Procedure Change current played Preview
+procedure TScreenSong.ChangeMusic;
+begin
+ //When Music Preview is avtivated -> then Change Music
+ if (Ini.PreviewVolume <> 0) then
+ begin
+ // Stop previous song
+ AudioPlayback.Stop;
+ // Disable music start delay
+ MusicStartTime := 0;
+
+ if (CatSongs.VisibleSongs > 0) then
+ begin
+ // delay start of music for 200ms (see Draw())
+ MusicStartTime := SDL_GetTicks() + 200;
+ end;
+ end;
+end;
+
+procedure TScreenSong.SkipTo(Target: Cardinal);
+var
+ i: integer;
+begin
+ UnLoadDetailedCover;
+
+ Interaction := High(CatSongs.Song);
+ SongTarget := 0;
+
+ for i := 1 to Target+1 do
+ SelectNext;
+
+ FixSelected2;
+end;
+
+procedure TScreenSong.DrawEqualizer;
+var
+ I, J: Integer;
+ ChansPerBand: byte; // channels per band
+ MaxChannel: Integer;
+ CurBand: Integer; // current band
+ CurTime: Cardinal;
+ PosX, PosY: Integer;
+ Pos: Real;
+begin
+ // Nothing to do if no music is played or an equalizer bar consists of no block
+ if (AudioPlayback.Finished or (Theme.Song.Equalizer.Length <= 0)) then
+ Exit;
+
+ CurTime := SDL_GetTicks();
+
+ // Evaluate FFT-data every 44 ms
+ if (CurTime >= EqualizerTime) then
+ begin
+ EqualizerTime := CurTime + 44;
+ AudioPlayback.GetFFTData(EqualizerData);
+
+ Pos := 0;
+ // use only the first approx. 92 of 256 FFT-channels (approx. up to 8kHz
+ ChansPerBand := ceil(92 / Theme.Song.Equalizer.Bands); // How much channels are used for one Band
+ MaxChannel := ChansPerBand * Theme.Song.Equalizer.Bands - 1;
+
+ // Change Lengths
+ for i := 0 to MaxChannel do
+ begin
+ // Gain higher freq. data so that the bars are visible
+ if i > 35 then
+ EqualizerData[i] := EqualizerData[i] * 8
+ else if i > 11 then
+ EqualizerData[i] := EqualizerData[i] * 4.5
+ else
+ EqualizerData[i] := EqualizerData[i] * 1.1;
+
+ // clamp data
+ if (EqualizerData[i] > 1) then
+ EqualizerData[i] := 1;
+
+ // Get max. pos
+ if (EqualizerData[i] * Theme.Song.Equalizer.Length > Pos) then
+ Pos := EqualizerData[i] * Theme.Song.Equalizer.Length;
+
+ // Check if this is the last channel in the band
+ if ((i+1) mod ChansPerBand = 0) then
+ begin
+ CurBand := i div ChansPerBand;
+
+ // Smooth delay if new equalizer is lower than the old one
+ if ((EqualizerBands[CurBand] > Pos) and (EqualizerBands[CurBand] > 1)) then
+ EqualizerBands[CurBand] := EqualizerBands[CurBand] - 1
+ else
+ EqualizerBands[CurBand] := Round(Pos);
+
+ Pos := 0;
+ end;
+ end;
+
+ end;
+
+ // Draw equalizer bands
+
+ // Setup OpenGL
+ glColor4f(Theme.Song.Equalizer.ColR, Theme.Song.Equalizer.ColG, Theme.Song.Equalizer.ColB, Theme.Song.Equalizer.Alpha);
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+
+ // Set position of the first equalizer bar
+ PosY := Theme.Song.Equalizer.Y;
+ PosX := Theme.Song.Equalizer.X;
+
+ // Draw bars for each band
+ for I := 0 to High(EqualizerBands) do
+ begin
+ // Reset to lower or left position depending on the drawing-direction
+ if Theme.Song.Equalizer.Direction then // Vertical bars
+ // FIXME: Is Theme.Song.Equalizer.Y the upper or lower coordinate?
+ PosY := Theme.Song.Equalizer.Y //+ (Theme.Song.Equalizer.H + Theme.Song.Equalizer.Space) * Theme.Song.Equalizer.Length
+ else // Horizontal bars
+ PosX := Theme.Song.Equalizer.X;
+
+ // Draw the bar as a stack of blocks
+ for J := 1 to EqualizerBands[I] do
+ begin
+ // Draw block
+ glBegin(GL_QUADS);
+ glVertex3f(PosX, PosY, Theme.Song.Equalizer.Z);
+ glVertex3f(PosX, PosY+Theme.Song.Equalizer.H, Theme.Song.Equalizer.Z);
+ glVertex3f(PosX+Theme.Song.Equalizer.W, PosY+Theme.Song.Equalizer.H, Theme.Song.Equalizer.Z);
+ glVertex3f(PosX+Theme.Song.Equalizer.W, PosY, Theme.Song.Equalizer.Z);
+ glEnd;
+
+ // Calc position of the bar's next block
+ if Theme.Song.Equalizer.Direction then // Vertical bars
+ PosY := PosY - Theme.Song.Equalizer.H - Theme.Song.Equalizer.Space
+ else // Horizontal bars
+ PosX := PosX + Theme.Song.Equalizer.W + Theme.Song.Equalizer.Space;
+ end;
+
+ // Calc position of the next bar
+ if Theme.Song.Equalizer.Direction then // Vertical bars
+ PosX := PosX + Theme.Song.Equalizer.W + Theme.Song.Equalizer.Space
+ else // Horizontal bars
+ PosY := PosY + Theme.Song.Equalizer.H + Theme.Song.Equalizer.Space;
+ end;
+end;
+
+procedure TScreenSong.SelectRandomSong;
+var
+ I, I2: Integer;
+begin
+ case PlaylistMan.Mode of
+ smNormal: //All Songs Just Select Random Song
+ begin
+ //When Tabs are activated then use Tab Method
+ if (Ini.Tabs_at_startup = 1) then
+ begin
+ repeat
+ I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1;
+ until CatSongs.Song[I2].Main = false;
+
+ //Search Cat
+ for I := I2 downto low(CatSongs.Song) do
+ begin
+ if CatSongs.Song[I].Main then
+ break;
+ end;
+ //In I ist jetzt die Kategorie in I2 der Song
+ //I is the CatNum, I2 is the No of the Song within this Cat
+
+ //Choose Cat
+ CatSongs.ShowCategoryList;
+
+ //Show Cat in Top Left Mod
+ ShowCatTL (I);
+
+ CatSongs.ClickCategoryButton(I);
+ SelectNext;
+
+ //Choose Song
+ SkipTo(I2-I);
+ end
+ //When Tabs are deactivated use easy Method
+ else
+ SkipTo(Random(CatSongs.VisibleSongs));
+ end;
+ smPartyMode: //One Category Select Category and Select Random Song
+ begin
+ CatSongs.ShowCategoryList;
+ CatSongs.ClickCategoryButton(PlaylistMan.CurPlayList);
+ ShowCatTL(PlaylistMan.CurPlayList);
+
+ SelectNext;
+ FixSelected2;
+
+ SkipTo(Random(CatSongs.VisibleSongs));
+ end;
+ smPlaylistRandom: //Playlist: Select Playlist and Select Random Song
+ begin
+ PlaylistMan.SetPlayList(PlaylistMan.CurPlayList);
+
+ SkipTo(Random(CatSongs.VisibleSongs));
+ FixSelected2;
+ end;
+ end;
+
+ AudioPlayback.PlaySound(SoundLib.Change);
+ ChangeMusic;
+ SetScroll;
+ //UpdateLCD; //TODO: maybe LCD Support as Plugin?
+end;
+
+procedure TScreenSong.SetJoker;
+begin
+ // If Party Mode
+ // to-do : Party
+ if Mode = smPartyMode then //Show Joker that are available
+ begin
+ (*
+ if (PartySession.Teams.NumTeams >= 1) then
+ begin
+ Static[StaticTeam1Joker1].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 1);
+ Static[StaticTeam1Joker2].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 2);
+ Static[StaticTeam1Joker3].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 3);
+ Static[StaticTeam1Joker4].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 4);
+ Static[StaticTeam1Joker5].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 5);
+ end
+ else
+ begin
+ Static[StaticTeam1Joker1].Visible := False;
+ Static[StaticTeam1Joker2].Visible := False;
+ Static[StaticTeam1Joker3].Visible := False;
+ Static[StaticTeam1Joker4].Visible := False;
+ Static[StaticTeam1Joker5].Visible := False;
+ end;
+
+ if (PartySession.Teams.NumTeams >= 2) then
+ begin
+ Static[StaticTeam2Joker1].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 1);
+ Static[StaticTeam2Joker2].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 2);
+ Static[StaticTeam2Joker3].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 3);
+ Static[StaticTeam2Joker4].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 4);
+ Static[StaticTeam2Joker5].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 5);
+ end
+ else
+ begin
+ Static[StaticTeam2Joker1].Visible := False;
+ Static[StaticTeam2Joker2].Visible := False;
+ Static[StaticTeam2Joker3].Visible := False;
+ Static[StaticTeam2Joker4].Visible := False;
+ Static[StaticTeam2Joker5].Visible := False;
+ end;
+
+ if (PartySession.Teams.NumTeams >= 3) then
+ begin
+ Static[StaticTeam3Joker1].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 1);
+ Static[StaticTeam3Joker2].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 2);
+ Static[StaticTeam3Joker3].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 3);
+ Static[StaticTeam3Joker4].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 4);
+ Static[StaticTeam3Joker5].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 5);
+ end
+ else
+ begin
+ Static[StaticTeam3Joker1].Visible := False;
+ Static[StaticTeam3Joker2].Visible := False;
+ Static[StaticTeam3Joker3].Visible := False;
+ Static[StaticTeam3Joker4].Visible := False;
+ Static[StaticTeam3Joker5].Visible := False;
+ end;
+ *)
+ end
+ else
+ begin //Hide all
+ Static[StaticTeam1Joker1].Visible := False;
+ Static[StaticTeam1Joker2].Visible := False;
+ Static[StaticTeam1Joker3].Visible := False;
+ Static[StaticTeam1Joker4].Visible := False;
+ Static[StaticTeam1Joker5].Visible := False;
+
+ Static[StaticTeam2Joker1].Visible := False;
+ Static[StaticTeam2Joker2].Visible := False;
+ Static[StaticTeam2Joker3].Visible := False;
+ Static[StaticTeam2Joker4].Visible := False;
+ Static[StaticTeam2Joker5].Visible := False;
+
+ Static[StaticTeam3Joker1].Visible := False;
+ Static[StaticTeam3Joker2].Visible := False;
+ Static[StaticTeam3Joker3].Visible := False;
+ Static[StaticTeam3Joker4].Visible := False;
+ Static[StaticTeam3Joker5].Visible := False;
+ end;
+end;
+
+procedure TScreenSong.SetStatics;
+var
+ I: Integer;
+ Visible: Boolean;
+begin
+ //Set Visibility of Party Statics and Text
+ Visible := (Mode = smPartyMode);
+
+ for I := 0 to high(StaticParty) do
+ Static[StaticParty[I]].Visible := Visible;
+
+ for I := 0 to high(TextParty) do
+ Text[TextParty[I]].Visible := Visible;
+
+ //Set Visibility of Non Party Statics and Text
+ Visible := not Visible;
+
+ for I := 0 to high(StaticNonParty) do
+ Static[StaticNonParty[I]].Visible := Visible;
+
+ for I := 0 to high(TextNonParty) do
+ Text[TextNonParty[I]].Visible := Visible;
+end;
+
+//Procedures for Menu
+
+procedure TScreenSong.StartSong;
+begin
+ CatSongs.Selected := Interaction;
+ AudioPlayback.Stop;
+ //Party Mode
+ if (Mode = smPartyMode) then
+ begin
+ FadeTo(@ScreenSingModi);
+ end
+ else
+ begin
+ FadeTo(@ScreenSing);
+ end;
+end;
+
+procedure TScreenSong.SelectPlayers;
+begin
+ CatSongs.Selected := Interaction;
+ AudioPlayback.Stop;
+
+ ScreenName.Goto_SingScreen := True;
+ FadeTo(@ScreenName);
+end;
+
+procedure TScreenSong.OpenEditor;
+begin
+ if (Songs.SongList.Count > 0) and
+ (not CatSongs.Song[Interaction].Main) and
+ (Mode = smNormal) then
+ begin
+ AudioPlayback.Stop;
+ AudioPlayback.PlaySound(SoundLib.Start);
+ CurrentSong := CatSongs.Song[Interaction];
+ FadeTo(@ScreenEditSub);
+ end;
+end;
+
+//Team No of Team (0-5)
+procedure TScreenSong.DoJoker (Team: Byte);
+begin
+ {
+ if (Mode = smPartyMode) and
+ (PartySession.Teams.NumTeams >= Team + 1) and
+ (PartySession.Teams.Teaminfo[Team].Joker > 0) then
+ begin
+ //Use Joker
+ Dec(PartySession.Teams.Teaminfo[Team].Joker);
+ SelectRandomSong;
+ SetJoker;
+ end;
+ }
+end;
+
+//Detailed Cover Unloading. Unloads the Detailed, uncached Cover of the cur. Song
+procedure TScreenSong.UnLoadDetailedCover;
+begin
+ CoverTime := 0;
+
+ // show cached texture
+ Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, true);
+ Button[Interaction].Texture2.Alpha := 0;
+
+ if Button[Interaction].Texture.Name <> Skin.GetTextureFileName('SongCover') then
+ Texture.UnloadTexture(Button[Interaction].Texture.Name, TEXTURE_TYPE_PLAIN, false);
+end;
+
+procedure TScreenSong.Refresh;
+begin
+ {
+ CatSongs.Refresh;
+ CatSongs.ShowCategoryList;
+ Interaction := 0;
+ SelectNext;
+ FixSelected;
+ }
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenStatDetail.pas b/Game/Code/Screens/UScreenStatDetail.pas
index c5c8245f..98faed03 100644
--- a/Game/Code/Screens/UScreenStatDetail.pas
+++ b/Game/Code/Screens/UScreenStatDetail.pas
@@ -1,257 +1,257 @@
-unit UScreenStatDetail;
-
-interface
-
-{$I switches.inc}
-
-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; CharCode: WideChar; 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; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- // check normal keys
- case WideCharUpperCase(CharCode)[1] of
- 'Q':
- begin
- Result := false;
- Exit;
- end;
- end;
-
- // check special keys
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- AudioPlayback.PlaySound(SoundLib.Back);
- 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
- AudioPlayback.PlaySound(SoundLib.Back);
- 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;
-
- 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);
-
- LoadFromTheme(Theme.StatDetail);
-
- 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]);
-
- Interaction := 0;
- Typ := 0;
-end;
-
-procedure TScreenStatDetail.onShow;
-begin
- inherited;
-
- //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.
+unit UScreenStatDetail;
+
+interface
+
+{$I switches.inc}
+
+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; CharCode: WideChar; 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; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ // check normal keys
+ case WideCharUpperCase(CharCode)[1] of
+ 'Q':
+ begin
+ Result := false;
+ Exit;
+ end;
+ end;
+
+ // check special keys
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ AudioPlayback.PlaySound(SoundLib.Back);
+ 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
+ AudioPlayback.PlaySound(SoundLib.Back);
+ 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;
+
+ 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);
+
+ LoadFromTheme(Theme.StatDetail);
+
+ 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]);
+
+ Interaction := 0;
+ Typ := 0;
+end;
+
+procedure TScreenStatDetail.onShow;
+begin
+ inherited;
+
+ //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/UScreenWelcome.pas b/Game/Code/Screens/UScreenWelcome.pas
index 68a6bfff..019e5baf 100644
--- a/Game/Code/Screens/UScreenWelcome.pas
+++ b/Game/Code/Screens/UScreenWelcome.pas
@@ -1,122 +1,122 @@
-unit UScreenWelcome;
-
-interface
-
-{$I switches.inc}
-
-uses
- UMenu, SDL, SysUtils, UThemes;
-
-type
- TScreenWelcome = class(TMenu)
- public
- Animation: real;
- Fadeout: boolean;
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
- function Draw: boolean; override;
- procedure onShow; override;
- end;
-
-implementation
-
-uses UGraphic, UTime, USkins, UTexture;
-
-function TScreenWelcome.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then begin
- case PressedKey of
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- Result := False;
- end;
- SDLK_RETURN:
- begin
- FadeTo(@ScreenMain);
- Fadeout := true;
- end;
- end;
- end;
-end;
-
-constructor TScreenWelcome.Create;
-begin
- inherited Create;
- AddStatic(-10, -10, 0, 0, 1, 1, 1, Skin.GetTextureFileName('ButtonAlt'), TEXTURE_TYPE_TRANSPARENT);
- AddStatic(-500, 440, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
- AddStatic(-500, 472, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
- AddStatic(-500, 504, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
- AddStatic(-500, 536, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
- AddStatic(-500, 568, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
- Animation := 0;
- Fadeout := false;
-end;
-
-procedure TScreenWelcome.onShow;
-begin
- inherited;
-
- CountSkipTimeSet;
-end;
-
-function TScreenWelcome.Draw: boolean;
-var
- Min: real;
- Max: real;
- Wsp: real;
- Pet: integer;
-begin
- // star animation
- Animation := Animation + TimeSkip*1000;
-
- // draw nothing
- Min := 0; Max := 1000;
- if (Animation >= Min) and (Animation < Max) then begin
- end;
-
- // popup
- Min := 1000; Max := 1120;
- if (Animation >= Min) and (Animation < Max) then begin
- Wsp := (Animation - Min) / (Max - Min);
- Static[0].Texture.X := 600;
- Static[0].Texture.Y := 600 - Wsp * 230;
- Static[0].Texture.W := 200;
- Static[0].Texture.H := Wsp * 230;
- end;
-
- // bounce
- Min := 1120; Max := 1200;
- if (Animation >= Min) and (Animation < Max) then begin
- Wsp := (Animation - Min) / (Max - Min);
- Static[0].Texture.Y := 370 + Wsp * 50;
- Static[0].Texture.H := 230 - Wsp * 50;
- end;
-
- // run
- Min := 1500; Max := 3500;
- if (Animation >= Min) and (Animation < Max) then begin
- Wsp := (Animation - Min) / (Max - Min);
-
- Static[0].Texture.X := 600 - Wsp * 1400;
- Static[0].Texture.H := 180;
-
-
- for Pet := 1 to 5 do begin
- Static[Pet].Texture.X := 770 - Wsp * 1400;
- Static[Pet].Texture.W := 150 + Wsp * 200;
- Static[Pet].Texture.Alpha := Wsp * 0.5;
- end;
- end;
-
- Min := 3500;
- if (Animation >= Min) and (not Fadeout) then begin
- FadeTo(@ScreenMain);
- Fadeout := true;
- end;
-
- inherited Draw;
-end;
-
-end.
+unit UScreenWelcome;
+
+interface
+
+{$I switches.inc}
+
+uses
+ UMenu, SDL, SysUtils, UThemes;
+
+type
+ TScreenWelcome = class(TMenu)
+ public
+ Animation: real;
+ Fadeout: boolean;
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+ procedure onShow; override;
+ end;
+
+implementation
+
+uses UGraphic, UTime, USkins, UTexture;
+
+function TScreenWelcome.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then begin
+ case PressedKey of
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ Result := False;
+ end;
+ SDLK_RETURN:
+ begin
+ FadeTo(@ScreenMain);
+ Fadeout := true;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenWelcome.Create;
+begin
+ inherited Create;
+ AddStatic(-10, -10, 0, 0, 1, 1, 1, Skin.GetTextureFileName('ButtonAlt'), TEXTURE_TYPE_TRANSPARENT);
+ AddStatic(-500, 440, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
+ AddStatic(-500, 472, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
+ AddStatic(-500, 504, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
+ AddStatic(-500, 536, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
+ AddStatic(-500, 568, 200, 5, 0, 0, 0, Skin.GetTextureFileName('Rectangle'), TEXTURE_TYPE_COLORIZED);
+ Animation := 0;
+ Fadeout := false;
+end;
+
+procedure TScreenWelcome.onShow;
+begin
+ inherited;
+
+ CountSkipTimeSet;
+end;
+
+function TScreenWelcome.Draw: boolean;
+var
+ Min: real;
+ Max: real;
+ Wsp: real;
+ Pet: integer;
+begin
+ // star animation
+ Animation := Animation + TimeSkip*1000;
+
+ // draw nothing
+ Min := 0; Max := 1000;
+ if (Animation >= Min) and (Animation < Max) then begin
+ end;
+
+ // popup
+ Min := 1000; Max := 1120;
+ if (Animation >= Min) and (Animation < Max) then begin
+ Wsp := (Animation - Min) / (Max - Min);
+ Static[0].Texture.X := 600;
+ Static[0].Texture.Y := 600 - Wsp * 230;
+ Static[0].Texture.W := 200;
+ Static[0].Texture.H := Wsp * 230;
+ end;
+
+ // bounce
+ Min := 1120; Max := 1200;
+ if (Animation >= Min) and (Animation < Max) then begin
+ Wsp := (Animation - Min) / (Max - Min);
+ Static[0].Texture.Y := 370 + Wsp * 50;
+ Static[0].Texture.H := 230 - Wsp * 50;
+ end;
+
+ // run
+ Min := 1500; Max := 3500;
+ if (Animation >= Min) and (Animation < Max) then begin
+ Wsp := (Animation - Min) / (Max - Min);
+
+ Static[0].Texture.X := 600 - Wsp * 1400;
+ Static[0].Texture.H := 180;
+
+
+ for Pet := 1 to 5 do begin
+ Static[Pet].Texture.X := 770 - Wsp * 1400;
+ Static[Pet].Texture.W := 150 + Wsp * 200;
+ Static[Pet].Texture.Alpha := Wsp * 0.5;
+ end;
+ end;
+
+ Min := 3500;
+ if (Animation >= Min) and (not Fadeout) then begin
+ FadeTo(@ScreenMain);
+ Fadeout := true;
+ end;
+
+ inherited Draw;
+end;
+
+end.