diff options
Diffstat (limited to 'src/Classes/ULyrics.pas')
-rw-r--r-- | src/Classes/ULyrics.pas | 884 |
1 files changed, 0 insertions, 884 deletions
diff --git a/src/Classes/ULyrics.pas b/src/Classes/ULyrics.pas deleted file mode 100644 index 305cb91f..00000000 --- a/src/Classes/ULyrics.pas +++ /dev/null @@ -1,884 +0,0 @@ -unit ULyrics; - -interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -{$I switches.inc} - -uses - gl, - glext, - UTexture, - UThemes, - UMusic; - -type - // stores two textures for enabled/disabled states - TPlayerIconTex = array [0..1] of TTexture; - - PLyricWord = ^TLyricWord; - TLyricWord = record - X: Real; // left corner - Width: Real; // width - Start: Cardinal; // start of the word in quarters (beats) - Length: Cardinal; // length of the word in quarters - Text: String; // text - Freestyle: Boolean; // is freestyle? - end; - ALyricWord = array of TLyricWord; - - TLyricLine = class - public - Text: String; // text - Tex: glUInt; // texture of the text - Width: Real; // width - Size: Byte; // fontsize - Words: ALyricWord; // words in this line - CurWord: Integer; // current active word idx (only valid if line is active) - Start: Integer; // start of this line in quarters (Note: negative start values are possible due to gap) - StartNote: Integer; // start of the first note of this line in quarters - Length: Integer; // length in quarters (from start of first to the end of the last note) - HasFreestyle: Boolean; // one or more word are freestyle? - CountFreestyle: Integer; // how often there is a change from freestyle to non freestyle in this line - Players: Byte; // players that should sing that line (bitset, Player1: 1, Player2: 2, Player3: 4) - LastLine: Boolean; // is this the last line of the song? - - constructor Create(); - destructor Destroy(); override; - procedure Reset(); - end; - - TLyricEngine = class - private - LastDrawBeat: Real; - UpperLine: TLyricLine; // first line displayed (top) - LowerLine: TLyricLine; // second lind displayed (bottom) - QueueLine: TLyricLine; // third line (will be displayed when lower line is finished) - - IndicatorTex: TTexture; // texture for lyric indikator - BallTex: TTexture; // texture of the ball for the lyric effect - - QueueFull: Boolean; // set to true if the queue is full and a line will be replaced with the next AddLine - LCounter: Word; // line counter - - // duet mode - textures for player icons - // FIXME: do not use a fixed player count, use MAX_PLAYERS instead - PlayerIconTex: array[0..5] of TPlayerIconTex; - - //Some helper Procedures for Lyric Drawing - procedure DrawLyrics (Beat: Real); - procedure DrawLyricsLine(X, W, Y: Real; Size: Byte; Line: TLyricLine; Beat: Real); - procedure DrawPlayerIcon(Player: Byte; Enabled: Boolean; X, Y, Size, Alpha: Real); - procedure DrawBall(XBall, YBall, Alpha:Real); - - public - // positions, line specific settings - UpperLineX: Real; //X Start Pos of UpperLine - UpperLineW: Real; //Width of UpperLine with Icon(s) and Text - UpperLineY: Real; //Y Start Pos of UpperLine - UpperLineSize: Byte; //Max Size of Lyrics Text in UpperLine - - LowerLineX: Real; //X Start Pos of LowerLine - LowerLineW: Real; //Width of LowerLine with Icon(s) and Text - LowerLineY: Real; //Y Start Pos of LowerLine - LowerLineSize: Byte; //Max Size of Lyrics Text in LowerLine - - // display propertys - LineColor_en: TRGBA; //Color of Words in an Enabled Line - LineColor_dis: TRGBA; //Color of Words in a Disabled Line - LineColor_act: TRGBA; //Color of teh active Word - FontStyle: Byte; //Font for the Lyric Text - FontReSize: Boolean; //ReSize Lyrics if they don't fit Screen - - { // currently not used - FadeInEffect: Byte; //Effect for Line Fading in: 0: No Effect; 1: Fade Effect; 2: Move Upwards from Bottom to Pos - FadeOutEffect: Byte; //Effect for Line Fading out: 0: No Effect; 1: Fade Effect; 2: Move Upwards - } - - UseLinearFilter: Boolean; //Should Linear Tex Filter be used - - // song specific settings - BPM: Real; - Resolution: Integer; - - // properties to easily read options of this class - property IsQueueFull: Boolean read QueueFull; // line in queue? - property LineCounter: Word read LCounter; // lines that were progressed so far (after last clear) - - procedure AddLine(Line: PLine); // adds a line to the queue, if there is space - procedure Draw (Beat: Real); // draw the current (active at beat) lyrics - - // clears all cached song specific information - procedure Clear(cBPM: Real = 0; cResolution: Integer = 0); - - function GetUpperLine(): TLyricLine; - function GetLowerLine(): TLyricLine; - - function GetUpperLineIndex(): Integer; - - constructor Create; overload; - constructor Create(ULX,ULY,ULW,ULS,LLX,LLY,LLW,LLS: Real); overload; - procedure LoadTextures; - destructor Destroy; override; - end; - -implementation - -uses SysUtils, - USkins, - TextGL, - UGraphic, - UDisplay, - ULog, - math, - UIni; - -//----------- -//Helper procs to use TRGB in Opengl ...maybe this should be somewhere else -//----------- -procedure glColorRGB(Color: TRGB); overload; -begin - glColor3f(Color.R, Color.G, Color.B); -end; - -procedure glColorRGB(Color: TRGB; Alpha: Real); overload; -begin - glColor4f(Color.R, Color.G, Color.B, Alpha); -end; - -procedure glColorRGB(Color: TRGBA); overload; -begin - glColor4f(Color.R, Color.G, Color.B, Color.A); -end; - -procedure glColorRGB(Color: TRGBA; Alpha: Real); overload; -begin - glColor4f(Color.R, Color.G, Color.B, Min(Color.A, Alpha)); -end; - -{ TLyricLine } - -constructor TLyricLine.Create(); -begin - inherited; - Reset(); -end; - -destructor TLyricLine.Destroy(); -begin - SetLength(Words, 0); - inherited; -end; - -procedure TLyricLine.Reset(); -begin - Start := 0; - StartNote := 0; - Length := 0; - LastLine := False; - - Text := ''; - Width := 0; - - // duet mode: players of that line (default: all) - Players := $FF; - - SetLength(Words, 0); - CurWord := -1; - - HasFreestyle := False; - CountFreestyle := 0; -end; - - -{ TLyricEngine } - -//--------------- -// Create - Constructor, just get Memory -//--------------- -constructor TLyricEngine.Create; -begin - inherited; - - BPM := 0; - Resolution := 0; - LCounter := 0; - QueueFull := False; - - UpperLine := TLyricLine.Create; - LowerLine := TLyricLine.Create; - QueueLine := TLyricLine.Create; - - UseLinearFilter := True; - LastDrawBeat := 0; -end; - -constructor TLyricEngine.Create(ULX,ULY,ULW,ULS,LLX,LLY,LLW,LLS:Real); -begin - Create; - - UpperLineX := ULX; - UpperLineW := ULW; - UpperLineY := ULY; - UpperLineSize := Trunc(ULS); - - LowerLineX := LLX; - LowerLineW := LLW; - LowerLineY := LLY; - LowerLineSize := Trunc(LLS); - - LoadTextures; -end; - - -//--------------- -// Destroy - Frees Memory -//--------------- -destructor TLyricEngine.Destroy; -begin - UpperLine.Free; - LowerLine.Free; - QueueLine.Free; - inherited; -end; - -//--------------- -// Clear - Clears all cached Song specific Information -//--------------- -procedure TLyricEngine.Clear(cBPM: Real; cResolution: Integer); -begin - BPM := cBPM; - Resolution := cResolution; - LCounter := 0; - QueueFull := False; - - LastDrawBeat:=0; -end; - - -//--------------- -// LoadTextures - Load Player Textures and Create Lyric Textures -//--------------- -procedure TLyricEngine.LoadTextures; -var - I: Integer; - - function CreateLineTex: glUint; - begin - // generate and bind Texture - glGenTextures(1, @Result); - glBindTexture(GL_TEXTURE_2D, Result); - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - if UseLinearFilter then - begin - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - end; - end; - -begin - - // lyric indicator (bar that indicates when the line start) - IndicatorTex := Texture.LoadTexture(Skin.GetTextureFileName('LyricHelpBar'), TEXTURE_TYPE_TRANSPARENT, $FF00FF); - - // ball for current word hover in ball effect - BallTex := Texture.LoadTexture(Skin.GetTextureFileName('Ball'), TEXTURE_TYPE_TRANSPARENT, 0); - - // duet mode: load player icon - for I := 0 to 5 do - begin - PlayerIconTex[I][0] := Texture.LoadTexture(Skin.GetTextureFileName('LyricIcon_P' + InttoStr(I+1)), TEXTURE_TYPE_TRANSPARENT, 0); - PlayerIconTex[I][1] := Texture.LoadTexture(Skin.GetTextureFileName('LyricIconD_P' + InttoStr(I+1)), TEXTURE_TYPE_TRANSPARENT, 0); - end; - - // create line textures - UpperLine.Tex := CreateLineTex; - LowerLine.Tex := CreateLineTex; - QueueLine.Tex := CreateLineTex; -end; - - -//--------------- -// AddLine - Adds LyricLine to queue -// The LyricEngine stores three lines in its queue: -// UpperLine: the upper line displayed in the lyrics -// LowerLine: the lower line displayed in the lyrics -// QueueLine: an offscreen line that precedes LowerLine -// If the queue is full the next call to AddLine will replace UpperLine with -// LowerLine, LowerLine with QueueLine and QueueLine with the Line parameter. -//--------------- -procedure TLyricEngine.AddLine(Line: PLine); -var - LyricLine: TLyricLine; - PosX: Real; - I: Integer; - CurWord: PLyricWord; - RenderPass: Integer; - - function CalcWidth(LyricLine: TLyricLine): Real; - begin - Result := glTextWidth(PChar(LyricLine.Text)); - - Result := Result + (LyricLine.CountFreestyle * 10); - - // if the line ends with a freestyle not, then leave the place to finish to draw the text italic - if (LyricLine.Words[High(LyricLine.Words)].Freestyle) then - Result := Result + 12; - end; - -begin - // only add lines, if there is space - if not IsQueueFull then - begin - // set LyricLine to line to write to - if (LineCounter = 0) then - LyricLine := UpperLine - else if (LineCounter = 1) then - LyricLine := LowerLine - else - begin - // now the queue is full - LyricLine := QueueLine; - QueueFull := True; - end; - end - else - begin // rotate lines (round-robin-like) - LyricLine := UpperLine; - UpperLine := LowerLine; - LowerLine := QueueLine; - QueueLine := LyricLine; - end; - - // reset line state - LyricLine.Reset(); - - // check if sentence has notes - if (Line <> nil) and (Length(Line.Note) > 0) then - begin - // copy values from SongLine to LyricLine - LyricLine.Start := Line.Start; - LyricLine.StartNote := Line.Note[0].Start; - LyricLine.Length := Line.Note[High(Line.Note)].Start + - Line.Note[High(Line.Note)].Length - - Line.Note[0].Start; - LyricLine.LastLine := Line.LastLine; - - // copy words - SetLength(LyricLine.Words, Length(Line.Note)); - for I := 0 to High(Line.Note) do - begin - LyricLine.Words[I].Start := Line.Note[I].Start; - LyricLine.Words[I].Length := Line.Note[I].Length; - LyricLine.Words[I].Text := Line.Note[I].Text; - LyricLine.Words[I].Freestyle := Line.Note[I].NoteType = ntFreestyle; - - LyricLine.HasFreestyle := LyricLine.HasFreestyle or LyricLine.Words[I].Freestyle; - LyricLine.Text := LyricLine.Text + LyricLine.Words[I].Text; - - if (I > 0) and - LyricLine.Words[I-1].Freestyle and - not LyricLine.Words[I].Freestyle then - begin - Inc(LyricLine.CountFreestyle); - end; - end; - - // set font params - SetFontStyle(FontStyle); - SetFontPos(0, 0); - LyricLine.Size := UpperLineSize; - SetFontSize(LyricLine.Size); - SetFontItalic(False); - SetFontReflection(False, 0); - glColor4f(1, 1, 1, 1); - - // change fontsize to fit the screen - LyricLine.Width := CalcWidth(LyricLine); - while (LyricLine.Width > UpperLineW) do - begin - Dec(LyricLine.Size); - - if (LyricLine.Size <=1) then - Break; - - SetFontSize(LyricLine.Size); - LyricLine.Width := CalcWidth(LyricLine); - end; - - // Offscreen rendering of LyricTexture: - // First we will create a white transparent background to draw on. - // If the text was simply drawn to the screen with blending, the translucent - // parts of the text would be merged with the current color of the background. - // This would result in a texture that partly contains the screen we are - // drawing on. This will be visible in the fonts outline when the LyricTexture - // is drawn to the screen later. - // So we have to draw the text in TWO passes. - // At the first pass we copy the characters to the back-buffer in such a way - // that preceding characters are not repainted by following chars (otherwise - // some characters would be blended twice in the 2nd pass). - // To achieve this we disable blending and enable the depth-test. The z-buffer - // is used as a mask or replacement for the missing stencil-buffer. A z-value - // of 1 means the pixel was not assigned yet, whereas 0 stands for a pixel - // that was already drawn on. In addition we set the depth-func in such a way - // that assigned pixels (0) will not be drawn a second time. - // At the second pass we draw the text with blending and without depth-test. - // This will blend overlapping characters but not the background as it was - // repainted in the first pass. - - glPushAttrib(GL_VIEWPORT_BIT or GL_DEPTH_BUFFER_BIT); - glViewPort(0, 0, 800, 600); - glClearColor(0, 0, 0, 0); - glDepthRange(0, 1); - glClearDepth(1); - glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); - - SetFontZ(0); - - // assure blending is off and the correct depth-func is enabled - glDisable(GL_BLEND); - glDepthFunc(GL_LESS); - - // we need two passes to draw the font onto the screen. - for RenderPass := 0 to 1 do - begin - if (RenderPass = 0) then - begin - // first pass: simply copy each character to the screen without overlapping. - SetFontBlend(false); - glEnable(GL_DEPTH_TEST); - end - else - begin - // second pass: now we will blend overlapping characters. - SetFontBlend(true); - glDisable(GL_DEPTH_TEST); - end; - - PosX := 0; - - // set word positions and line size and draw the line to the back-buffer - for I := 0 to High(LyricLine.Words) do - begin - CurWord := @LyricLine.Words[I]; - - SetFontItalic(CurWord.Freestyle); - - CurWord.X := PosX; - - // Draw Lyrics - SetFontPos(PosX, 0); - glPrint(PChar(CurWord.Text)); - - CurWord.Width := glTextWidth(PChar(CurWord.Text)); - if CurWord.Freestyle then - begin - if (I < High(LyricLine.Words)) and not LyricLine.Words[I+1].Freestyle then - CurWord.Width := CurWord.Width + 10 - else if (I = High(LyricLine.Words)) then - CurWord.Width := CurWord.Width + 12; - end; - PosX := PosX + CurWord.Width; - end; - end; - - // copy back-buffer to texture - glBindTexture(GL_TEXTURE_2D, LyricLine.Tex); - // FIXME: this does not work this way - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 600-64, 1024, 64, 0); - if (glGetError() <> GL_NO_ERROR) then - Log.LogError('Creation of Lyrics-texture failed', 'TLyricEngine.AddLine'); - - // restore OpenGL state - glPopAttrib(); - - // clear buffer (use white to avoid flimmering if no cover/video is available) - glClearColor(1, 1, 1, 1); - glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); - end; // if (Line <> nil) and (Length(Line.Note) > 0) - - // increase the counter - Inc(LCounter); -end; - - -//--------------- -// Draw - Procedure Draws Lyrics; Beat is curent Beat in Quarters -// Draw just manage the Lyrics, drawing is done by a call of DrawLyrics -//--------------- -procedure TLyricEngine.Draw(Beat: Real); -begin - DrawLyrics(Beat); - LastDrawBeat := Beat; -end; - -//--------------- -// DrawLyrics(private) - Helper for Draw; main Drawing procedure -//--------------- -procedure TLyricEngine.DrawLyrics(Beat: Real); -begin - DrawLyricsLine(UpperLineX, UpperLineW, UpperlineY, 15, Upperline, Beat); - DrawLyricsLine(LowerLineX, LowerLineW, LowerlineY, 15, Lowerline, Beat); -end; - -//--------------- -// DrawPlayerIcon(private) - Helper for Draw; Draws a Playericon -//--------------- -procedure TLyricEngine.DrawPlayerIcon(Player: Byte; Enabled: Boolean; X, Y, Size, Alpha: Real); -var - IEnabled: Byte; -begin - if Enabled then - IEnabled := 0 - else - IEnabled := 1; - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBindTexture(GL_TEXTURE_2D, PlayerIconTex[Player][IEnabled].TexNum); - - glColor4f(1, 1, 1, Alpha); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(X, Y); - glTexCoord2f(0, 1); glVertex2f(X, Y + Size); - glTexCoord2f(1, 1); glVertex2f(X + Size, Y + Size); - glTexCoord2f(1, 0); glVertex2f(X + Size, Y); - glEnd; - - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); -end; - -//--------------- -// DrawBall(private) - Helper for Draw; Draws the Ball over the LyricLine if needed -//--------------- -procedure TLyricEngine.DrawBall(XBall, YBall, Alpha: Real); -begin - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBindTexture(GL_TEXTURE_2D, BallTex.TexNum); - - glColor4f(1, 1, 1, Alpha); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(XBall - 10, YBall); - glTexCoord2f(0, 1); glVertex2f(XBall - 10, YBall + 20); - glTexCoord2f(1, 1); glVertex2f(XBall + 10, YBall + 20); - glTexCoord2f(1, 0); glVertex2f(XBall + 10, YBall); - glEnd; - - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); -end; - -//--------------- -// DrawLyricsLine(private) - Helper for Draw; Draws one LyricLine -//--------------- -procedure TLyricEngine.DrawLyricsLine(X, W, Y: Real; Size: Byte; Line: TLyricLine; Beat: Real); -var - CurWordStart, CurWordEnd: Real; // screen coordinates of current word and the rest of the sentence - FreestyleDiff: Integer; // difference between top and bottom coordiantes for freestyle lyrics - Progress: Real; // progress of singing the current word - LyricX: Real; // left - LyricX2: Real; // right - LyricY: Real; // top - LyricsHeight: Real; // height the lyrics are displayed - Alpha: Real; // alphalevel to fade out at end - CurWord, LastWord: PLyricWord; // current word - - {// duet mode - IconSize: Real; // size of player icons - IconAlpha: Real; // alpha level of player icons - } -begin - // do not draw empty lines - // Note: lines with no words in it do not have a valid texture - if (Length(Line.Words) = 0) or - (Line.Width <= 0) then - begin - Exit; - end; - - // this is actually a bit more than the real font size - // it helps adjusting the "zoom-center" - LyricsHeight := 30.5 * (Line.Size/10); - - { - // duet mode - IconSize := (2 * Size); - IconAlpha := Frac(Beat/(Resolution*4)); - - DrawPlayerIcon (0, True, X, Y + (42 - IconSize) / 2 , IconSize, IconAlpha); - DrawPlayerIcon (1, True, X + IconSize + 1, Y + (42 - IconSize) / 2, IconSize, IconAlpha); - DrawPlayerIcon (2, True, X + (IconSize + 1)*2, Y + (42 - IconSize) / 2, IconSize, IconAlpha); - } - - LyricX := X + W/2 - Line.Width/2; - LyricX2 := LyricX + Line.Width; - - // maybe center smaller lines - //LyricY := Y; - LyricY := Y + ((Size / Line.Size - 1) * LyricsHeight) / 2; - - Alpha := 1; - - // check if this line is active (at least its first note must be active) - if (Beat >= Line.StartNote) then - begin - // if this line just got active, CurWord is -1, - // this means we should try to make the first word active - if (Line.CurWord = -1) then - Line.CurWord := 0; - - // check if the current active word is still active. - // Otherwise proceed to the next word if there is one in this line. - // Note: the max. value of Line.CurWord is High(Line.Words) - if (Line.CurWord < High(Line.Words)) and - (Beat >= Line.Words[Line.CurWord + 1].Start) then - begin - Inc(Line.CurWord); - end; - - FreestyleDiff := 0; - - // determine current and last word in this line. - // If the end of the line is reached use the last word as current word. - LastWord := @Line.Words[High(Line.Words)]; - CurWord := @Line.Words[Line.CurWord]; - - // calc the progress of the lyrics effect - Progress := (Beat - CurWord.Start) / CurWord.Length; - if Progress >= 1 then - Progress := 1; - if Progress <= 0 then - Progress := 0; - - // last word of this line finished, but this line did not hide -> fade out - if Line.LastLine and - (Beat > LastWord.Start + LastWord.Length) then - begin - Alpha := 1 - (Beat - (LastWord.Start + LastWord.Length)) / 15; - if (Alpha < 0) then - Alpha := 0; - end; - - // determine the start-/end positions of the fragment of the current word - CurWordStart := CurWord.X; - CurWordEnd := CurWord.X + CurWord.Width; - - // Slide Effect - // simply paint the active texture to the current position - if Ini.LyricsEffect = 2 then - begin - CurWordStart := CurWordStart + CurWord.Width * Progress; - CurWordEnd := CurWordStart; - end; - - if CurWord.Freestyle then - begin - if (Line.CurWord < High(Line.Words)) and - (not Line.Words[Line.CurWord + 1].Freestyle) then - begin - FreestyleDiff := 2; - end - else - begin - FreestyleDiff := 12; - CurWordStart := CurWordStart - 1; - CurWordEnd := CurWordEnd - 2; - end; - end; - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, Line.Tex); - - // draw sentence up to current word - // type 0: simple lyric effect - // type 3: ball lyric effect - // type 4: shift lyric effect - if (Ini.LyricsEffect in [0, 3, 4]) then - // ball lyric effect - only highlight current word and not that ones before in this line - glColorRGB(LineColor_en, Alpha) - else - glColorRGB(LineColor_act, Alpha); - - glBegin(GL_QUADS); - glTexCoord2f(0, 1); - glVertex2f(LyricX, LyricY); - - glTexCoord2f(0, 1-LyricsHeight/64); - glVertex2f(LyricX, LyricY + LyricsHeight); - - glTexCoord2f(CurWordStart/1024, 1-LyricsHeight/64); - glVertex2f(LyricX + CurWordStart, LyricY + LyricsHeight); - - glTexCoord2f((CurWordStart + FreestyleDiff)/1024, 1); - glVertex2f(LyricX + CurWordStart + FreestyleDiff, LyricY); - glEnd; - - // draw rest of sentence - glColorRGB(LineColor_en, Alpha); - glBegin(GL_QUADS); - glTexCoord2f((CurWordEnd + FreestyleDiff)/1024, 1); - glVertex2f(LyricX + CurWordEnd + FreestyleDiff, LyricY); - - glTexCoord2f(CurWordEnd/1024, 1-LyricsHeight/64); - glVertex2f(LyricX + CurWordEnd, LyricY + LyricsHeight); - - glTexCoord2f(Line.Width/1024, 1-LyricsHeight/64); - glVertex2f(LyricX2, LyricY + LyricsHeight); - - glTexCoord2f(Line.Width/1024, 1); - glVertex2f(LyricX2, LyricY); - glEnd; - - // draw active word: - // type 0: simple lyric effect - // type 3: ball lyric effect - // type 4: shift lyric effect - // only change the color of the current word - if (Ini.LyricsEffect in [0, 3, 4]) then - begin - if (Ini.LyricsEffect = 4) then - LyricY := LyricY - 8 * (1-Progress); - - glColor4f(LineColor_act.r, LineColor_act.g, LineColor_act.b, Alpha); - glBegin(GL_QUADS); - glTexCoord2f((CurWordStart + FreestyleDiff)/1024, 1); - glVertex2f(LyricX + CurWordStart + FreestyleDiff, LyricY); - - glTexCoord2f(CurWordStart/1024, 0); - glVertex2f(LyricX + CurWordStart, LyricY + 64); - - glTexCoord2f(CurWordEnd/1024, 0); - glVertex2f(LyricX + CurWordEnd, LyricY + 64); - - glTexCoord2f((CurWordEnd + FreestyleDiff)/1024, 1); - glVertex2f(LyricX + CurWordEnd + FreestyleDiff, LyricY); - glEnd; - - if (Ini.LyricsEffect = 4) then - LyricY := LyricY + 8 * (1-Progress); - end - - // draw active word: - // type 1: zoom lyric effect - // change color and zoom current word - else if Ini.LyricsEffect = 1 then - begin - glPushMatrix; - - glTranslatef(LyricX + CurWordStart + (CurWordEnd-CurWordStart)/2, - LyricY + LyricsHeight/2, 0); - - // set current zoom factor - glScalef(1.0 + (1-Progress) * 0.5, 1.0 + (1-Progress) * 0.5, 1.0); - - glColor4f(LineColor_act.r, LineColor_act.g, LineColor_act.b, Alpha); - glBegin(GL_QUADS); - glTexCoord2f((CurWordStart + FreestyleDiff)/1024, 1); - glVertex2f(-(CurWordEnd-CurWordStart)/2 + FreestyleDiff, -LyricsHeight/2); - - glTexCoord2f(CurWordStart/1024, 1-LyricsHeight/64); - glVertex2f(-(CurWordEnd-CurWordStart)/2, LyricsHeight/2); - - glTexCoord2f(CurWordEnd/1024, 1-LyricsHeight/64); - glVertex2f((CurWordEnd-CurWordStart)/2, LyricsHeight/2); - - glTexCoord2f((CurWordEnd + FreestyleDiff)/1024, 1); - glVertex2f((CurWordEnd-CurWordStart)/2 + FreestyleDiff, -LyricsHeight/2); - glEnd; - - glPopMatrix; - end; - - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - - // type 3: ball lyric effect - if Ini.LyricsEffect = 3 then - begin - DrawBall(LyricX + CurWordStart + (CurWordEnd-CurWordStart) * Progress, - LyricY - 15 - 15*sin(Progress * Pi), Alpha); - end; - end - else - begin - // this section is called if the whole line can be drawn at once and no - // word has to be emphasized. - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBindTexture(GL_TEXTURE_2D, Line.Tex); - - // enable the upper, disable the lower line - if (Line = UpperLine) then - glColorRGB(LineColor_en) - else - glColorRGB(LineColor_dis); - - glBegin(GL_QUADS); - glTexCoord2f(0, 1); - glVertex2f(LyricX, LyricY); - - glTexCoord2f(0, 1-LyricsHeight/64); - glVertex2f(LyricX, LyricY + LyricsHeight); - - glTexCoord2f(Line.Width/1024, 1-LyricsHeight/64); - glVertex2f(LyricX2, LyricY + LyricsHeight); - - glTexCoord2f(Line.Width/1024, 1); - glVertex2f(LyricX2, LyricY); - glEnd; - - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - end; -end; - -//--------------- -// GetUpperLine() - Returns a reference to the upper line -//--------------- -function TLyricEngine.GetUpperLine(): TLyricLine; -begin - Result := UpperLine; -end; - -//--------------- -// GetLowerLine() - Returns a reference to the lower line -//--------------- -function TLyricEngine.GetLowerLine(): TLyricLine; -begin - Result := LowerLine; -end; - -//--------------- -// GetUpperLineIndex() - Returns the index of the upper line -//--------------- -function TLyricEngine.GetUpperLineIndex(): Integer; -const - QUEUE_SIZE = 3; -begin - // no line in queue - if (LineCounter <= 0) then - Result := -1 - // no line has been removed from queue yet - else if (LineCounter <= QUEUE_SIZE) then - Result := 0 - // lines have been removed from queue already - else - Result := LineCounter - QUEUE_SIZE; -end; - -end. - |