aboutsummaryrefslogtreecommitdiffstats
path: root/Medley/src/screens
diff options
context:
space:
mode:
Diffstat (limited to 'Medley/src/screens')
-rw-r--r--Medley/src/screens/UScreenScore.pas241
-rw-r--r--Medley/src/screens/UScreenSing.pas399
-rw-r--r--Medley/src/screens/UScreenSong.pas150
3 files changed, 649 insertions, 141 deletions
diff --git a/Medley/src/screens/UScreenScore.pas b/Medley/src/screens/UScreenScore.pas
index ce1b11e5..5a50a3dc 100644
--- a/Medley/src/screens/UScreenScore.pas
+++ b/Medley/src/screens/UScreenScore.pas
@@ -39,6 +39,7 @@ uses
SysUtils,
UDisplay,
UMusic,
+ USong,
USongs,
UThemes,
gl,
@@ -74,19 +75,30 @@ type
BarGolden_ActualHeight: real;
end;
+ TPlayerScoreData = record
+ Data: array[1..6] of TPlayerScoreScreenData;
+ end;
+
TPlayerScoreRatingPics = record // a fine array of the rating pictures
RateEaseStep: integer;
RateEaseValue: real;
end;
+ TPLayerScorePics = record
+ Data: array[1..6] of TPlayerScoreRatingPics;
+ end;
+
TScreenScore = class(TMenu)
private
BarTime: cardinal;
ArrayStartModifier: integer;
public
+ //TeamInfo: TTeamInfo;
aPlayerScoreScreenTextures: array[1..6] of TPlayerScoreScreenTexture;
- aPlayerScoreScreenDatas: array[1..6] of TPlayerScoreScreenData;
- aPlayerScoreScreenRatings: array[1..6] of TPlayerScoreRatingPics;
+ aPlayerScoreScreenDatas: array of TPlayerScoreData;
+ aPlayerScoreScreenRatings: array of TPlayerScorePics;
+
+ ActualRound: integer;
BarScore_EaseOut_Step: real;
BarPhrase_EaseOut_Step: real;
@@ -133,6 +145,7 @@ type
procedure OnShow; override;
procedure OnShowFinish; override;
function Draw: boolean; override;
+ procedure RefreshTexts;
procedure FillPlayer(Item, P: integer);
procedure EaseBarIn(PlayerNumber: integer; BarType: string);
@@ -190,6 +203,22 @@ begin
begin
Display.SaveScreenShot;
end;
+ SDLK_RIGHT:
+ begin
+ if ActualRound<Length(PlaylistMedley.Stats)-1 then
+ begin
+ inc(ActualRound);
+ RefreshTexts;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ if ActualRound>0 then
+ begin
+ dec(ActualRound);
+ RefreshTexts;
+ end;
+ end;
end;
end;
end;
@@ -203,6 +232,37 @@ begin
end;
end;
+procedure TScreenScore.RefreshTexts;
+begin
+ if (ActualRound < Length(PlaylistMedley.Stats)-1) then
+ begin
+ Text[TextArtist].Text := IntToStr(ActualRound+1) + '/' +
+ IntToStr(Length(PlaylistMedley.Stats)-1) + ': ' +
+ PlaylistMedley.Stats[ActualRound].SongArtist;
+ Text[TextTitle].Text := PlaylistMedley.Stats[ActualRound].SongTitle;
+ Text[TextTitle].Visible := true;
+ Text[TextArtistTitle].Text := IntToStr(ActualRound+1) + '/' +
+ IntToStr(Length(PlaylistMedley.Stats)-1) + ': ' +
+ PlaylistMedley.Stats[ActualRound].SongArtist +
+ ' - ' + PlaylistMedley.Stats[ActualRound].SongTitle;
+ end else
+ begin
+ if (ScreenSong.Mode = smMedley) then
+ begin
+ Text[TextArtist].Text := Language.Translate('SING_TOTAL');
+ Text[TextTitle].Visible := false;
+ Text[TextArtistTitle].Text := Language.Translate('SING_TOTAL');
+ end else
+ begin
+ Text[TextArtist].Text := PlaylistMedley.Stats[ActualRound].SongArtist;
+ Text[TextTitle].Text := PlaylistMedley.Stats[ActualRound].SongTitle;
+ Text[TextTitle].Visible := true;
+ Text[TextArtistTitle].Text := PlaylistMedley.Stats[ActualRound].SongArtist + ' - ' +
+ PlaylistMedley.Stats[ActualRound].SongTitle;
+ end;
+ end;
+end;
+
constructor TScreenScore.Create;
var
Player: integer;
@@ -293,20 +353,21 @@ begin
else
ArrayStartModifier := 0; //this should never happen
end;
+ ActualRound:=0;
+ SetLength(aPlayerScoreScreenDatas, Length(PlaylistMedley.Stats));
+ SetLength(aPlayerScoreScreenRatings, Length(PlaylistMedley.Stats));
- for P := 1 to PlayersPlay do
+ for I := 0 to Length(PlaylistMedley.Stats) - 1 do
begin
- // data
- aPlayerScoreScreenDatas[P].Bar_Y := Theme.Score.StaticBackLevel[P + ArrayStartModifier].Y;
-
- // ratings
- aPlayerScoreScreenRatings[P].RateEaseStep := 1;
- aPlayerScoreScreenRatings[P].RateEaseValue := 20;
+ for P := 1 to PlayersPlay do
+ begin
+ aPlayerScoreScreenDatas[I].Data[P].Bar_Y :=
+ Theme.Score.StaticBackLevel[P + ArrayStartModifier].Y;
+ aPlayerScoreScreenRatings[I].Data[P].RateEaseStep := 1;
+ aPlayerScoreScreenRatings[I].Data[P].RateEaseValue := 20;
+ end;
end;
-
- Text[TextArtist].Text := CurrentSong.Artist;
- Text[TextTitle].Text := CurrentSong.Title;
- Text[TextArtistTitle].Text := CurrentSong.Artist + ' - ' + CurrentSong.Title;
+ RefreshTexts;
// set visibility
case PlayersPlay of
@@ -405,18 +466,6 @@ var
PStart: integer;
PHigh: integer;
begin
-{*
- 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;
-*}
-
//Draw the Background
DrawBG;
@@ -548,7 +597,8 @@ begin
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]].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);
@@ -562,9 +612,13 @@ begin
end;
procedure TScreenScore.ShowRating(PlayerNumber: integer);
+const
+ rate_factor: array[0..7] of real = (2.0, 4.0, 5.0, 6.0, 7.5, 8.5, 9.0, 10.0);
var
Rating: integer;
ThemeIndex: integer;
+ rate_max: array[0..7] of integer;
+ max, I: integer;
begin
// We have to do this here because we use the same Theme Object
@@ -575,55 +629,57 @@ begin
6: ThemeIndex := ((PlayerNumber-1) mod 3) + 1 + ArrayStartModifier;
end;
- 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;
+ //build rating scores
+ if ActualRound = Length(PlaylistMedley.Stats)-1 then
+ max := MAX_SONG_SCORE
else
+ max := max_song_score_medley;
+
+ for I := 0 to 6 do
+ rate_max[I] := round(max/10*rate_factor[I])+9;
+
+ //fix 7
+ rate_max[7] := 10000;
+
+ if PlaylistMedley.Stats[ActualRound].Player[PlayerNumber-1].ScoreTotalInt<=rate_max[0] then
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_TONE_DEAF');
+ Rating := 0;
+ end else if PlaylistMedley.Stats[ActualRound].Player[PlayerNumber-1].ScoreTotalInt<=rate_max[1] then
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_AMATEUR');
+ Rating := 1;
+ end else if PlaylistMedley.Stats[ActualRound].Player[PlayerNumber-1].ScoreTotalInt<=rate_max[2] then
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_WANNABE');
+ Rating := 2;
+ end else if PlaylistMedley.Stats[ActualRound].Player[PlayerNumber-1].ScoreTotalInt<=rate_max[3] then
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_HOPEFUL');
+ Rating := 3;
+ end else if PlaylistMedley.Stats[ActualRound].Player[PlayerNumber-1].ScoreTotalInt<=rate_max[4] then
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_RISING_STAR');
+ Rating := 4;
+ end else if PlaylistMedley.Stats[ActualRound].Player[PlayerNumber-1].ScoreTotalInt<=rate_max[5] then
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_LEAD_SINGER');
+ Rating := 5;
+ end else if PlaylistMedley.Stats[ActualRound].Player[PlayerNumber-1].ScoreTotalInt<=rate_max[6] then
+ begin
+ Text[TextScore[ThemeIndex]].Text := Language.Translate('SING_SCORE_SUPERSTAR');
+ Rating := 6;
+ end else if PlaylistMedley.Stats[ActualRound].Player[PlayerNumber-1].ScoreTotalInt<=rate_max[7] then
+ 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
+ if ( Theme.Score.StaticRatings[ThemeIndex].W > 0 ) and ( aPlayerScoreScreenRatings[ActualRound].Data[PlayerNumber].RateEaseValue > 0 ) then
begin
- Text[TextScore[ThemeIndex]].Alpha := aPlayerScoreScreenRatings[PlayerNumber].RateEaseValue / Theme.Score.StaticRatings[ThemeIndex].W;
+ Text[TextScore[ThemeIndex]].Alpha := aPlayerScoreScreenRatings[ActualRound].Data[PlayerNumber].RateEaseValue / Theme.Score.StaticRatings[ThemeIndex].W;
end;
// end todo
@@ -642,7 +698,7 @@ begin
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;
+ Width := aPlayerScoreScreenRatings[ActualRound].Data[PlayerNumber].RateEaseValue/2;
glBindTexture(GL_TEXTURE_2D, Tex_Score_Ratings[Rating].TexNum);
@@ -669,7 +725,7 @@ var
RaiseStep, MaxVal: real;
EaseOut_Step: integer;
begin
- EaseOut_Step := aPlayerScoreScreenRatings[PlayerNumber].RateEaseStep;
+ EaseOut_Step := aPlayerScoreScreenRatings[ActualRound].Data[PlayerNumber].RateEaseStep;
MaxVal := Theme.Score.StaticRatings[PlayerNumber + ArrayStartModifier].W;
RaiseStep := EaseOut_Step;
@@ -688,8 +744,8 @@ begin
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;
+ inc(aPlayerScoreScreenRatings[ActualRound].Data[PlayerNumber].RateEaseStep);
+ aPlayerScoreScreenRatings[ActualRound].Data[PlayerNumber].RateEaseValue := ReturnValue;
end;
Result := ReturnValue;
@@ -716,21 +772,21 @@ begin
// 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;
+ Score := PlaylistMedley.Stats[ActualRound].Player[PlayerNumber - 1].ScoreInt;
RaiseStep := BarScore_EaseOut_Step;
BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y + MaxHeight;
end
else if (BarType = 'Line') then
begin
- Score := Player[PlayerNumber - 1].ScoreLineInt;
+ Score := PlaylistMedley.Stats[ActualRound].Player[PlayerNumber - 1].ScoreLineInt;
RaiseStep := BarPhrase_EaseOut_Step;
- BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y - aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight + MaxHeight;
+ BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y - aPlayerScoreScreenDatas[ActualRound].Data[PlayerNumber].BarScore_ActualHeight + MaxHeight;
end
else if (BarType = 'Golden') then
begin
- Score := Player[PlayerNumber - 1].ScoreGoldenInt;
+ Score := PlaylistMedley.Stats[ActualRound].Player[PlayerNumber - 1].ScoreGoldenInt;
RaiseStep := BarGolden_EaseOut_Step;
- BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y - aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight - aPlayerScoreScreenDatas[PlayerNumber].BarLine_ActualHeight + MaxHeight;
+ BarStartPosY := Theme.Score.StaticBackLevel[PlayerNumber + ArrayStartModifier].Y - aPlayerScoreScreenDatas[ActualRound].Data[PlayerNumber].BarScore_ActualHeight - aPlayerScoreScreenDatas[ActualRound].Data[PlayerNumber].BarLine_ActualHeight + MaxHeight;
end
else
begin
@@ -739,9 +795,12 @@ begin
end;
// the height dependend of the score
- Height2Reach := (Score / MAX_SONG_SCORE) * MaxHeight;
+ if ActualRound=Length(PlaylistMedley.Stats)-1 then
+ Height2Reach := (Score / MAX_SONG_SCORE) * MaxHeight
+ else
+ Height2Reach := (Score / max_song_score_medley) * MaxHeight;
- if (aPlayerScoreScreenDatas[PlayerNumber].Bar_Actual_Height < Height2Reach) then
+ if (aPlayerScoreScreenDatas[ActualRound].Data[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
@@ -761,11 +820,11 @@ begin
DrawBar(BarType, PlayerNumber, BarStartPosY, NewHeight);
if (BarType = 'Note') then
- aPlayerScoreScreenDatas[PlayerNumber].BarScore_ActualHeight := NewHeight
+ aPlayerScoreScreenDatas[ActualRound].Data[PlayerNumber].BarScore_ActualHeight := NewHeight
else if (BarType = 'Line') then
- aPlayerScoreScreenDatas[PlayerNumber].BarLine_ActualHeight := NewHeight
+ aPlayerScoreScreenDatas[ActualRound].Data[PlayerNumber].BarLine_ActualHeight := NewHeight
else if (BarType = 'Golden') then
- aPlayerScoreScreenDatas[PlayerNumber].BarGolden_ActualHeight := NewHeight;
+ aPlayerScoreScreenDatas[ActualRound].Data[PlayerNumber].BarGolden_ActualHeight := NewHeight;
end;
procedure TscreenScore.DrawBar(BarType: string; PlayerNumber: integer; BarStartPosY: single; NewHeight: real);
@@ -839,19 +898,19 @@ begin
begin
EaseOut_Step := BarScore_EaseOut_Step;
ActualScoreValue := TextScore_ActualValue[PlayerNumber];
- ScoreReached := Player[PlayerNumber-1].ScoreInt;
+ ScoreReached := PlaylistMedley.Stats[ActualRound].Player[PlayerNumber-1].ScoreInt;
end;
if (ScoreType = 'Line') then
begin
EaseOut_Step := BarPhrase_EaseOut_Step;
ActualScoreValue := TextPhrase_ActualValue[PlayerNumber];
- ScoreReached := Player[PlayerNumber-1].ScoreLineInt;
+ ScoreReached := PlaylistMedley.Stats[ActualRound].Player[PlayerNumber-1].ScoreLineInt;
end;
if (ScoreType = 'Golden') then
begin
EaseOut_Step := BarGolden_EaseOut_Step;
ActualScoreValue := TextGolden_ActualValue[PlayerNumber];
- ScoreReached := Player[PlayerNumber-1].ScoreGoldenInt;
+ ScoreReached := PlaylistMedley.Stats[ActualRound].Player[PlayerNumber-1].ScoreGoldenInt;
end;
// EaseOut_Step is the actual step in the raising process, like the 20iest step of EaseOut_MaxSteps
@@ -893,7 +952,7 @@ var
begin
Text[TextName[Item]].Text := Ini.Name[P];
- S := IntToStr((Round(Player[P].Score) div 10) * 10);
+ S := IntToStr((Round(PlaylistMedley.Stats[ActualRound].Player[P].Score) div 10) * 10);
while (Length(S)<4) do
S := '0' + S;
Text[TextNotesScore[Item]].Text := S;
@@ -903,17 +962,17 @@ begin
//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);
+ S := IntToStr(PlaylistMedley.Stats[ActualRound].Player[P].ScoreTotalInt);
while (Length(S)<5) do
S := '0' + S;
Text[TextTotalScore[Item]].Text := S;
- S := IntToStr(Player[P].ScoreLineInt);
+ S := IntToStr(PlaylistMedley.Stats[ActualRound].Player[P].ScoreLineInt);
while (Length(S)<4) do
S := '0' + S;
Text[TextLineBonusScore[Item]].Text := S;
- S := IntToStr(Player[P].ScoreGoldenInt);
+ S := IntToStr(PlaylistMedley.Stats[ActualRound].Player[P].ScoreGoldenInt);
while (Length(S)<4) do
S := '0' + S;
Text[TextGoldenNotesScore[Item]].Text := S;
diff --git a/Medley/src/screens/UScreenSing.pas b/Medley/src/screens/UScreenSing.pas
index 342abac1..1bc16754 100644
--- a/Medley/src/screens/UScreenSing.pas
+++ b/Medley/src/screens/UScreenSing.pas
@@ -46,10 +46,12 @@ uses
UMenu,
UMusic,
USingScores,
+ USong,
USongs,
UTexture,
UThemes,
UPath,
+ UPathUtils,
UTime;
type
@@ -95,6 +97,11 @@ type
FadeOut: boolean;
Lyrics: TLyricEngine;
+ SongNameStatic: integer;
+ SongNameText: integer;
+
+ ApplauseSounds: array of TAudioPlaybackStream;
+
// score manager:
Scores: TSingScores;
@@ -112,6 +119,8 @@ type
function ParseInput(PressedKey: cardinal; CharCode: UCS4Char;
PressedDown: boolean): boolean; override;
function Draw: boolean; override;
+ procedure LoadNextSong;
+ procedure UpdateMedleyStats(medley_end: boolean);
procedure Finish; virtual;
procedure Pause; // toggle pause
@@ -130,7 +139,6 @@ uses
ULanguage,
UNote,
URecord,
- USong,
UDisplay,
UUnicodeUtils;
@@ -149,7 +157,14 @@ begin
begin
// when not ask before exit then finish now
if (Ini.AskbeforeDel <> 1) then
- Finish
+ begin
+ if ScreenSong.Mode=smMedley then
+ PlaylistMedley.CurrentMedleySong:=PlaylistMedley.NumMedleySongs+1;
+ Finish;
+ AudioPlayback.PlaySound(SoundLib.Back);
+ FadeOut := true;
+ FadeTo(@ScreenScore);
+ end
// else just pause and let the popup make the work
else if not Paused then
Pause;
@@ -185,9 +200,11 @@ begin
begin
// record sound hack:
//Sound[0].BufferLong
-
+ if ScreenSong.Mode=smMedley then
+ PlaylistMedley.CurrentMedleySong:=PlaylistMedley.NumMedleySongs+1;
Finish;
AudioPlayback.PlaySound(SoundLib.Back);
+ FadeOut := true;
FadeTo(@ScreenScore);
end;
@@ -307,11 +324,18 @@ begin
// <note> pausepopup is not visibile at the beginning </note>
Static[StaticPausePopup].Visible := false;
+ SongNameStatic := AddStatic(Theme.Sing.StaticSongName);
+ SongNameText := AddText(Theme.Sing.TextSongName);
+
Lyrics := TLyricEngine.Create(
Theme.LyricBar.UpperX, Theme.LyricBar.UpperY, Theme.LyricBar.UpperW, Theme.LyricBar.UpperH,
Theme.LyricBar.LowerX, Theme.LyricBar.LowerY, Theme.LyricBar.LowerW, Theme.LyricBar.LowerH);
LyricsSync := TLyricsSyncSource.Create();
+
+ SetLength(ApplauseSounds, 1);
+ FreeAndNil(ApplauseSounds[0]);
+ ApplauseSounds[0] := AudioPlayback.OpenSound(SoundPath.Append('Applause.mp3'));
end;
procedure TScreenSing.OnShow;
@@ -334,6 +358,19 @@ begin
//the song was sung to the end
SungToEnd := false;
+ //Reset Player Medley stats
+ if ScreenSong.Mode = smMedley then
+ begin
+ PlaylistMedley.CurrentMedleySong:=1;
+ PlaylistMedley.ApplausePlayed := false;
+
+ //max_song_score_medley := round(MAX_SONG_SCORE / NumMedleySongs);
+ //max_song_line_bonus_medley := round(MAX_SONG_LINE_BONUS / NumMedleySongs);
+ PlaylistMedley.NumPlayer := PlayersPlay;
+ SetLength(PlaylistMedley.Stats, 0);
+ max_song_score_medley := round(MAX_SONG_SCORE / PlaylistMedley.NumMedleySongs);
+ max_song_line_bonus_medley := round(MAX_SONG_LINE_BONUS / PlaylistMedley.NumMedleySongs);
+ end;
// reset video playback engine, to play video clip ...
fCurrentVideoPlaybackEngine := VideoPlayback;
@@ -425,10 +462,43 @@ begin
Static[StaticP3R].Visible := V3R;
Text[TextP3R].Visible := V3R;
+ if ScreenSong.Mode = smMedley then
+ begin
+ Static[SongNameStatic].Visible := true;
+ Text[SongNameText].Visible := true;
+ end else
+ begin
+ Static[SongNameStatic].Visible := false;
+ Text[SongNameText].Visible := false;
+ end;
+
+ LoadNextSong;
+
+ Log.LogStatus('End', 'OnShow');
+end;
+
+procedure TScreenSing.LoadNextSong;
+var
+ Index: integer;
+ VideoFile, BgFile: IPath;
+ success: boolean;
+
+begin
// FIXME: sets path and filename to ''
+ //AudioPlayback.Stop();
ResetSingTemp;
-
- CurrentSong := CatSongs.Song[CatSongs.Selected];
+
+ if ScreenSong.Mode <> smMedley then
+ CurrentSong := CatSongs.Song[CatSongs.Selected]
+ else
+ begin
+ CurrentSong := CatSongs.Song[PlaylistMedley.Song[PlaylistMedley.CurrentMedleySong-1]];
+ {AudioPlayback.Open(CurrentSong[CatSongsMedley.Selected].Path.Append(CatSongsMedley.Song[CatSongsMedley.Selected].Mp3));
+ CurrentSong := CatSongsMedley.Song[CatSongsMedley.Selected];
+ Text[SongNameText].Text := 'Medley ' + IntToStr(CurrentMedleySong)+'/'+
+ IntToStr(NumMedleySongs)+': '+
+ CurrentSong.Artist+' - '+CurrentSong.Title;}
+ end;
// FIXME: bad style, put the try-except into loadsong() and not here
try
@@ -445,6 +515,7 @@ begin
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();
@@ -453,10 +524,17 @@ begin
else
ScreenPopupError.ShowPopup(Language.Translate('ERROR_CORRUPT_SONG'));
// FIXME: do we need this?
- CurrentSong.Path := CatSongs.Song[CatSongs.Selected].Path;
+ //CurrentSong.Path := CatSongs.Song[CatSongs.Selected].Path;
Exit;
end;
+ if ScreenSong.Mode = smMedley then
+ begin
+ CurrentSong.SetMedleyMode;
+ Text[SongNameText].Text := IntToStr(PlaylistMedley.CurrentMedleySong) +
+ '/' + IntToStr(PlaylistMedley.NumMedleySongs) + ': ' +
+ CurrentSong.Artist + ' - ' + CurrentSong.Title;
+ end;
// reset video playback engine, to play video clip ...
fCurrentVideoPlaybackEngine.Close;
fCurrentVideoPlaybackEngine := VideoPlayback;
@@ -484,7 +562,12 @@ begin
begin
fShowVisualization := false;
fCurrentVideoPlaybackEngine := VideoPlayback;
- fCurrentVideoPlaybackEngine.Position := CurrentSong.VideoGAP + CurrentSong.Start;
+ if ScreenSong.Mode <> smMedley then
+ fCurrentVideoPlaybackEngine.Position := CurrentSong.VideoGAP + CurrentSong.Start
+ else
+ fCurrentVideoPlaybackEngine.Position := CurrentSong.VideoGAP +
+ GetTimeFromBeat(CurrentSong.Medley.StartBeat) - CurrentSong.Medley.FadeIn_time +
+ CurrentSong.Start;
fCurrentVideoPlaybackEngine.Play;
VideoLoaded := true;
end;
@@ -534,17 +617,34 @@ begin
// prepare lyrics timer
LyricsState.Reset();
- LyricsState.SetCurrentTime(CurrentSong.Start);
- LyricsState.StartTime := CurrentSong.Gap;
- if (CurrentSong.Finish > 0) then
- LyricsState.TotalTime := CurrentSong.Finish / 1000
- else
- LyricsState.TotalTime := AudioPlayback.Length;
- LyricsState.UpdateBeats();
+ if ScreenSong.Mode <> smMedley then
+ begin
+ LyricsState.SetCurrentTime(CurrentSong.Start); //in seconds
+ LyricsState.StartTime := CurrentSong.Gap; //in milliseconds
+ if (CurrentSong.Finish > 0) then
+ LyricsState.TotalTime := CurrentSong.Finish / 1000 //in seconds
+ else
+ LyricsState.TotalTime := AudioPlayback.Length;
+ LyricsState.UpdateBeats();
- // prepare music
- AudioPlayback.Stop();
- AudioPlayback.Position := CurrentSong.Start;
+ // prepare music
+ AudioPlayback.Stop();
+ AudioPlayback.Position := CurrentSong.Start;
+ end else
+ begin
+ LyricsState.SetCurrentTime(GetTimeFromBeat(CurrentSong.Medley.StartBeat) - CurrentSong.Medley.FadeIn_time);
+ LyricsState.StartTime := CurrentSong.Gap;
+ if (CurrentSong.Finish > 0) then
+ LyricsState.TotalTime := CurrentSong.Finish / 1000 //in seconds
+ else
+ LyricsState.TotalTime := AudioPlayback.Length;
+ LyricsState.UpdateBeats();
+
+ // prepare music
+ AudioPlayback.Stop();
+ AudioPlayback.Open(CurrentSong.Path.Append(CurrentSong.Mp3));
+ AudioPlayback.Position := GetTimeFromBeat(CurrentSong.Medley.StartBeat) - CurrentSong.Medley.FadeIn_time;
+ end;
// synchronize music to the lyrics
AudioPlayback.SetSyncSource(LyricsSync);
@@ -572,7 +672,7 @@ begin
// main text
Lyrics.Clear(CurrentSong.BPM[0].BPM, CurrentSong.Resolution);
-
+
// set custom options
case Ini.LyricsFont of
0: // normal fonts
@@ -615,42 +715,82 @@ begin
end;
end; // case
- // initialize lyrics by filling its queue
- while (not Lyrics.IsQueueFull) and
+ if ScreenSong.Mode <> smMedley then
+ begin
+ // initialize lyrics by filling its queue
+ while (not Lyrics.IsQueueFull) and
(Lyrics.LineCounter <= High(Lines[0].Line)) do
+ begin
+ Lyrics.AddLine(@Lines[0].Line[Lyrics.LineCounter]);
+ end;
+
+ // deactivate pause
+ Paused := false;
+
+ // kill all stars not killed yet (goldenstarstwinkle mod)
+ GoldenRec.SentenceChange;
+
+ // set position of line bonus - line bonus end
+ // set number of empty sentences for line bonus
+ NumEmptySentences := 0;
+ for Index := Low(Lines[0].Line) to High(Lines[0].Line) do
+ if Lines[0].Line[Index].TotalNotes = 0 then
+ Inc(NumEmptySentences);
+ end else
begin
- Lyrics.AddLine(@Lines[0].Line[Lyrics.LineCounter]);
+ // initialize lyrics by filling its queue
+ while (not Lyrics.IsQueueFull) and
+ (Lyrics.LineCounter <= High(Lines[0].Line)) do
+ begin
+ Lyrics.AddLine(@Lines[0].Line[Lyrics.LineCounter]);
+ end;
+
+ // deactivate pause
+ Paused := false;
+
+ // kill all stars not killed yet (goldenstarstwinkle mod)
+ GoldenRec.SentenceChange;
+
+ // set position of line bonus - line bonus end
+ // set number of empty sentences for line bonus
+ NumEmptySentences := 0;
+ for Index := Low(Lines[0].Line) to High(Lines[0].Line) do
+ if Lines[0].Line[Index].TotalNotes = 0 then
+ Inc(NumEmptySentences);
end;
- // deactivate pause
- Paused := false;
+ //Test
+ // start lyrics
+ LyricsState.Resume();
- // kill all stars not killed yet (goldenstarstwinkle mod)
- GoldenRec.SentenceChange;
+ // start music
+ if ScreenSong.Mode <> smMedley then
+ AudioPlayback.Play()
+ else
+ begin
+ AudioPlayback.SetVolume(0.3);
+ AudioPlayback.FadeIn(CurrentSong.Medley.FadeIn_time, 1.0);
+ end;
- // set position of line bonus - line bonus end
- // set number of empty sentences for line bonus
- NumEmptySentences := 0;
- for Index := Low(Lines[0].Line) to High(Lines[0].Line) do
- if Lines[0].Line[Index].TotalNotes = 0 then
- Inc(NumEmptySentences);
+ // start timer
+ CountSkipTimeSet;
- Log.LogStatus('End', 'OnShow');
+ PlaylistMedley.ApplausePlayed := false;
end;
procedure TScreenSing.onShowFinish;
begin
- // hide cursor on singscreen show
+ //hide cursor on singscreen show
Display.SetCursor;
-
+
// start lyrics
- LyricsState.Resume();
+ //LyricsState.Resume();
// start music
- AudioPlayback.Play();
+ //AudioPlayback.Play();
// start timer
- CountSkipTimeSet;
+ //CountSkipTimeSet;
end;
procedure TScreenSing.OnHide;
@@ -672,6 +812,8 @@ var
Sec: integer;
T: integer;
CurLyricsTime: real;
+ medley_end: boolean;
+ medley_start_applause: boolean;
Line: TLyricLine;
LastWord: TLyricWord;
begin
@@ -742,7 +884,12 @@ begin
// retrieve current lyrics time, we have to store the value to avoid
// that min- and sec-values do not match
- CurLyricsTime := LyricsState.GetCurrentTime();
+ if ScreenSong.Mode <> smMedley then
+ CurLyricsTime := LyricsState.TotalTime - LyricsState.GetCurrentTime()
+ else
+ CurLyricsTime := GetTimeFromBeat(CurrentSong.Medley.EndBeat) +
+ CurrentSong.Medley.FadeOut_time - LyricsState.GetCurrentTime();
+
Min := Round(CurLyricsTime) div 60;
Sec := Round(CurLyricsTime) mod 60;
@@ -785,24 +932,44 @@ begin
// draw static menu (FG)
DrawFG;
+ if (ScreenSong.Mode = smMedley) and (LyricsState.GetCurrentTime() >
+ GetTimeFromBeat(CurrentSong.Medley.EndBeat) + CurrentSong.Medley.FadeOut_time) then
+ medley_end := true
+ else
+ medley_end := false;
+
+ if (ScreenSong.Mode = smMedley) and (LyricsState.GetCurrentTime() >
+ GetTimeFromBeat(CurrentSong.Medley.EndBeat)) then
+ medley_start_applause := true
+ else
+ medley_start_applause := false;
+
// check for music finish
//Log.LogError('Check for music finish: ' + BoolToStr(Music.Finished) + ' ' + FloatToStr(LyricsState.CurrentTime*1000) + ' ' + IntToStr(CurrentSong.Finish));
if ShowFinish then
begin
- if (not AudioPlayback.Finished) and ((CurrentSong.Finish = 0) or
+ if (not AudioPlayback.Finished) and not medley_end and ((CurrentSong.Finish = 0) or
(LyricsState.GetCurrentTime() * 1000 <= CurrentSong.Finish)) then
begin
// analyze song if not paused
if (not Paused) then
+ begin
Sing(Self);
+ //Update Medley Stats
+ if (ScreenSong.Mode = smMedley) and not FadeOut then
+ UpdateMedleyStats(medley_start_applause);
+ end;
end
else
begin
if (not FadeOut) then
begin
Finish;
- FadeOut := true;
- FadeTo(@ScreenScore);
+ if ScreenSong.Mode = smNormal then
+ begin
+ FadeOut := true;
+ FadeTo(@ScreenScore);
+ end;
end;
end;
end;
@@ -850,7 +1017,49 @@ begin
Result := true;
end;
+procedure TScreenSing.UpdateMedleyStats(medley_end: boolean);
+var
+ len, num, I : integer;
+ lastline: boolean;
+ vol: real;
+begin
+ len := Length(PlaylistMedley.Stats);
+ num := PlaylistMedley.NumPlayer;
+
+ if (PlaylistMedley.CurrentMedleySong>len) and
+ (PlaylistMedley.CurrentMedleySong<=PlaylistMedley.NumMedleySongs) then
+ begin
+ inc(len);
+ SetLength(PlaylistMedley.Stats, len);
+ SetLength(PlaylistMedley.Stats[len-1].Player, num);
+ PlaylistMedley.Stats[len-1].SongArtist := CurrentSong.Artist;
+ PlaylistMedley.Stats[len-1].SongTitle := CurrentSong.Title;
+ end;
+
+ if (PlaylistMedley.CurrentMedleySong<=PlaylistMedley.NumMedleySongs) then
+ for I := 0 to num - 1 do
+ PlaylistMedley.Stats[len-1].Player[I] := Player[I];
+
+ if medley_end and not PlaylistMedley.ApplausePlayed and
+ (PlaylistMedley.CurrentMedleySong<=PlaylistMedley.NumMedleySongs) then
+ begin
+ PlaylistMedley.ApplausePlayed:=true;
+ AudioPlayback.PlaySound(ApplauseSounds[0]);
+ end;
+
+ if(LyricsState.GetCurrentTime() > GetTimeFromBeat(CurrentSong.Medley.EndBeat)) then
+ begin
+ vol := 1-(LyricsState.GetCurrentTime() - GetTimeFromBeat(CurrentSong.Medley.EndBeat))/
+ CurrentSong.Medley.FadeOut_time ;
+ AudioPlayback.SetVolume(vol); //used as fade out!
+ end;
+end;
+
procedure TScreenSing.Finish;
+var
+ I, J: integer;
+ len, num: integer;
+ Color: TRGB;
begin
AudioInput.CaptureStop;
AudioPlayback.Stop;
@@ -879,6 +1088,91 @@ begin
end;
SetFontItalic(false);
+
+ if ScreenSong.Mode = smMedley then
+ begin
+ {***** just a quick and dirty fix.... *******}
+ // setup score manager
+ Scores.ClearPlayers; // clear old player values
+
+ Color.R := 0;
+ Color.G := 0;
+ Color.B := 0;
+ // add new players
+ for I := 0 to PlayersPlay - 1 do
+ begin
+ Scores.AddPlayer(Tex_ScoreBG[I], Color);
+ end;
+
+ Scores.Init; // get positions for players
+
+ // prepare players
+ SetLength(Player, PlayersPlay);
+ {***** end of quick and dirty fix ******}
+
+ if not FadeOut then
+ begin
+ inc(PlaylistMedley.CurrentMedleySong);
+ if PlaylistMedley.CurrentMedleySong<=PlaylistMedley.NumMedleySongs then
+ begin
+ //AudioPlayback.PlaySound(SoundLib.Applause);
+ LoadNextSong;
+ end else
+ begin
+ //build sums
+ len := Length(PlaylistMedley.Stats);
+ num := PlaylistMedley.NumPlayer;
+
+ SetLength(PlaylistMedley.Stats, len+1);
+ SetLength(PlaylistMedley.Stats[len].Player, num);
+
+ for J := 0 to len - 1 do
+ begin
+ for I := 0 to num - 1 do
+ begin
+ PlaylistMedley.Stats[len].Player[I].Score :=
+ PlaylistMedley.Stats[len].Player[I].Score +
+ PlaylistMedley.Stats[J].Player[I].Score;
+
+ PlaylistMedley.Stats[len].Player[I].ScoreLine :=
+ PlaylistMedley.Stats[len].Player[I].ScoreLine +
+ PlaylistMedley.Stats[J].Player[I].ScoreLine;
+
+ PlaylistMedley.Stats[len].Player[I].ScoreGolden :=
+ PlaylistMedley.Stats[len].Player[I].ScoreGolden +
+ PlaylistMedley.Stats[J].Player[I].ScoreGolden;
+
+ PlaylistMedley.Stats[len].Player[I].ScoreInt :=
+ PlaylistMedley.Stats[len].Player[I].ScoreInt +
+ PlaylistMedley.Stats[J].Player[I].ScoreInt;
+
+ PlaylistMedley.Stats[len].Player[I].ScoreLineInt :=
+ PlaylistMedley.Stats[len].Player[I].ScoreLineInt +
+ PlaylistMedley.Stats[J].Player[I].ScoreLineInt;
+
+ PlaylistMedley.Stats[len].Player[I].ScoreGoldenInt :=
+ PlaylistMedley.Stats[len].Player[I].ScoreGoldenInt +
+ PlaylistMedley.Stats[J].Player[I].ScoreGoldenInt;
+
+ PlaylistMedley.Stats[len].Player[I].ScoreTotalInt :=
+ PlaylistMedley.Stats[len].Player[I].ScoreTotalInt +
+ PlaylistMedley.Stats[J].Player[I].ScoreTotalInt;
+ end; //of for I
+ end; //of for J
+
+ FadeOut:=true;
+ FadeTo(@ScreenScore);
+ end;
+ end;
+ end else
+ begin
+ SetLength(PlaylistMedley.Stats, 1);
+ SetLength(PlaylistMedley.Stats[0].Player, PlayersPlay);
+ for I := 0 to PlayersPlay - 1 do
+ PlaylistMedley.Stats[0].Player[I] := Player[I];
+ PlaylistMedley.Stats[0].SongArtist := CurrentSong.Artist;
+ PlaylistMedley.Stats[0].SongTitle := CurrentSong.Title;
+ end;
end;
procedure TScreenSing.OnSentenceEnd(SentenceIndex: cardinal);
@@ -904,10 +1198,19 @@ begin
Exit;
// set max song score
- if (Ini.LineBonus = 0) then
- MaxSongScore := MAX_SONG_SCORE
- else
- MaxSongScore := MAX_SONG_SCORE - MAX_SONG_LINE_BONUS;
+ if ScreenSong.Mode <> smMedley then
+ begin
+ if (Ini.LineBonus = 0) then
+ MaxSongScore := MAX_SONG_SCORE
+ else
+ MaxSongScore := MAX_SONG_SCORE - MAX_SONG_LINE_BONUS;
+ end else
+ begin
+ if (Ini.LineBonus = 0) then
+ MaxSongScore := max_song_score_medley
+ else
+ MaxSongScore := max_song_score_medley - max_song_line_bonus_medley;
+ end;
// Note: ScoreValue is the sum of all note values of the song
MaxLineScore := MaxSongScore * (Line.TotalNotes / Lines[0].ScoreValue);
@@ -941,7 +1244,11 @@ begin
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) -
+ if ScreenSong.Mode <> smMedley then
+ LineBonus := MAX_SONG_LINE_BONUS / (Length(Lines[0].Line) -
+ NumEmptySentences)
+ else
+ LineBonus := max_song_line_bonus_medley / (Length(Lines[0].Line) -
NumEmptySentences);
// apply line-bonus
CurrentPlayer.ScoreLine :=
diff --git a/Medley/src/screens/UScreenSong.pas b/Medley/src/screens/UScreenSong.pas
index bd5eebe5..bab2ef51 100644
--- a/Medley/src/screens/UScreenSong.pas
+++ b/Medley/src/screens/UScreenSong.pas
@@ -53,6 +53,8 @@ uses
UTime;
type
+ TVisArr = array of integer;
+
TScreenSong = class(TMenu)
private
Equalizer: Tms_Equalizer;
@@ -138,6 +140,9 @@ type
procedure HideCatTL;// Show Cat in Tob left
procedure Refresh; //Refresh Song Sorting
procedure ChangeMusic;
+
+ function getVisibleMedleyArr(): TVisArr;
+ procedure StartMedley(num: integer);
//Party Mode
procedure SelectRandomSong;
procedure SetJoker;
@@ -345,6 +350,21 @@ begin
Exit;
end;
+ Ord('S'):
+ begin
+ if (Length(getVisibleMedleyArr()) > 0) and (Mode = smNormal) and
+ (CatSongs.Song[Interaction].Medley.Source = msTag) then
+ begin
+ StartMedley(0);
+ end;
+ end;
+ Ord('D'):
+ begin
+ if (Length(getVisibleMedleyArr()) > 0) and (Mode = smNormal) then
+ begin
+ StartMedley(5);
+ end;
+ end;
Ord('M'): //Show SongMenu
begin
if (Songs.SongList.Count > 0) then
@@ -1002,6 +1022,11 @@ begin
// Set texts
Text[TextArtist].Text := CatSongs.Song[Interaction].Artist;
Text[TextTitle].Text := CatSongs.Song[Interaction].Title;
+
+ //medley mod
+ if CatSongs.Song[Interaction].Medley.Source = msTag then
+ Text[TextTitle].Text := Text[TextTitle].Text + '[M]';
+
if (Ini.TabsAtStartup = 1) and (CatSongs.CatNumShow = -1) then
begin
Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].OrderNum) + '/' + IntToStr(CatSongs.CatCount);
@@ -1496,6 +1521,9 @@ begin
AudioPlayback.Stop;
+ if Mode = smMedley then
+ Mode := smNormal;
+
if Ini.Players <= 3 then PlayersPlay := Ini.Players + 1;
if Ini.Players = 4 then PlayersPlay := 6;
@@ -1725,19 +1753,29 @@ end;
procedure TScreenSong.StartMusicPreview();
var
- Song: TSong;
+ Song: TSong;
+ success: boolean;
begin
AudioPlayback.Close();
+ if CatSongs.Song[Interaction].Main then
+ Exit;
+
Song := CatSongs.Song[Interaction];
- if not assigned(Song) then
+ if not assigned(Song) or Song.Main then
Exit;
if AudioPlayback.Open(Song.Path.Append(Song.Mp3)) then
begin
PreviewOpened := Interaction;
-
- AudioPlayback.Position := AudioPlayback.Length / 4;
+
+ if Song.Medley.Source <> msNone then
+ begin
+ CurrentSong := Song;
+ AudioPlayback.Position := GetTimeFromBeat(Song.Medley.StartBeat);
+ end else
+ AudioPlayback.Position := AudioPlayback.Length / 4;
+
// set preview volume
if (Ini.PreviewFading = 0) then
begin
@@ -1747,6 +1785,10 @@ begin
end
else
begin
+ AudioPlayback.Position := AudioPlayback.Position - Ini.PreviewFading;
+ if AudioPlayback.Position<0 then
+ AudioPlayback.Position := 0;
+
// music fade enabled: start muted and fade-in
AudioPlayback.SetVolume(0);
AudioPlayback.FadeIn(Ini.PreviewFading, IPreviewVolumeVals[Ini.PreviewVolume]);
@@ -1796,6 +1838,106 @@ begin
end;
end;
+function TScreenSong.getVisibleMedleyArr(): TVisArr;
+var
+ I: integer;
+ res: TVisArr;
+begin
+ SetLength(res, 0);
+ for I := 0 to Length(CatSongs.Song) - 1 do
+ begin
+ if CatSongs.Song[I].Visible and (CatSongs.Song[I].Medley.Source = msTag) then
+ begin
+ SetLength(res, Length(res)+1);
+ res[Length(res)-1] := I;
+ end;
+ end;
+ Result := res;
+end;
+
+//start Medley round
+procedure TScreenSong.StartMedley(num: integer);
+ procedure AddSong(SongNr: integer);
+ begin
+ SetLength(PlaylistMedley.Song, Length(PlaylistMedley.Song)+1);
+ PlaylistMedley.Song[Length(PlaylistMedley.Song)-1] := SongNr;
+ end;
+
+ function SongAdded(SongNr: integer): boolean;
+ var
+ i: integer;
+ skipped :boolean;
+ begin
+ skipped := false;
+ for i := 0 to Length(PlaylistMedley.Song) - 1 do
+ begin
+ if (SongNr=PlaylistMedley.Song[i]) then
+ begin
+ skipped:=true;
+ break;
+ end;
+ end;
+ Result:=skipped;
+ end;
+
+ function NumSongsAdded(): Integer;
+ begin
+ Result := Length(PlaylistMedley.Song);
+ end;
+
+ function GetNextSongNr: integer;
+ var
+ I, num: integer;
+ unused_arr: array of integer;
+ visible_arr: TVisArr;
+ begin
+ SetLength(unused_arr, 0);
+ visible_arr := getVisibleMedleyArr();
+ for I := 0 to Length(visible_arr) - 1 do
+ begin
+ if (not SongAdded(visible_arr[I])) then
+ begin
+ SetLength(unused_arr, Length(unused_arr)+1);
+ unused_arr[Length(unused_arr)-1] := visible_arr[I];
+ end;
+ end;
+
+ num := random(Length(unused_arr));
+ Result := unused_arr[num];
+end;
+
+var
+ I: integer;
+ VS: integer;
+
+begin
+ StopMusicPreview();
+ Mode := smMedley;
+
+ if num>0 then
+ begin
+ VS := Length(getVisibleMedleyArr());
+ if VS < num then
+ PlaylistMedley.NumMedleySongs := VS
+ else
+ PlaylistMedley.NumMedleySongs := num;
+
+ Randomize;
+ //set up Playlist Medley
+ SetLength(PlaylistMedley.Song, 0);
+ for I := 0 to PlaylistMedley.NumMedleySongs - 1 do
+ begin
+ AddSong(GetNextSongNr);
+ end;
+ end else
+ begin
+ SetLength(PlaylistMedley.Song, 1);
+ PlaylistMedley.Song[0] := Interaction;
+ PlaylistMedley.NumMedleySongs := 1;
+ end;
+ FadeTo(@ScreenSing);
+end;
+
procedure TScreenSong.SkipTo(Target: cardinal);
var
i: integer;