aboutsummaryrefslogtreecommitdiffstats
path: root/Medley/src/screens/UScreenSingModi.pas
diff options
context:
space:
mode:
Diffstat (limited to 'Medley/src/screens/UScreenSingModi.pas')
-rw-r--r--Medley/src/screens/UScreenSingModi.pas582
1 files changed, 582 insertions, 0 deletions
diff --git a/Medley/src/screens/UScreenSingModi.pas b/Medley/src/screens/UScreenSingModi.pas
new file mode 100644
index 00000000..48d1e9a1
--- /dev/null
+++ b/Medley/src/screens/UScreenSingModi.pas
@@ -0,0 +1,582 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit UScreenSingModi;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UMenu,
+ UMusic,
+ SDL,
+ SysUtils,
+ UFiles,
+ UTime,
+ USongs,
+ UIni,
+ ULog,
+ UTexture,
+ ULyrics,
+ TextGL,
+ gl,
+ UPath,
+ UThemes,
+ UScreenSing,
+ ModiSDK;
+
+type
+ TScreenSingModi = class(TScreenSing)
+ protected
+
+ public
+ Winner: byte; //Who Wins
+ PlayerInfo: TPlayerInfo;
+ TeamInfo: TTeamInfo;
+
+ constructor Create; override;
+ procedure OnShow; override;
+ //procedure onShowFinish; override;
+ function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; override;
+ function Draw: boolean; override;
+ procedure Finish; override;
+ end;
+
+type
+ TCustomSoundEntry = record
+ Filename : IPath;
+ Stream : TAudioPlaybackStream;
+ end;
+
+var
+ //Custom Sounds
+ CustomSounds: array of TCustomSoundEntry;
+
+//Procedured for Plugin
+function LoadTex(const Name: PChar; Typ: TTextureType): TsmallTexture;
+ {$IFDEF MSWINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
+//function Translate (const Name: PChar): PChar;
+// {$IFDEF MSWINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
+//Procedure to Print Text
+procedure Print(const Style, Size: byte; const X, Y: real; const Text: PChar);
+ {$IFDEF MSWINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
+//Procedure that loads a Custom Sound
+function LoadSound(const Name: PChar): cardinal;
+ {$IFDEF MSWINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
+//Plays a Custom Sound
+procedure PlaySound(const Index: cardinal);
+ {$IFDEF MSWINDOWS} stdcall; {$ELSE} cdecl; {$ENDIF}
+
+//Utilys
+function ToSentences(Const Lines: TLines): TSentences;
+
+implementation
+
+uses
+ Classes,
+ Math,
+ UDLLManager,
+ UDraw,
+ UGraphic,
+ UGraphicClasses,
+ ULanguage,
+ UNote,
+ UPathUtils,
+ URecord,
+ USkins;
+
+// Method for input parsing. If false is returned, GetNextWindow
+// should be checked to know the next window to load;
+function TScreenSingModi.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean;
+begin
+ Result := true;
+ if (PressedDown) then
+ begin // Key Down
+ case PressedKey of
+
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ Finish;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeTo(@ScreenPartyScore);
+ end;
+
+ else
+ Result := inherited ParseInput(PressedKey, CharCode, PressedDown);
+ end;
+ end;
+end;
+
+constructor TScreenSingModi.Create;
+begin
+ inherited Create;
+
+end;
+
+function ToSentences(Const Lines: TLines): TSentences;
+var
+ I, J: integer;
+begin
+ Result.Current := Lines.Current;
+ Result.High := Lines.High;
+ Result.Number := Lines.Number;
+ Result.Resolution := Lines.Resolution;
+ Result.NotesGAP := Lines.NotesGAP;
+ Result.TotalLength := Lines.ScoreValue;
+
+ SetLength(Result.Sentence, Length(Lines.Line));
+ for I := low(Result.Sentence) to high(Result.Sentence) do
+ begin
+ Result.Sentence[I].Start := Lines.Line[I].Start;
+ Result.Sentence[I].StartNote := Lines.Line[I].Note[0].Start;
+ Result.Sentence[I].Lyric := Lines.Line[I].Lyric;
+ Result.Sentence[I].End_ := Lines.Line[I].End_;
+ Result.Sentence[I].BaseNote := Lines.Line[I].BaseNote;
+ Result.Sentence[I].HighNote := Lines.Line[I].HighNote;
+ Result.Sentence[I].TotalNotes := Lines.Line[I].TotalNotes;
+
+ SetLength(Result.Sentence[I].Note, Length(Lines.Line[I].Note));
+ for J := low(Result.Sentence[I].Note) to high(Result.Sentence[I].Note) do
+ begin
+ Result.Sentence[I].Note[J].Color := Lines.Line[I].Note[J].Color;
+ Result.Sentence[I].Note[J].Start := Lines.Line[I].Note[J].Start;
+ Result.Sentence[I].Note[J].Length := Lines.Line[I].Note[J].Length;
+ Result.Sentence[I].Note[J].Tone := Lines.Line[I].Note[J].Tone;
+ //Result.Sentence[I].Note[J].Text := Lines.Line[I].Note[J].Text;
+ Result.Sentence[I].Note[J].FreeStyle := (Lines.Line[I].Note[J].NoteType = ntFreestyle);
+ end;
+ end;
+end;
+
+procedure TScreenSingModi.OnShow;
+var
+ I: integer;
+begin
+ inherited;
+
+ PlayersPlay := TeamInfo.NumTeams;
+
+ if DLLMan.Selected.LoadSong then //Start with Song
+ begin
+ inherited;
+ end
+ else //Start Without Song
+ begin
+ AudioInput.CaptureStart;
+ end;
+
+//Set Playerinfo
+ PlayerInfo.NumPlayers := PlayersPlay;
+ for I := 0 to PlayerInfo.NumPlayers-1 do
+ begin
+ PlayerInfo.Playerinfo[I].Name := PChar(Ini.Name[I]);
+ PlayerInfo.Playerinfo[I].Score := 0;
+ PlayerInfo.Playerinfo[I].Bar := 50;
+ PlayerInfo.Playerinfo[I].Enabled := true;
+ end;
+
+ for I := PlayerInfo.NumPlayers to high(PlayerInfo.Playerinfo) do
+ begin
+ PlayerInfo.Playerinfo[I].Score:= 0;
+ PlayerInfo.Playerinfo[I].Bar := 0;
+ PlayerInfo.Playerinfo[I].Enabled := false;
+ end;
+
+ {Case PlayersPlay of
+ 1: begin
+ PlayerInfo.Playerinfo[0].PosX := Static[StaticP1ScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ScoreBG].Texture.Y + Static[StaticP1ScoreBG].Texture.H;
+ end;
+ 2,4: begin
+ PlayerInfo.Playerinfo[0].PosX := Static[StaticP1TwoPScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[0].PosY := Static[StaticP1TwoPScoreBG].Texture.Y + Static[StaticP1TwoPScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[2].PosX := Static[StaticP1TwoPScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[2].PosY := Static[StaticP1TwoPScoreBG].Texture.Y + Static[StaticP1TwoPScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[1].PosX := Static[StaticP2RScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[1].PosY := Static[StaticP2RScoreBG].Texture.Y + Static[StaticP2RScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[3].PosX := Static[StaticP2RScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[3].PosY := Static[StaticP2RScoreBG].Texture.Y + Static[StaticP2RScoreBG].Texture.H;
+ end;
+ 3,6: begin
+ PlayerInfo.Playerinfo[0].PosX := Static[StaticP1ThreePScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ThreePScoreBG].Texture.Y + Static[StaticP1ThreePScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[3].PosX := Static[StaticP1ThreePScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[3].PosY := Static[StaticP1ThreePScoreBG].Texture.Y + Static[StaticP1ThreePScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[1].PosX := Static[StaticP2MScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[1].PosY := Static[StaticP2MScoreBG].Texture.Y + Static[StaticP2MScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[4].PosX := Static[StaticP2MScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[4].PosY := Static[StaticP2MScoreBG].Texture.Y + Static[StaticP2MScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[2].PosX := Static[StaticP3RScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[2].PosY := Static[StaticP3RScoreBG].Texture.Y + Static[StaticP3RScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[5].PosX := Static[StaticP3RScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[5].PosY := Static[StaticP3RScoreBG].Texture.Y + Static[StaticP3RScoreBG].Texture.H;
+ end;
+ end; }
+
+ // play music (I)
+ //Music.CaptureStart;
+ //Music.MoveTo(AktSong.Start);
+
+ //Init Plugin
+ if not DLLMan.PluginInit(TeamInfo, PlayerInfo, ToSentences(Lines[0]), LoadTex, Print, LoadSound, PlaySound) then
+ begin
+ //Fehler
+ Log.LogError('Could not Init Plugin');
+ Halt;
+ end;
+
+ // Set Background (Little Workaround, maybe change sometime)
+ if (DLLMan.Selected.LoadBack) and (DLLMan.Selected.LoadSong) then
+ ScreenSing.Tex_Background := Tex_Background;
+
+ Winner := 0;
+
+ //Set Score Visibility
+ Scores.Visible := DLLMan.Selected.ShowScore;
+
+ {if PlayersPlay = 1 then
+ begin
+ Text[TextP1Score].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP1ScoreBG].Visible := DLLMan.Selected.ShowScore;
+ end;
+
+ if (PlayersPlay = 2) or (PlayersPlay = 4) then
+ begin
+ Text[TextP1TwoPScore].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP1TwoPScoreBG].Visible := DLLMan.Selected.ShowScore;
+
+ Text[TextP2RScore].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP2RScoreBG].Visible := DLLMan.Selected.ShowScore;
+ end;
+
+ if (PlayersPlay = 3) or (PlayersPlay = 6) then
+ begin
+ Text[TextP1ThreePScore].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP1ThreePScoreBG].Visible := DLLMan.Selected.ShowScore;
+
+ Text[TextP2MScore].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP2MScoreBG].Visible := DLLMan.Selected.ShowScore;
+
+ Text[TextP3RScore].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP3RScoreBG].Visible := DLLMan.Selected.ShowScore;
+ end; }
+end;
+
+function TScreenSingModi.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ TextStr: string;
+ S, I: integer;
+ T: integer;
+ CurLyricsTime: real;
+begin
+ Result := false;
+
+ //Set Playerinfo
+ PlayerInfo.NumPlayers := PlayersPlay;
+ for I := 0 to PlayerInfo.NumPlayers-1 do
+ begin
+ PlayerInfo.Playerinfo[I].Name := PChar(Player[I].Name);
+ if PlayerInfo.Playerinfo[I].Enabled then
+ begin
+ if (Player[I].ScoreTotalInt <= MAX_SONG_SCORE) then
+ PlayerInfo.Playerinfo[I].Score:= Player[I].ScoreTotalInt;
+ PlayerInfo.Playerinfo[I].Bar := Round(Scores.Players[I].RBPos * 100);
+ end;
+ end;
+
+ Background.Draw;
+
+ // draw background picture (if any, and if no visualizations)
+ // when we don't check for visualizations the visualizations would
+ // be overdrawn by the picture when {UNDEFINED UseTexture} in UVisualizer
+ if (DllMan.Selected.LoadSong) and (DllMan.Selected.LoadBack) and (not fShowVisualization) then
+ SingDrawBackground;
+
+ // set player names (for 2 screens and only Singstar skin)
+ if ScreenAct = 1 then
+ begin
+ Text[TextP1].Text := 'P1';
+ Text[TextP1TwoP].Text := 'P1'; // added for ps3 skin
+ Text[TextP1ThreeP].Text := 'P1'; // added for ps3 skin
+ Text[TextP2R].Text := 'P2';
+ Text[TextP2M].Text := 'P2';
+ Text[TextP3R].Text := 'P3';
+ end
+
+ Else if ScreenAct = 2 then
+ begin
+ case PlayersPlay of
+ 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
+
+ // stereo <- and where iss P2M? or P3?
+ 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;
+
+ for S := 1 to 1 do
+ Static[S].Texture.X := Static[S].Texture.X + 10*ScreenX;
+
+ for T := 0 to 1 do
+ Text[T].X := Text[T].X + 10*ScreenX;
+
+ if DLLMan.Selected.LoadSong then
+ begin
+ // update static menu with time ...
+ CurLyricsTime := LyricsState.GetCurrentTime();
+ Min := Round(CurLyricsTime) div 60;
+ Sec := Round(CurLyricsTime) 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);
+ end;
+
+ // update and draw movie
+{ if ShowFinish and CurrentSong.VideoLoaded and DllMan.Selected.LoadVideo then
+ begin
+ UpdateSmpeg; // this only draws
+ end;}
+
+ // update and draw movie
+ if (ShowFinish and (VideoLoaded or fShowVisualization) and DllMan.Selected.LoadVideo) then
+ begin
+ if assigned(fCurrentVideoPlaybackEngine) then
+ begin
+ // Just call this once
+ // when Screens = 2
+ if (ScreenAct = 1) then
+ fCurrentVideoPlaybackEngine.GetFrame(CurrentSong.VideoGAP + LyricsState.GetCurrentTime());
+
+ fCurrentVideoPlaybackEngine.DrawGL(ScreenAct);
+ end;
+ end;
+
+ // draw static menu (FG)
+ DrawFG;
+
+ if ShowFinish then
+ begin
+ if DllMan.Selected.LoadSong then
+ begin
+ if (not AudioPlayback.Finished) and ((CurrentSong.Finish = 0) or (LyricsState.GetCurrentTime*1000 <= CurrentSong.Finish)) then
+ begin
+ //Pause Mod:
+ if not Paused then
+ Sing(Self); // analyze song
+ end
+ else
+ begin
+ if not FadeOut then
+ begin
+ Finish;
+ FadeOut := true;
+ FadeTo(@ScreenPartyScore);
+ end;
+ end;
+ end;
+ end;
+
+ // draw custom items
+ SingModiDraw(PlayerInfo); // always draw
+
+ //GoldenNoteStarsTwinkle Mod
+ GoldenRec.SpawnRec;
+ //GoldenNoteStarsTwinkle Mod
+
+ //Draw Score
+ Scores.Draw;
+
+ //Update PlayerInfo
+ for I := 0 to PlayerInfo.NumPlayers-1 do
+ begin
+ if PlayerInfo.Playerinfo[I].Enabled then
+ begin
+ //PlayerInfo.Playerinfo[I].Bar := Player[I].ScorePercent;
+ PlayerInfo.Playerinfo[I].Score := Player[I].ScoreTotalInt;
+ end;
+ end;
+
+ if ((ShowFinish) and (not Paused)) then
+ begin
+ if not DLLMan.PluginDraw(Playerinfo, Lines[0].Current) then
+ begin
+ if not FadeOut then
+ begin
+ Finish;
+ FadeOut := true;
+ FadeTo(@ScreenPartyScore);
+ end;
+ end;
+ end;
+
+ //Change PlayerInfo/Changeables
+ for I := 0 to PlayerInfo.NumPlayers-1 do
+ begin
+ if (Player[I].ScoreTotalInt <> PlayerInfo.Playerinfo[I].Score) then
+ begin
+ //Player[I].ScoreTotal := Player[I].ScoreTotal + (PlayerInfo.Playerinfo[I].Score - Player[I].ScoreTotalI);
+ Player[I].ScoreTotalInt := PlayerInfo.Playerinfo[I].Score;
+ end;
+ {if (PlayerInfo.Playerinfo[I].Bar <> Player[I].ScorePercent) then
+ Player[I].ScorePercentTarget := PlayerInfo.Playerinfo[I].Bar; }
+ end;
+
+ // back stereo
+ 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;}
+
+ for S := 1 to 1 do
+ Static[S].Texture.X := Static[S].Texture.X - 10*ScreenX;
+
+ for T := 0 to 1 do
+ Text[T].X := Text[T].X - 10*ScreenX;
+
+ Result := true;
+end;
+
+procedure TScreenSingModi.Finish;
+begin
+inherited Finish;
+
+Winner := DllMan.PluginFinish(PlayerInfo);
+
+//Log.LogError('Winner: ' + InttoStr(Winner));
+
+//DLLMan.UnLoadPlugin;
+end;
+
+function LoadTex(const Name: PChar; Typ: TTextureType): TsmallTexture;
+var
+ TexName: IPath;
+ Ext: UTF8String;
+ Tex: TTexture;
+begin
+ //Get texture Name
+ TexName := Skin.GetTextureFileName(string(Name));
+ //Get File Typ
+ Ext := TexName.GetExtension().ToUTF8;
+ if (UpperCase(Ext) = '.JPG') then
+ Ext := 'JPG'
+ else
+ Ext := 'BMP';
+
+ Tex := Texture.LoadTexture(false, TexName, UTexture.TTextureType(Typ), 0);
+
+ Result.TexNum := Tex.TexNum;
+ Result.W := Tex.W;
+ Result.H := Tex.H;
+end;
+{
+function Translate (const Name: PChar): PChar; stdcall;
+begin
+ Result := PChar(Language.Translate(string(Name)));
+end; }
+
+//Procedure to Print Text
+procedure Print(const Style, Size: byte; const X, Y: real; const Text: PChar);
+begin
+ SetFontItalic ((Style and 128) = 128);
+ SetFontStyle(Style and 7);
+ // FIXME: FONTSIZE
+ // used by Hold_The_Line / TeamDuell
+ SetFontSize(Size);
+ SetFontPos (X, Y);
+ glPrint (Language.Translate(string(Text)));
+end;
+
+//Procedure that loads a Custom Sound
+function LoadSound(const Name: PChar): cardinal;
+var
+ Stream: TAudioPlaybackStream;
+ i: integer;
+ Filename: IPath;
+ SoundFile: IPath;
+begin
+ //Search for Sound in already loaded Sounds
+ SoundFile := SoundPath.Append(Name);
+ for i := 0 to High(CustomSounds) do
+ begin
+ if (SoundFile.Equals(CustomSounds[i].Filename, true)) then
+ begin
+ Result := i;
+ Exit;
+ end;
+ end;
+
+ Stream := AudioPlayback.OpenSound(SoundFile);
+ if (Stream = nil) then
+ begin
+ Result := 0;
+ Exit;
+ end;
+
+ SetLength(CustomSounds, Length(CustomSounds)+1);
+ CustomSounds[High(CustomSounds)].Stream := Stream;
+ Result := High(CustomSounds);
+end;
+
+//Plays a Custom Sound
+procedure PlaySound(const Index: cardinal);
+begin
+ if (Index <= High(CustomSounds)) then
+ AudioPlayback.PlaySound(CustomSounds[Index].Stream);
+end;
+
+end.
+