From 26d8c209beba866f111a9d047bf1a70fe245b75d Mon Sep 17 00:00:00 2001 From: b1indy Date: Thu, 20 Sep 2007 07:19:45 +0000 Subject: new lyrics stuff; it's broken (lyrics don't show) and in "debug" mode (weird stuff going on in the singscreen) but i'm tired of editing conflicts git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@412 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UDraw.pas | 3167 +++++++++++++++++----------------- Game/Code/Classes/UGraphic.pas | 1222 ++++++------- Game/Code/Classes/ULyrics.pas | 777 +++++---- Game/Code/Classes/UMain.pas | 1588 ++++++++--------- Game/Code/Classes/UMusic.pas | 1466 ++++++++-------- Game/Code/Classes/UThemes.pas | 4 + Game/Code/Screens/UScreenEditSub.pas | 2 +- Game/Code/Screens/UScreenSing.pas | 2557 +++++++++++++-------------- Game/Code/UltraStar.dpr | 92 +- 9 files changed, 5520 insertions(+), 5355 deletions(-) (limited to 'Game/Code') diff --git a/Game/Code/Classes/UDraw.pas b/Game/Code/Classes/UDraw.pas index ef1f2709..4c5d2ce0 100644 --- a/Game/Code/Classes/UDraw.pas +++ b/Game/Code/Classes/UDraw.pas @@ -1,1583 +1,1584 @@ -unit UDraw; - -interface - -{$IFDEF FPC} - {$MODE DELPHI} -{$ENDIF} - -uses UThemes, - ModiSDK, - UGraphicClasses; - -procedure SingDraw; -procedure SingModiDraw (PlayerInfo: TPlayerInfo); -procedure SingDrawBackground; -procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer); -procedure SingDrawNoteLines(Left, Top, Right: real; Space: integer); -procedure SingDrawBeatDelimeters(Left, Top, Right: real; NrCzesci: integer); -procedure SingDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer); -procedure SingDrawPlayerCzesc(X, Y, W: real; NrGracza: integer; Space: integer); -procedure SingDrawPlayerBGCzesc(Left, Top, Right: real; NrCzesci, NrGracza: integer; Space: integer); - -// TimeBar -procedure SingDrawTimeBar(); - -// The Singbar -procedure SingDrawSingbar(X, Y, W, H: real; Percent: integer); - -//Phrasen Bonus - Line Bonus -procedure SingDrawLineBonus( const X, Y: Single; Color: TRGB; Alpha: Single; Text: string; Age: Integer); - -//Draw Editor NoteLines -procedure EditDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer); - - -type - TRecR = record - Top: real; - Left: real; - Right: real; - Bottom: real; - - Width: real; - WMid: real; - Height: real; - HMid: real; - - Mid: real; - end; - -var - NotesW: real; - NotesH: real; - Starfr: integer; - StarfrG: integer; - - //SingBar - TickOld: cardinal; - TickOld2:cardinal; - -const - Przedz = 32; - -implementation - -uses {$IFDEF Win32} - windows, - {$ELSE} - lclintf, - {$ENDIF} - OpenGL12, - UGraphic, - SysUtils, - UMusic, - URecord, - ULog, - UScreenSing, - UScreenSingModi, - ULyrics, - UMain, - TextGL, - UTexture, - UDrawTexture, - UIni, - Math, - UDLLManager; - -procedure SingDrawBackground; -var - Rec: TRecR; - TexRec: TRecR; -begin - if ScreenSing.Tex_Background.TexNum >= 1 then begin - - glClearColor (1, 1, 1, 1); - glColor4f (1, 1, 1, 1); - - if (Ini.MovieSize <= 1) then //HalfSize BG - begin - (* half screen + gradient *) - Rec.Top := 110; // 80 - Rec.Bottom := Rec.Top + 20; - Rec.Left := 0; - Rec.Right := 800; - - TexRec.Top := (Rec.Top / 600) * ScreenSing.Tex_Background.TexH; - TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH; - TexRec.Left := 0; - TexRec.Right := ScreenSing.Tex_Background.TexW; - - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, ScreenSing.Tex_Background.TexNum); - glEnable(GL_BLEND); - glBegin(GL_QUADS); - (* gradient draw *) - (* top *) - glColor4f(1, 1, 1, 0); - glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top); - glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top); - glColor4f(1, 1, 1, 1); - glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom); - (* mid *) - Rec.Top := Rec.Bottom; - Rec.Bottom := 490 - 20; // 490 - 20 - TexRec.Top := TexRec.Bottom; - TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH; - glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top); - (* bottom *) - Rec.Top := Rec.Bottom; - Rec.Bottom := 490; // 490 - TexRec.Top := TexRec.Bottom; - TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH; - glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top); - glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top); - glColor4f(1, 1, 1, 0); - glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom); - - glEnd; - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - end - else //Full Size BG - begin - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, ScreenSing.Tex_Background.TexNum); - //glEnable(GL_BLEND); - glBegin(GL_QUADS); - - glTexCoord2f(0, 0); glVertex2f(0, 0); - glTexCoord2f(0, ScreenSing.Tex_Background.TexH); glVertex2f(0, 600); - glTexCoord2f( ScreenSing.Tex_Background.TexW, ScreenSing.Tex_Background.TexH); glVertex2f(800, 600); - glTexCoord2f( ScreenSing.Tex_Background.TexW, 0); glVertex2f(800, 0); - - glEnd; - glDisable(GL_TEXTURE_2D); - //glDisable(GL_BLEND); - end; - end; -end; - -procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer); -var - Pet: integer; -begin; -// Log.LogStatus('Oscilloscope', 'SingDraw'); - glColor3f(Skin_OscR, Skin_OscG, Skin_OscB); - {if (ParamStr(1) = '-black') or (ParamStr(1) = '-fsblack') then - glColor3f(1, 1, 1); } - - glBegin(GL_LINE_STRIP); - glVertex2f(X, -Sound[NrSound].BufferArray[1] / $10000 * H + Y + H/2); - for Pet := 2 to Sound[NrSound].n div 1 do begin - glVertex2f(X + (Pet-1) * W / (Sound[NrSound].n - 1), - -Sound[NrSound].BufferArray[Pet] / $10000 * H + Y + H/2); - end; - glEnd; -end; - -procedure SingDrawNoteLines(Left, Top, Right: real; Space: integer); -var - Pet: integer; -begin - glEnable(GL_BLEND); - glColor4f(Skin_P1_LinesR, Skin_P1_LinesG, Skin_P1_LinesB, 0.4); - glBegin(GL_LINES); - for Pet := 0 to 9 do begin - glVertex2f(Left, Top + Pet * Space); - glVertex2f(Right, Top + Pet * Space); - end; - glEnd; - glDisable(GL_BLEND); -end; - -procedure SingDrawBeatDelimeters(Left, Top, Right: real; NrCzesci: integer); -var - Pet: integer; - TempR: real; -begin - TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote); - glEnable(GL_BLEND); - glBegin(GL_LINES); - for Pet := Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote to Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec do begin - if (Pet mod Czesci[NrCzesci].Resolution) = Czesci[NrCzesci].NotesGAP then - glColor4f(0, 0, 0, 1) - else - glColor4f(0, 0, 0, 0.3); - glVertex2f(Left + TempR * (Pet - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote), Top); - glVertex2f(Left + TempR * (Pet - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote), Top + 135); - end; - glEnd; - glDisable(GL_BLEND); -end; - -// draw blank Notebars -procedure SingDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer); -var - Rec: TRecR; - Pet: integer; - TempR: real; - R,G,B: real; - - PlayerNumber: Integer; - - GoldenStarPos : real; -begin -// We actually don't have a playernumber in this procedure, it should reside in NrCzesci - but it's always set to zero -// So we exploit this behavior a bit - we give NrCzesci the playernumber, keep it in playernumber - and then we set NrCzesci to zero -// This could also come quite in handy when we do the duet mode, cause just the notes for the player that has to sing should be drawn then -// BUT this is not implemented yet, all notes are drawn! :D - - PlayerNumber := NrCzesci + 1; // Player 1 is 0 - NrCzesci := 0; - -// exploit done - - glColor3f(1, 1, 1); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote); - with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt] do begin - for Pet := 0 to HighNut do begin - with Nuta[Pet] do begin - if not FreeStyle then begin - - - if Ini.EffectSing = 0 then - // If Golden note Effect of then Change not Color - begin - case Wartosc of - 1: glColor4f(1, 1, 1, 1); // We set alpha to 1, cause we can control the transparency through the png itself - 2: glColor4f(1, 1, 0.3, 1); // no stars, paint yellow -> glColor4f(1, 1, 0.3, 0.85); - we could - end; // case - end //Else all Notes same Color - else - glColor4f(1, 1, 1, 1); // We set alpha to 1, cause we can control the transparency through the png itself - // Czesci == teil, element == piece, element | koniec == ende, schluss - // lewa czesc - left part - Rec.Left := (Start-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left + 0.5 + 10*ScreenX; - Rec.Right := Rec.Left + NotesW; - Rec.Top := Top - (Ton-BaseNote)*Space/2 - NotesH; - Rec.Bottom := Rec.Top + 2 * NotesH; - glBindTexture(GL_TEXTURE_2D, Tex_plain_Left[PlayerNumber].TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - - //We keep the postion of the top left corner b4 it's overwritten - GoldenStarPos := Rec.Left; - //done - - // srodkowa czesc - middle part - Rec.Left := Rec.Right; - Rec.Right := (Start+Dlugosc-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left - NotesW - 0.5 + 10*ScreenX; // Dlugosc == länge - - glBindTexture(GL_TEXTURE_2D, Tex_plain_Mid[PlayerNumber].TexNum); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(round((Rec.Right-Rec.Left)/32), 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(round((Rec.Right-Rec.Left)/32), 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - - // prawa czesc - right part - Rec.Left := Rec.Right; - Rec.Right := Rec.Right + NotesW; - - glBindTexture(GL_TEXTURE_2D, Tex_plain_Right[PlayerNumber].TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - - // Golden Star Patch - if (Wartosc = 2) AND (Ini.EffectSing=1) then - begin - GoldenRec.SaveGoldenStarsRec(GoldenStarPos, Rec.Top, Rec.Right, Rec.Bottom); - end; - - end; // if not FreeStyle - end; // with - end; // for - end; // with - - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); -end; - - -// draw sung notes -procedure SingDrawPlayerCzesc(X, Y, W: real; NrGracza: integer; Space: integer); -var - TempR: real; - Rec: TRecR; - N: integer; - R: real; - G: real; - B: real; - A: real; - NotesH2: real; - begin -// Log.LogStatus('Player notes', 'SingDraw'); - -// if NrGracza = 0 then LoadColor(R, G, B, 'P1Light') -// else LoadColor(R, G, B, 'P2Light'); - -// R := 71/255; -// G := 175/255; -// B := 247/255; - - glColor3f(1, 1, 1); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - if Player[NrGracza].IlNut > 0 then - begin - TempR := W / (Czesci[0].Czesc[Czesci[0].Akt].Koniec - Czesci[0].Czesc[Czesci[0].Akt].StartNote); - for N := 0 to Player[NrGracza].HighNut do - begin - with Player[NrGracza].Nuta[N] do - begin - // Left part of note - Rec.Left := X + (Start-Czesci[0].Czesc[Czesci[0].Akt].StartNote) * TempR + 0.5 + 10*ScreenX; - Rec.Right := Rec.Left + NotesW; - - // Draw it in half size, if not hit - if Hit then - begin - NotesH2 := NotesH - end - else - begin - NotesH2 := int(NotesH * 0.65); - end; - - Rec.Top := Y - (Ton-Czesci[0].Czesc[Czesci[0].Akt].BaseNote)*Space/2 - NotesH2; - Rec.Bottom := Rec.Top + 2 *NotesH2; - - // draw the left part - glColor3f(1, 1, 1); - glBindTexture(GL_TEXTURE_2D, Tex_Left[NrGracza+1].TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - - // Middle part of the note - Rec.Left := Rec.Right; - Rec.Right := X + (Start+Dlugosc-Czesci[0].Czesc[Czesci[0].Akt].StartNote) * TempR - NotesW - 0.5 + 10*ScreenX; - - // (nowe) - dunno - if (Start+Dlugosc-1 = Czas.AktBeatD) then - Rec.Right := Rec.Right - (1-Frac(Czas.MidBeatD)) * TempR; - // the left note is more right than the right note itself, sounds weird - so we fix that xD - if Rec.Right <= Rec.Left then Rec.Right := Rec.Left; - - // draw the middle part - glBindTexture(GL_TEXTURE_2D, Tex_Mid[NrGracza+1].TexNum); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); - glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(round((Rec.Right-Rec.Left)/32), 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(round((Rec.Right-Rec.Left)/32), 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - glColor3f(1, 1, 1); - - // the right part of the note - Rec.Left := Rec.Right; - Rec.Right := Rec.Right + NotesW; - - glBindTexture(GL_TEXTURE_2D, Tex_Right[NrGracza+1].TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - - // Perfect note is stored - if Perfect and (Ini.EffectSing=1) then - begin - A := 1 - 2*(Czas.Teraz - GetTimeFromBeat(Start+Dlugosc)); - if not (Start+Dlugosc-1 = Czas.AktBeatD) then - - //Star animation counter - //inc(Starfr); - //Starfr := Starfr mod 128; - GoldenRec.SavePerfectNotePos(Rec.Left, Rec.Top); - end; - end; // with - end; // for - // eigentlich brauchen wir hier einen vergleich, um festzustellen, ob wir mit - // singen schon weiter wären, als bei Rec.Right, _auch, wenn nicht gesungen wird_ - - // passing on NrGracza... hope this is really something like the player-number, not only - // some kind of weird index into a colour-table - - if (Ini.EffectSing=1) then - GoldenRec.GoldenNoteTwinkle(Rec.Top,Rec.Bottom,Rec.Right, NrGracza); - end; // if -end; - -//draw Note glow -procedure SingDrawPlayerBGCzesc(Left, Top, Right: real; NrCzesci, NrGracza: integer; Space: integer); -var - Rec: TRecR; - Pet: integer; - TempR: real; - R,G,B: real; - X1, X2, X3, X4: real; - W, H: real; -begin - if (Player[NrGracza].ScoreTotalI >= 0) then begin - glColor4f(1, 1, 1, sqrt((1+sin(Music.Position * 3))/4)/ 2 + 0.5 ); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote); - with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt] do begin - for Pet := 0 to HighNut do begin - with Nuta[Pet] do begin - if not FreeStyle then begin - // begin: 14, 20 - // easy: 6, 11 - W := NotesW * 2 + 2; - H := NotesH * 1.5 + 3.5; - - X2 := (Start-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left + 0.5 + 10*ScreenX + 4; // wciecie - X1 := X2-W; - - X3 := (Start+Dlugosc-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left - 0.5 + 10*ScreenX - 4; // wciecie - X4 := X3+W; - - // left - Rec.Left := X1; - Rec.Right := X2; - Rec.Top := Top - (Ton-BaseNote)*Space/2 - H; - Rec.Bottom := Rec.Top + 2 * H; - - glBindTexture(GL_TEXTURE_2D, Tex_BG_Left[NrGracza+1].TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - - - // srodkowa czesc - Rec.Left := X2; - Rec.Right := X3; - - glBindTexture(GL_TEXTURE_2D, Tex_BG_Mid[NrGracza+1].TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - - // prawa czesc - Rec.Left := X3; - Rec.Right := X4; - - glBindTexture(GL_TEXTURE_2D, Tex_BG_Right[NrGracza+1].TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - end; // if not FreeStyle - end; // with - end; // for - end; // with - - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - end; -end; - -procedure SingDraw; -var - Pet: integer; - Pet2: integer; - TempR: real; - Rec: TRecR; - TexRec: TRecR; - NR: TRecR; - FS: real; - BarFrom: integer; - BarAlpha: real; - BarWspol: real; - TempCol: real; - Tekst: string; - LyricTemp: string; - PetCz: integer; - - //SingBar Mod - A: Integer; - E: Integer; - I: Integer; - //end Singbar Mod - -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; - - // background //BG Fullsize Mod - //SingDrawBackground; - - //TimeBar mod - SingDrawTimeBar(); - //eoa TimeBar mod - - // rysuje paski pod nutami - if PlayersPlay = 1 then - SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15); - if (PlayersPlay = 2) or (PlayersPlay = 4) then begin - SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P1_NotesB - 105, Nr.Right + 10*ScreenX, 15); - SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15); - end; - - if (PlayersPlay = 3) or (PlayersPlay = 6) then begin - SingDrawNoteLines(Nr.Left + 10*ScreenX, 120, Nr.Right + 10*ScreenX, 12); - SingDrawNoteLines(Nr.Left + 10*ScreenX, 245, Nr.Right + 10*ScreenX, 12); - SingDrawNoteLines(Nr.Left + 10*ScreenX, 370, Nr.Right + 10*ScreenX, 12); - end; - - // rysuje tekst - new Lyric engine - ScreenSing.LyricMain.Draw; - ScreenSing.LyricSub.Draw; - - // rysuje pasek, podpowiadajacy poczatek spiwania w scenie - FS := 1.3; - BarFrom := Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start; - if BarFrom > 40 then BarFrom := 40; - if (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start > 8) and // dluga przerwa //16->12 for more help bars and then 12->8 for even more - (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat > 0) and // przed tekstem - (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat < 40) then begin // ale nie za wczesnie - BarWspol := (Czas.MidBeat - (Czesci[0].Czesc[Czesci[0].Akt].StartNote - BarFrom)) / BarFrom; - Rec.Left := NR.Left + BarWspol * -// (NR.WMid - Czesci[0].Czesc[Czesci[0].Akt].LyricWidth / 2 * FS - 50); - (ScreenSing.LyricMain.ClientX - NR.Left - 50) + 10*ScreenX; - Rec.Right := Rec.Left + 50; - Rec.Top := Skin_LyricsT + 3; - Rec.Bottom := Rec.Top + 33;//SingScreen.LyricMain.Size * 3; -{ // zapalanie - BarAlpha := (BarWspol*10) * 0.5; - if BarAlpha > 0.5 then BarAlpha := 0.5; - - // gaszenie - if BarWspol > 0.95 then BarAlpha := 0.5 * (1 - (BarWspol - 0.95) * 20);} - - //Change fuer Crazy Joker - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBindTexture(GL_TEXTURE_2D, Tex_Lyric_Help_Bar.TexNum); - glBegin(GL_QUADS); - glColor4f(1, 1, 1, 0); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glColor4f(1, 1, 1, 0.5); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - glDisable(GL_BLEND); - - end; - - // oscilloscope - if Ini.Oscilloscope = 1 then begin - if PlayersPlay = 1 then - SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); - - if PlayersPlay = 2 then begin - SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); - SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1); - end; - - if PlayersPlay = 4 then begin - if ScreenAct = 1 then begin - SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); - SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1); - end; - if ScreenAct = 2 then begin - SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2); - SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3); - end; - end; - - if PlayersPlay = 3 then begin - SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0); - SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1); - SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2); - end; - - if PlayersPlay = 6 then begin - if ScreenAct = 1 then begin - SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0); - SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1); - SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2); - end; - if ScreenAct = 2 then begin - SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3); - SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4); - SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5); - end; - end; - - end - - //SingBar Mod - //modded again to make it moveable: it's working, so why try harder - else if Ini.Oscilloscope = 2 then - begin - A := GetTickCount div 33; - if A <> Tickold then begin - Tickold := A; - for E := 0 to (PlayersPlay - 1) do begin //Set new Pos + Alpha - I := Player[E].ScorePercentTarget - Player[E].ScorePercent; - if I > 0 then Inc(Player[E].ScorePercent) - else if I < 0 then Dec(Player[E].ScorePercent); - end; //for - end; //if - - if PlayersPlay = 1 then begin - SingDrawSingbar(Theme.Sing.StaticP1SingBar.x, Theme.Sing.StaticP1SingBar.y, Theme.Sing.StaticP1SingBar.w, Theme.Sing.StaticP1SingBar.h , Player[0].ScorePercent); - end; - - if PlayersPlay = 2 then begin - SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent); - SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent); - end; - - if PlayersPlay = 3 then begin - SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent); - SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent); - SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent); - end; - - if PlayersPlay = 4 then begin - if ScreenAct = 1 then begin - SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent); - SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent); - end; - if ScreenAct = 2 then begin - SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[2].ScorePercent); - SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[3].ScorePercent); - end; - end; - - if PlayersPlay = 6 then begin - if ScreenAct = 1 then begin - SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent); - SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent); - SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent); - end; - if ScreenAct = 2 then begin - SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[3].ScorePercent); - SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[4].ScorePercent); - SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[5].ScorePercent); - end; - end; - end; - //end Singbar Mod - - //PhrasenBonus - Line Bonus Mod - if Ini.LineBonus > 0 then begin - A := GetTickCount div 33; - if (A <> Tickold2) AND (Player[0].LineBonus_Visible) then begin - Tickold2 := A; - for E := 0 to (PlayersPlay - 1) do begin - //Change Alpha - Player[E].LineBonus_Alpha := Player[E].LineBonus_Alpha - 0.02; - if Player[E].LineBonus_Alpha <= 0 then - begin - Player[E].LineBonus_Age := 0; - Player[E].LineBonus_Visible := False - end - else - begin - inc(Player[E].LineBonus_Age, 1); - //Change Position - if (Player[E].LineBonus_PosX < Player[E].LineBonus_TargetX) then - Player[E].LineBonus_PosX := Player[E].LineBonus_PosX + (2 - Player[E].LineBonus_Alpha * 1.5) - else if (Player[E].LineBonus_PosX > Player[E].LineBonus_TargetX) then - Player[E].LineBonus_PosX := Player[E].LineBonus_PosX - (2 - Player[E].LineBonus_Alpha * 1.5); - - if (Player[E].LineBonus_PosY < Player[E].LineBonus_TargetY) then - Player[E].LineBonus_PosY := Player[E].LineBonus_PosY + (2 - Player[E].LineBonus_Alpha * 1.5) - else if (Player[E].LineBonus_PosY > Player[E].LineBonus_TargetY) then - Player[E].LineBonus_PosY := Player[E].LineBonus_PosY - (2 - Player[E].LineBonus_Alpha * 1.5); - - end; // shift position of the pop up (if not dead) - end; // loop - for all players - end; // if - linebonus - - - if PlayersPlay = 1 then begin - SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); - end - - else if PlayersPlay = 2 then begin - SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); - SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); - end - - else if PlayersPlay = 3 then begin - SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); - SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); - SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age); - end - - else if PlayersPlay = 4 then begin - if ScreenAct = 1 then begin - SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); - SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); - end; - if ScreenAct = 2 then begin - SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age); - SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age); - end; - end; - - if PlayersPlay = 6 then begin - if ScreenAct = 1 then begin - SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); - SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); - SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age); - end; - if ScreenAct = 2 then begin - SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age); - SingDrawLineBonus( Player[4].LineBonus_PosX, Player[4].LineBonus_PosY, Player[4].LineBonus_Color, Player[4].LineBonus_Alpha, Player[4].LineBonus_Text, Player[4].LineBonus_Age); - SingDrawLineBonus( Player[5].LineBonus_PosX, Player[5].LineBonus_PosY, Player[5].LineBonus_Color, Player[5].LineBonus_Alpha, Player[5].LineBonus_Text, Player[5].LineBonus_Age); - end; - end; - end; - //PhrasenBonus - Line Bonus Mod End - -// Set the note heights according to the difficulty level - case Ini.Difficulty of - 0: - begin - NotesH := 11; // 9 - NotesW := 6; // 5 - end; - 1: - begin - NotesH := 8; // 7 - NotesW := 4; // 4 - end; - 2: - begin - NotesH := 5; - NotesW := 3; - end; - end; - -// Draw the Notes - if PlayersPlay = 1 then begin - SingDrawPlayerBGCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 0, 15); // Background glow - colorized in playercolor - SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15); // Plain unsung notes - colorized in playercolor - SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 15); // imho the sung notes - end; - - if (PlayersPlay = 2) then begin - SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15); - SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15); - - SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15); - SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 1, 15); - - SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15); - SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15); - end; - - if PlayersPlay = 3 then begin - NotesW := NotesW * 0.8; - NotesH := NotesH * 0.8; - - SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12); - SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12); - SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12); - - SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12); - SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 1, 12); - SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 2, 12); - - SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12); - SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12); - SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12); - end; - - if PlayersPlay = 4 then begin - if ScreenAct = 1 then begin - SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15); - SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15); - end; - if ScreenAct = 2 then begin - SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 2, 15); - SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 3, 15); - end; - - if ScreenAct = 1 then begin - SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15); - SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 1, 15); - end; - if ScreenAct = 2 then begin - SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 2, 15); - SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 3, 15); - end; - - if ScreenAct = 1 then begin - SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15); - SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15); - end; - if ScreenAct = 2 then begin - SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 2, 15); - SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 3, 15); - end; - end; - - if PlayersPlay = 6 then begin - NotesW := NotesW * 0.8; - NotesH := NotesH * 0.8; - - if ScreenAct = 1 then begin - SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12); - SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12); - SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12); - end; - if ScreenAct = 2 then begin - SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 3, 12); - SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 4, 12); - SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 5, 12); - end; - - if ScreenAct = 1 then begin - SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12); - SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 1, 12); - SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 2, 12); - end; - if ScreenAct = 2 then begin - SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 3, 12); - SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 4, 12); - SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 5, 12); - end; - - if ScreenAct = 1 then begin - SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12); - SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12); - SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12); - end; - if ScreenAct = 2 then begin - SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 3, 12); - SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 4, 12); - SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 5, 12); - end; - end; - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); -end; - -// q'n'd for using the game mode dll's -procedure SingModiDraw (PlayerInfo: TPlayerInfo); -var - Pet: integer; - Pet2: integer; - TempR: real; - Rec: TRecR; - TexRec: TRecR; - NR: TRecR; - FS: real; - BarFrom: integer; - BarAlpha: real; - BarWspol: real; - TempCol: real; - Tekst: string; - LyricTemp: string; - PetCz: integer; - - //SingBar Mod - A: Integer; - E: Integer; - I: Integer; - //end Singbar Mod - -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; - - // time bar - SingDrawTimeBar(); - - if DLLMan.Selected.ShowNotes then - begin - if PlayersPlay = 1 then - SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15); - if (PlayersPlay = 2) or (PlayersPlay = 4) then begin - SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P1_NotesB - 105, Nr.Right + 10*ScreenX, 15); - SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15); - end; - - if (PlayersPlay = 3) or (PlayersPlay = 6) then begin - SingDrawNoteLines(Nr.Left + 10*ScreenX, 120, Nr.Right + 10*ScreenX, 12); - SingDrawNoteLines(Nr.Left + 10*ScreenX, 245, Nr.Right + 10*ScreenX, 12); - SingDrawNoteLines(Nr.Left + 10*ScreenX, 370, Nr.Right + 10*ScreenX, 12); - end; - end; - - // Lyric engine - ScreenSingModi.LyricMain.Draw; - ScreenSingModi.LyricSub.Draw; - - // rysuje pasek, podpowiadajacy poczatek spiwania w scenie - FS := 1.3; - BarFrom := Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start; - if BarFrom > 40 then BarFrom := 40; - if (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start > 8) and // dluga przerwa //16->12 for more help bars and then 12->8 for even more - (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat > 0) and // przed tekstem - (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat < 40) then begin // ale nie za wczesnie - BarWspol := (Czas.MidBeat - (Czesci[0].Czesc[Czesci[0].Akt].StartNote - BarFrom)) / BarFrom; - Rec.Left := NR.Left + BarWspol * (ScreenSingModi.LyricMain.ClientX - NR.Left - 50) + 10*ScreenX; - Rec.Right := Rec.Left + 50; - Rec.Top := Skin_LyricsT + 3; - Rec.Bottom := Rec.Top + 33;//SingScreen.LyricMain.Size * 3; - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBindTexture(GL_TEXTURE_2D, Tex_Lyric_Help_Bar.TexNum); - glBegin(GL_QUADS); - glColor4f(1, 1, 1, 0); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glColor4f(1, 1, 1, 0.5); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - glDisable(GL_BLEND); - end; - - // oscilloscope | the thing that moves when you yell into your mic (imho) - if (((Ini.Oscilloscope = 1) AND (DLLMan.Selected.ShowRateBar_O)) AND (NOT DLLMan.Selected.ShowRateBar)) then begin - if PlayersPlay = 1 then - if PlayerInfo.Playerinfo[0].Enabled then - SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); - - if PlayersPlay = 2 then begin - if PlayerInfo.Playerinfo[0].Enabled then - SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); - if PlayerInfo.Playerinfo[1].Enabled then - SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1); - end; - - if PlayersPlay = 4 then begin - if ScreenAct = 1 then begin - if PlayerInfo.Playerinfo[0].Enabled then - SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); - if PlayerInfo.Playerinfo[1].Enabled then - SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1); - end; - if ScreenAct = 2 then begin - if PlayerInfo.Playerinfo[2].Enabled then - SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2); - if PlayerInfo.Playerinfo[3].Enabled then - SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3); - end; - end; - - if PlayersPlay = 3 then begin - if PlayerInfo.Playerinfo[0].Enabled then - SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0); - if PlayerInfo.Playerinfo[1].Enabled then - SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1); - if PlayerInfo.Playerinfo[2].Enabled then - SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2); - end; - - if PlayersPlay = 6 then begin - if ScreenAct = 1 then begin - if PlayerInfo.Playerinfo[0].Enabled then - SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0); - if PlayerInfo.Playerinfo[1].Enabled then - SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1); - if PlayerInfo.Playerinfo[2].Enabled then - SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2); - end; - if ScreenAct = 2 then begin - if PlayerInfo.Playerinfo[3].Enabled then - SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3); - if PlayerInfo.Playerinfo[4].Enabled then - SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4); - if PlayerInfo.Playerinfo[5].Enabled then - SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5); - end; - end; - - end - - //SingBar Mod - // seems like we don't want the flicker thing, we want the linebonus rating bar beneath the scores - else if ((Ini.Oscilloscope = 2) AND (DLLMan.Selected.ShowRateBar_O)) OR (DLLMan.Selected.ShowRateBar) then begin - A := GetTickCount div 33; - if A <> Tickold then begin - Tickold := A; - for E := 0 to (PlayersPlay - 1) do begin //Set new Pos + Alpha - I := Player[E].ScorePercentTarget - Player[E].ScorePercent; - if I > 0 then Inc(Player[E].ScorePercent) - else if I < 0 then Dec(Player[E].ScorePercent); - end; //for - end; //if - - if PlayersPlay = 1 then begin - if PlayerInfo.Playerinfo[0].Enabled then - SingDrawSingbar(Theme.Sing.StaticP1SingBar.x, Theme.Sing.StaticP1SingBar.y, Theme.Sing.StaticP1SingBar.w, Theme.Sing.StaticP1SingBar.h , Player[0].ScorePercent); - end; - - if PlayersPlay = 2 then begin - if PlayerInfo.Playerinfo[0].Enabled then - SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent); - if PlayerInfo.Playerinfo[1].Enabled then - SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent); - end; - - if PlayersPlay = 3 then begin - if PlayerInfo.Playerinfo[0].Enabled then - SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent); - if PlayerInfo.Playerinfo[1].Enabled then - SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent); - if PlayerInfo.Playerinfo[2].Enabled then - SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent); - end; - - if PlayersPlay = 4 then begin - if ScreenAct = 1 then begin - if PlayerInfo.Playerinfo[0].Enabled then - SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent); - if PlayerInfo.Playerinfo[1].Enabled then - SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent); - end; - if ScreenAct = 2 then begin - if PlayerInfo.Playerinfo[2].Enabled then - SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[2].ScorePercent); - if PlayerInfo.Playerinfo[3].Enabled then - SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[3].ScorePercent); - end; - end; - - if PlayersPlay = 6 then begin - if ScreenAct = 1 then begin - if PlayerInfo.Playerinfo[0].Enabled then - SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent); - if PlayerInfo.Playerinfo[1].Enabled then - SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent); - if PlayerInfo.Playerinfo[2].Enabled then - SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent); - end; - if ScreenAct = 2 then begin - if PlayerInfo.Playerinfo[3].Enabled then - SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[3].ScorePercent); - if PlayerInfo.Playerinfo[4].Enabled then - SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[4].ScorePercent); - if PlayerInfo.Playerinfo[5].Enabled then - SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[5].ScorePercent); - end; - end; - end; - //end Singbar Mod - - //PhrasenBonus - Line Bonus Mod - if ((Ini.LineBonus > 0) AND (DLLMan.Selected.EnLineBonus_O)) OR (DLLMan.Selected.EnLineBonus) then begin - A := GetTickCount div 33; - if (A <> Tickold2) AND (Player[0].LineBonus_Visible) then begin - Tickold2 := A; - for E := 0 to (PlayersPlay - 1) do begin - //Change Alpha - Player[E].LineBonus_Alpha := Player[E].LineBonus_Alpha - 0.02; - - if Player[E].LineBonus_Alpha <= 0 then - begin - Player[E].LineBonus_Age := 0; - Player[E].LineBonus_Visible := False - end - else - begin - inc(Player[E].LineBonus_Age, 1); - //Change Position - if (Player[E].LineBonus_PosX < Player[E].LineBonus_TargetX) then // pop up has not yet reached it's position -> blend in - Player[E].LineBonus_PosX := Player[E].LineBonus_PosX + (2 - Player[E].LineBonus_Alpha * 1.5) - else if (Player[E].LineBonus_PosX > Player[E].LineBonus_TargetX) then // pop up has reached it's position -> blend out - Player[E].LineBonus_PosX := Player[E].LineBonus_PosX - (2 - Player[E].LineBonus_Alpha * 1.5); - - if (Player[E].LineBonus_PosY < Player[E].LineBonus_TargetY) then - Player[E].LineBonus_PosY := Player[E].LineBonus_PosY + (2 - Player[E].LineBonus_Alpha * 1.5) - else if (Player[E].LineBonus_PosY > Player[E].LineBonus_TargetY) then - Player[E].LineBonus_PosY := Player[E].LineBonus_PosY - (2 - Player[E].LineBonus_Alpha * 1.5); - - end; // pop up still visible, has not reached it's position - move it - end; // loop through all players - end; // if it's time to draw them - - if PlayersPlay = 1 then begin - if PlayerInfo.Playerinfo[0].Enabled then - SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); - end - - else if PlayersPlay = 2 then begin - if PlayerInfo.Playerinfo[0].Enabled then - SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); - if PlayerInfo.Playerinfo[1].Enabled then - SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); - end - - else if PlayersPlay = 3 then begin - if PlayerInfo.Playerinfo[0].Enabled then - SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); - if PlayerInfo.Playerinfo[1].Enabled then - SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); - if PlayerInfo.Playerinfo[2].Enabled then - SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age); - end - - else if PlayersPlay = 4 then begin - if ScreenAct = 1 then begin - if PlayerInfo.Playerinfo[0].Enabled then - SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); - if PlayerInfo.Playerinfo[1].Enabled then - SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); - end; - if ScreenAct = 2 then begin - if PlayerInfo.Playerinfo[2].Enabled then - SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age); - if PlayerInfo.Playerinfo[3].Enabled then - SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age); - end; - end; - - if PlayersPlay = 6 then begin - if ScreenAct = 1 then begin - if PlayerInfo.Playerinfo[0].Enabled then - SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); - if PlayerInfo.Playerinfo[1].Enabled then - SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); - if PlayerInfo.Playerinfo[2].Enabled then - SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age); - end; - if ScreenAct = 2 then begin - if PlayerInfo.Playerinfo[3].Enabled then - SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age); - if PlayerInfo.Playerinfo[4].Enabled then - SingDrawLineBonus( Player[4].LineBonus_PosX, Player[4].LineBonus_PosY, Player[4].LineBonus_Color, Player[4].LineBonus_Alpha, Player[4].LineBonus_Text, Player[4].LineBonus_Age); - if PlayerInfo.Playerinfo[5].Enabled then - SingDrawLineBonus( Player[5].LineBonus_PosX, Player[5].LineBonus_PosY, Player[5].LineBonus_Color, Player[5].LineBonus_Alpha, Player[5].LineBonus_Text, Player[5].LineBonus_Age); - end; - end; - end; -//PhrasenBonus - Line Bonus Mod End - -// resize the notes according to the difficulty level - case Ini.Difficulty of - 0: - begin - NotesH := 11; // 9 - NotesW := 6; // 5 - end; - 1: - begin - NotesH := 8; // 7 - NotesW := 4; // 4 - end; - 2: - begin - NotesH := 5; - NotesW := 3; - end; - end; - - if (DLLMAn.Selected.ShowNotes And DLLMan.Selected.LoadSong) then - begin - if (PlayersPlay = 1) And PlayerInfo.Playerinfo[0].Enabled then begin - SingDrawPlayerBGCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 0, 15); - SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15); - SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 15); - end; - - if (PlayersPlay = 2) then begin - if PlayerInfo.Playerinfo[0].Enabled then - begin - SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15); - SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15); - SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15); - end; - if PlayerInfo.Playerinfo[1].Enabled then - begin - SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15); - SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15); - SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15); - end; - - end; - - if PlayersPlay = 3 then begin - NotesW := NotesW * 0.8; - NotesH := NotesH * 0.8; - - if PlayerInfo.Playerinfo[0].Enabled then - begin - SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12); - SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12); - SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12); - end; - - if PlayerInfo.Playerinfo[1].Enabled then - begin - SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12); - SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 0, 12); - SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12); - end; - - if PlayerInfo.Playerinfo[2].Enabled then - begin - SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12); - SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 0, 12); - SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12); - end; - end; - - if PlayersPlay = 4 then begin - if ScreenAct = 1 then begin - SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15); - SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15); - end; - if ScreenAct = 2 then begin - SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 2, 15); - SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 3, 15); - end; - - SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15); - SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15); - - if ScreenAct = 1 then begin - SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15); - SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15); - end; - if ScreenAct = 2 then begin - SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 2, 15); - SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 3, 15); - end; - end; - - if PlayersPlay = 6 then begin - NotesW := NotesW * 0.8; - NotesH := NotesH * 0.8; - - if ScreenAct = 1 then begin - SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12); - SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12); - SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12); - end; - if ScreenAct = 2 then begin - SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 3, 12); - SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 4, 12); - SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 5, 12); - end; - - SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12); - SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 0, 12); - SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 0, 12); - - if ScreenAct = 1 then begin - SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12); - SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12); - SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12); - end; - if ScreenAct = 2 then begin - SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 3, 12); - SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 4, 12); - SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 5, 12); - end; - end; - end; - - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); -end; - - -//SingBar Mod -procedure SingDrawSingbar(X, Y, W, H: real; Percent: integer); -var - R: Real; - G: Real; - B: Real; - A: cardinal; - I: Integer; - -begin; - - //SingBar Background - glColor4f(1, 1, 1, 0.8); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Back.TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(X, Y); - glTexCoord2f(0, 1); glVertex2f(X, Y+H); - glTexCoord2f(1, 1); glVertex2f(X+W, Y+H); - glTexCoord2f(1, 0); glVertex2f(X+W, Y); - glEnd; - - //SingBar coloured Bar - Case Percent of - 0..22: begin - R := 1; - G := 0; - B := 0; - end; - 23..42: begin - R := 1; - G := ((Percent-23)/100)*5; - B := 0; - end; - 43..57: begin - R := 1; - G := 1; - B := 0; - end; - 58..77: begin - R := 1-(Percent - 58)/100*5; - G := 1; - B := 0; - end; - 78..99: begin - R := 0; - G := 1; - B := 0; - end; - End; //Case - - glColor4f(R, G, B, 1); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Bar.TexNum); - //Size= Player[PlayerNum].ScorePercent of W - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(X, Y); - glTexCoord2f(0, 1); glVertex2f(X, Y+H); - glTexCoord2f(1, 1); glVertex2f(X+(W/100 * (Percent +1)), Y+H); - glTexCoord2f(1, 0); glVertex2f(X+(W/100 * (Percent +1)), Y); - glEnd; - - //SingBar Front - glColor4f(1, 1, 1, 0.6); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Front.TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(X, Y); - glTexCoord2f(0, 1); glVertex2f(X, Y+H); - glTexCoord2f(1, 1); glVertex2f(X+W, Y+H); - glTexCoord2f(1, 0); glVertex2f(X+W, Y); - glEnd; -end; -//end Singbar Mod - -//PhrasenBonus - Line Bonus Pop Up -procedure SingDrawLineBonus( const X, Y: Single; Color: TRGB; Alpha: Single; Text: string; Age: Integer); -var -Length, X2: Real; //Length of Text -Size: Integer; //Size of Popup -begin -if Alpha <> 0 then -begin - -//Set Font Propertys -SetFontStyle(2); //Font: Outlined1 -if Age < 5 then SetFontSize(Age + 1) else SetFontSize(6); -SetFontItalic(False); - -//Check Font Size -Length := glTextWidth ( PChar(Text)) + 3; //Little Space for a Better Look ^^ - -//Text -SetFontPos (X + 50 - (Length / 2), Y + 12); //Position - - -if Age < 5 then Size := Age * 10 else Size := 50; - - //Draw Background - //glColor4f(Color.R, Color.G, Color.B, Alpha); //Set Color - glColor4f(1, 1, 1, Alpha); - - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - - //New Method, Not Variable - glBindTexture(GL_TEXTURE_2D, Tex_SingLineBonusBack[2].TexNum); - - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(X + 50 - Size, Y + 25 - (Size/2)); - glTexCoord2f(0, 1); glVertex2f(X + 50 - Size, Y + 25 + (Size/2)); - glTexCoord2f(1, 1); glVertex2f(X + 50 + Size, Y + 25 + (Size/2)); - glTexCoord2f(1, 0); glVertex2f(X + 50 + Size, Y + 25 - (Size/2)); - glEnd; - - glColor4f(1, 1, 1, Alpha); //Set Color - //Draw Text - glPrint (PChar(Text)); -end; -end; -//PhrasenBonus - Line Bonus Mod - -// Draw Note Bars for Editor -//There are 11 Resons for a new Procdedure: -// 1. It don't look good when you Draw the Golden Note Star Effect in the Editor -// 2. You can see the Freestyle Notes in the Editor SemiTransparent -// 3. Its easier and Faster then changing the old Procedure -procedure EditDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer); -var - Rec: TRecR; - Pet: integer; - TempR: real; -begin - glColor3f(1, 1, 1); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote); - with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt] do begin - for Pet := 0 to HighNut do begin - with Nuta[Pet] do begin - - // Golden Note Patch - case Wartosc of - 0: glColor4f(1, 1, 1, 0.35); - 1: glColor4f(1, 1, 1, 0.85); - 2: glColor4f(1, 1, 0.3, 0.85); - end; // case - - - - // lewa czesc - left part - Rec.Left := (Start-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left + 0.5 + 10*ScreenX; - Rec.Right := Rec.Left + NotesW; - Rec.Top := Top - (Ton-BaseNote)*Space/2 - NotesH; - Rec.Bottom := Rec.Top + 2 * NotesH; - glBindTexture(GL_TEXTURE_2D, Tex_Left[Color].TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - - // srodkowa czesc - middle part - Rec.Left := Rec.Right; - Rec.Right := (Start+Dlugosc-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left - NotesW - 0.5 + 10*ScreenX; - - glBindTexture(GL_TEXTURE_2D, Tex_Mid[Color].TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - - // prawa czesc - right part - Rec.Left := Rec.Right; - Rec.Right := Rec.Right + NotesW; - - glBindTexture(GL_TEXTURE_2D, Tex_Right[Color].TexNum); - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); - glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); - glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); - glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); - glEnd; - - end; // with - end; // for - end; // with - - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); -end; - -procedure SingDrawTimeBar(); -var x,y: real; - width, height: real; -begin - x := Theme.Sing.StaticTimeProgress.x; - y := Theme.Sing.StaticTimeProgress.y; - width:= Theme.Sing.StaticTimeProgress.w; - height:= Theme.Sing.StaticTimeProgress.h; - - glColor4f(Theme.Sing.StaticTimeProgress.ColR, - Theme.Sing.StaticTimeProgress.ColG, - Theme.Sing.StaticTimeProgress.ColB, 1); //Set Color - - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - - glBindTexture(GL_TEXTURE_2D, Tex_TimeProgress.TexNum); - - glBegin(GL_QUADS); - glTexCoord2f(0, 0); glVertex2f(x,y); - glTexCoord2f((width*(Czas.Teraz/Czas.Razem))/8, 0); glVertex2f(x+width*(Czas.Teraz/Czas.Razem), y); - glTexCoord2f((width*(Czas.Teraz/Czas.Razem))/8, 1); glVertex2f(x+width*(Czas.Teraz/Czas.Razem), y+height); - glTexCoord2f(0, 1); glVertex2f(x, y+height); - glEnd; - - glDisable(GL_TEXTURE_2D); - glDisable(GL_BLEND); - glcolor4f(1,1,1,1); -end; - -end. - +unit UDraw; + +interface + +{$IFDEF FPC} + {$MODE DELPHI} +{$ENDIF} + +uses UThemes, + ModiSDK, + UGraphicClasses; + +procedure SingDraw; +procedure SingModiDraw (PlayerInfo: TPlayerInfo); +procedure SingDrawBackground; +procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer); +procedure SingDrawNoteLines(Left, Top, Right: real; Space: integer); +procedure SingDrawBeatDelimeters(Left, Top, Right: real; NrCzesci: integer); +procedure SingDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer); +procedure SingDrawPlayerCzesc(X, Y, W: real; NrGracza: integer; Space: integer); +procedure SingDrawPlayerBGCzesc(Left, Top, Right: real; NrCzesci, NrGracza: integer; Space: integer); + +// TimeBar +procedure SingDrawTimeBar(); + +// The Singbar +procedure SingDrawSingbar(X, Y, W, H: real; Percent: integer); + +//Phrasen Bonus - Line Bonus +procedure SingDrawLineBonus( const X, Y: Single; Color: TRGB; Alpha: Single; Text: string; Age: Integer); + +//Draw Editor NoteLines +procedure EditDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer); + + +type + TRecR = record + Top: real; + Left: real; + Right: real; + Bottom: real; + + Width: real; + WMid: real; + Height: real; + HMid: real; + + Mid: real; + end; + +var + NotesW: real; + NotesH: real; + Starfr: integer; + StarfrG: integer; + + //SingBar + TickOld: cardinal; + TickOld2:cardinal; + +const + Przedz = 32; + +implementation + +uses {$IFDEF Win32} + windows, + {$ELSE} + lclintf, + {$ENDIF} + OpenGL12, + UGraphic, + SysUtils, + UMusic, + URecord, + ULog, + UScreenSing, + UScreenSingModi, + ULyrics, + UMain, + TextGL, + UTexture, + UDrawTexture, + UIni, + Math, + UDLLManager; + +procedure SingDrawBackground; +var + Rec: TRecR; + TexRec: TRecR; +begin + if ScreenSing.Tex_Background.TexNum >= 1 then begin + + glClearColor (1, 1, 1, 1); + glColor4f (1, 1, 1, 1); + + if (Ini.MovieSize <= 1) then //HalfSize BG + begin + (* half screen + gradient *) + Rec.Top := 110; // 80 + Rec.Bottom := Rec.Top + 20; + Rec.Left := 0; + Rec.Right := 800; + + TexRec.Top := (Rec.Top / 600) * ScreenSing.Tex_Background.TexH; + TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH; + TexRec.Left := 0; + TexRec.Right := ScreenSing.Tex_Background.TexW; + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, ScreenSing.Tex_Background.TexNum); + glEnable(GL_BLEND); + glBegin(GL_QUADS); + (* gradient draw *) + (* top *) + glColor4f(1, 1, 1, 0); + glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top); + glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top); + glColor4f(1, 1, 1, 1); + glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom); + (* mid *) + Rec.Top := Rec.Bottom; + Rec.Bottom := 490 - 20; // 490 - 20 + TexRec.Top := TexRec.Bottom; + TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH; + glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top); + (* bottom *) + Rec.Top := Rec.Bottom; + Rec.Bottom := 490; // 490 + TexRec.Top := TexRec.Bottom; + TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH; + glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top); + glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top); + glColor4f(1, 1, 1, 0); + glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom); + + glEnd; + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + end + else //Full Size BG + begin + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, ScreenSing.Tex_Background.TexNum); + //glEnable(GL_BLEND); + glBegin(GL_QUADS); + + glTexCoord2f(0, 0); glVertex2f(0, 0); + glTexCoord2f(0, ScreenSing.Tex_Background.TexH); glVertex2f(0, 600); + glTexCoord2f( ScreenSing.Tex_Background.TexW, ScreenSing.Tex_Background.TexH); glVertex2f(800, 600); + glTexCoord2f( ScreenSing.Tex_Background.TexW, 0); glVertex2f(800, 0); + + glEnd; + glDisable(GL_TEXTURE_2D); + //glDisable(GL_BLEND); + end; + end; +end; + +procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer); +var + Pet: integer; +begin; +// Log.LogStatus('Oscilloscope', 'SingDraw'); + glColor3f(Skin_OscR, Skin_OscG, Skin_OscB); + {if (ParamStr(1) = '-black') or (ParamStr(1) = '-fsblack') then + glColor3f(1, 1, 1); } + + glBegin(GL_LINE_STRIP); + glVertex2f(X, -Sound[NrSound].BufferArray[1] / $10000 * H + Y + H/2); + for Pet := 2 to Sound[NrSound].n div 1 do begin + glVertex2f(X + (Pet-1) * W / (Sound[NrSound].n - 1), + -Sound[NrSound].BufferArray[Pet] / $10000 * H + Y + H/2); + end; + glEnd; +end; + +procedure SingDrawNoteLines(Left, Top, Right: real; Space: integer); +var + Pet: integer; +begin + glEnable(GL_BLEND); + glColor4f(Skin_P1_LinesR, Skin_P1_LinesG, Skin_P1_LinesB, 0.4); + glBegin(GL_LINES); + for Pet := 0 to 9 do begin + glVertex2f(Left, Top + Pet * Space); + glVertex2f(Right, Top + Pet * Space); + end; + glEnd; + glDisable(GL_BLEND); +end; + +procedure SingDrawBeatDelimeters(Left, Top, Right: real; NrCzesci: integer); +var + Pet: integer; + TempR: real; +begin + TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote); + glEnable(GL_BLEND); + glBegin(GL_LINES); + for Pet := Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote to Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec do begin + if (Pet mod Czesci[NrCzesci].Resolution) = Czesci[NrCzesci].NotesGAP then + glColor4f(0, 0, 0, 1) + else + glColor4f(0, 0, 0, 0.3); + glVertex2f(Left + TempR * (Pet - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote), Top); + glVertex2f(Left + TempR * (Pet - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote), Top + 135); + end; + glEnd; + glDisable(GL_BLEND); +end; + +// draw blank Notebars +procedure SingDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer); +var + Rec: TRecR; + Pet: integer; + TempR: real; + R,G,B: real; + + PlayerNumber: Integer; + + GoldenStarPos : real; +begin +// We actually don't have a playernumber in this procedure, it should reside in NrCzesci - but it's always set to zero +// So we exploit this behavior a bit - we give NrCzesci the playernumber, keep it in playernumber - and then we set NrCzesci to zero +// This could also come quite in handy when we do the duet mode, cause just the notes for the player that has to sing should be drawn then +// BUT this is not implemented yet, all notes are drawn! :D + + PlayerNumber := NrCzesci + 1; // Player 1 is 0 + NrCzesci := 0; + +// exploit done + + glColor3f(1, 1, 1); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote); + with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt] do begin + for Pet := 0 to HighNut do begin + with Nuta[Pet] do begin + if not FreeStyle then begin + + + if Ini.EffectSing = 0 then + // If Golden note Effect of then Change not Color + begin + case Wartosc of + 1: glColor4f(1, 1, 1, 1); // We set alpha to 1, cause we can control the transparency through the png itself + 2: glColor4f(1, 1, 0.3, 1); // no stars, paint yellow -> glColor4f(1, 1, 0.3, 0.85); - we could + end; // case + end //Else all Notes same Color + else + glColor4f(1, 1, 1, 1); // We set alpha to 1, cause we can control the transparency through the png itself + // Czesci == teil, element == piece, element | koniec == ende, schluss + // lewa czesc - left part + Rec.Left := (Start-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left + 0.5 + 10*ScreenX; + Rec.Right := Rec.Left + NotesW; + Rec.Top := Top - (Ton-BaseNote)*Space/2 - NotesH; + Rec.Bottom := Rec.Top + 2 * NotesH; + glBindTexture(GL_TEXTURE_2D, Tex_plain_Left[PlayerNumber].TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + + //We keep the postion of the top left corner b4 it's overwritten + GoldenStarPos := Rec.Left; + //done + + // srodkowa czesc - middle part + Rec.Left := Rec.Right; + Rec.Right := (Start+Dlugosc-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left - NotesW - 0.5 + 10*ScreenX; // Dlugosc == länge + + glBindTexture(GL_TEXTURE_2D, Tex_plain_Mid[PlayerNumber].TexNum); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(round((Rec.Right-Rec.Left)/32), 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(round((Rec.Right-Rec.Left)/32), 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + + // prawa czesc - right part + Rec.Left := Rec.Right; + Rec.Right := Rec.Right + NotesW; + + glBindTexture(GL_TEXTURE_2D, Tex_plain_Right[PlayerNumber].TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + + // Golden Star Patch + if (Wartosc = 2) AND (Ini.EffectSing=1) then + begin + GoldenRec.SaveGoldenStarsRec(GoldenStarPos, Rec.Top, Rec.Right, Rec.Bottom); + end; + + end; // if not FreeStyle + end; // with + end; // for + end; // with + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); +end; + + +// draw sung notes +procedure SingDrawPlayerCzesc(X, Y, W: real; NrGracza: integer; Space: integer); +var + TempR: real; + Rec: TRecR; + N: integer; + R: real; + G: real; + B: real; + A: real; + NotesH2: real; + begin +// Log.LogStatus('Player notes', 'SingDraw'); + +// if NrGracza = 0 then LoadColor(R, G, B, 'P1Light') +// else LoadColor(R, G, B, 'P2Light'); + +// R := 71/255; +// G := 175/255; +// B := 247/255; + + glColor3f(1, 1, 1); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + if Player[NrGracza].IlNut > 0 then + begin + TempR := W / (Czesci[0].Czesc[Czesci[0].Akt].Koniec - Czesci[0].Czesc[Czesci[0].Akt].StartNote); + for N := 0 to Player[NrGracza].HighNut do + begin + with Player[NrGracza].Nuta[N] do + begin + // Left part of note + Rec.Left := X + (Start-Czesci[0].Czesc[Czesci[0].Akt].StartNote) * TempR + 0.5 + 10*ScreenX; + Rec.Right := Rec.Left + NotesW; + + // Draw it in half size, if not hit + if Hit then + begin + NotesH2 := NotesH + end + else + begin + NotesH2 := int(NotesH * 0.65); + end; + + Rec.Top := Y - (Ton-Czesci[0].Czesc[Czesci[0].Akt].BaseNote)*Space/2 - NotesH2; + Rec.Bottom := Rec.Top + 2 *NotesH2; + + // draw the left part + glColor3f(1, 1, 1); + glBindTexture(GL_TEXTURE_2D, Tex_Left[NrGracza+1].TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + + // Middle part of the note + Rec.Left := Rec.Right; + Rec.Right := X + (Start+Dlugosc-Czesci[0].Czesc[Czesci[0].Akt].StartNote) * TempR - NotesW - 0.5 + 10*ScreenX; + + // (nowe) - dunno + if (Start+Dlugosc-1 = Czas.AktBeatD) then + Rec.Right := Rec.Right - (1-Frac(Czas.MidBeatD)) * TempR; + // the left note is more right than the right note itself, sounds weird - so we fix that xD + if Rec.Right <= Rec.Left then Rec.Right := Rec.Left; + + // draw the middle part + glBindTexture(GL_TEXTURE_2D, Tex_Mid[NrGracza+1].TexNum); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(round((Rec.Right-Rec.Left)/32), 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(round((Rec.Right-Rec.Left)/32), 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + glColor3f(1, 1, 1); + + // the right part of the note + Rec.Left := Rec.Right; + Rec.Right := Rec.Right + NotesW; + + glBindTexture(GL_TEXTURE_2D, Tex_Right[NrGracza+1].TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + + // Perfect note is stored + if Perfect and (Ini.EffectSing=1) then + begin + A := 1 - 2*(Czas.Teraz - GetTimeFromBeat(Start+Dlugosc)); + if not (Start+Dlugosc-1 = Czas.AktBeatD) then + + //Star animation counter + //inc(Starfr); + //Starfr := Starfr mod 128; + GoldenRec.SavePerfectNotePos(Rec.Left, Rec.Top); + end; + end; // with + end; // for + // eigentlich brauchen wir hier einen vergleich, um festzustellen, ob wir mit + // singen schon weiter wären, als bei Rec.Right, _auch, wenn nicht gesungen wird_ + + // passing on NrGracza... hope this is really something like the player-number, not only + // some kind of weird index into a colour-table + + if (Ini.EffectSing=1) then + GoldenRec.GoldenNoteTwinkle(Rec.Top,Rec.Bottom,Rec.Right, NrGracza); + end; // if +end; + +//draw Note glow +procedure SingDrawPlayerBGCzesc(Left, Top, Right: real; NrCzesci, NrGracza: integer; Space: integer); +var + Rec: TRecR; + Pet: integer; + TempR: real; + R,G,B: real; + X1, X2, X3, X4: real; + W, H: real; +begin + if (Player[NrGracza].ScoreTotalI >= 0) then begin + glColor4f(1, 1, 1, sqrt((1+sin(Music.Position * 3))/4)/ 2 + 0.5 ); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote); + with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt] do begin + for Pet := 0 to HighNut do begin + with Nuta[Pet] do begin + if not FreeStyle then begin + // begin: 14, 20 + // easy: 6, 11 + W := NotesW * 2 + 2; + H := NotesH * 1.5 + 3.5; + + X2 := (Start-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left + 0.5 + 10*ScreenX + 4; // wciecie + X1 := X2-W; + + X3 := (Start+Dlugosc-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left - 0.5 + 10*ScreenX - 4; // wciecie + X4 := X3+W; + + // left + Rec.Left := X1; + Rec.Right := X2; + Rec.Top := Top - (Ton-BaseNote)*Space/2 - H; + Rec.Bottom := Rec.Top + 2 * H; + + glBindTexture(GL_TEXTURE_2D, Tex_BG_Left[NrGracza+1].TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + + + // srodkowa czesc + Rec.Left := X2; + Rec.Right := X3; + + glBindTexture(GL_TEXTURE_2D, Tex_BG_Mid[NrGracza+1].TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + + // prawa czesc + Rec.Left := X3; + Rec.Right := X4; + + glBindTexture(GL_TEXTURE_2D, Tex_BG_Right[NrGracza+1].TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + end; // if not FreeStyle + end; // with + end; // for + end; // with + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + end; +end; + +procedure SingDraw; +var + Pet: integer; + Pet2: integer; + TempR: real; + Rec: TRecR; + TexRec: TRecR; + NR: TRecR; + FS: real; + BarFrom: integer; + BarAlpha: real; + BarWspol: real; + TempCol: real; + Tekst: string; + LyricTemp: string; + PetCz: integer; + + //SingBar Mod + A: Integer; + E: Integer; + I: Integer; + //end Singbar Mod + +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; + + // background //BG Fullsize Mod + //SingDrawBackground; + + //TimeBar mod + SingDrawTimeBar(); + //eoa TimeBar mod + + // rysuje paski pod nutami + if PlayersPlay = 1 then + SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15); + if (PlayersPlay = 2) or (PlayersPlay = 4) then begin + SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P1_NotesB - 105, Nr.Right + 10*ScreenX, 15); + SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15); + end; + + if (PlayersPlay = 3) or (PlayersPlay = 6) then begin + SingDrawNoteLines(Nr.Left + 10*ScreenX, 120, Nr.Right + 10*ScreenX, 12); + SingDrawNoteLines(Nr.Left + 10*ScreenX, 245, Nr.Right + 10*ScreenX, 12); + SingDrawNoteLines(Nr.Left + 10*ScreenX, 370, Nr.Right + 10*ScreenX, 12); + end; + + // Draw Lyrics + ScreenSing.Lyrics.Draw(Czas.MidBeat); + + // todo: Lyrics +{ // rysuje pasek, podpowiadajacy poczatek spiwania w scenie + FS := 1.3; + BarFrom := Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start; + if BarFrom > 40 then BarFrom := 40; + if (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start > 8) and // dluga przerwa //16->12 for more help bars and then 12->8 for even more + (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat > 0) and // przed tekstem + (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat < 40) then begin // ale nie za wczesnie + BarWspol := (Czas.MidBeat - (Czesci[0].Czesc[Czesci[0].Akt].StartNote - BarFrom)) / BarFrom; + Rec.Left := NR.Left + BarWspol * +// (NR.WMid - Czesci[0].Czesc[Czesci[0].Akt].LyricWidth / 2 * FS - 50); + (ScreenSing.LyricMain.ClientX - NR.Left - 50) + 10*ScreenX; + Rec.Right := Rec.Left + 50; + Rec.Top := Skin_LyricsT + 3; + Rec.Bottom := Rec.Top + 33;//SingScreen.LyricMain.Size * 3; +{ // zapalanie + BarAlpha := (BarWspol*10) * 0.5; + if BarAlpha > 0.5 then BarAlpha := 0.5; + + // gaszenie + if BarWspol > 0.95 then BarAlpha := 0.5 * (1 - (BarWspol - 0.95) * 20);}{ + + //Change fuer Crazy Joker + + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, Tex_Lyric_Help_Bar.TexNum); + glBegin(GL_QUADS); + glColor4f(1, 1, 1, 0); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glColor4f(1, 1, 1, 0.5); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + glDisable(GL_BLEND); + + end; } + + // oscilloscope + if Ini.Oscilloscope = 1 then begin + if PlayersPlay = 1 then + SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); + + if PlayersPlay = 2 then begin + SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); + SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1); + end; + + if PlayersPlay = 4 then begin + if ScreenAct = 1 then begin + SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); + SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1); + end; + if ScreenAct = 2 then begin + SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2); + SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3); + end; + end; + + if PlayersPlay = 3 then begin + SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0); + SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1); + SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2); + end; + + if PlayersPlay = 6 then begin + if ScreenAct = 1 then begin + SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0); + SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1); + SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2); + end; + if ScreenAct = 2 then begin + SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3); + SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4); + SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5); + end; + end; + + end + + //SingBar Mod + //modded again to make it moveable: it's working, so why try harder + else if Ini.Oscilloscope = 2 then + begin + A := GetTickCount div 33; + if A <> Tickold then begin + Tickold := A; + for E := 0 to (PlayersPlay - 1) do begin //Set new Pos + Alpha + I := Player[E].ScorePercentTarget - Player[E].ScorePercent; + if I > 0 then Inc(Player[E].ScorePercent) + else if I < 0 then Dec(Player[E].ScorePercent); + end; //for + end; //if + + if PlayersPlay = 1 then begin + SingDrawSingbar(Theme.Sing.StaticP1SingBar.x, Theme.Sing.StaticP1SingBar.y, Theme.Sing.StaticP1SingBar.w, Theme.Sing.StaticP1SingBar.h , Player[0].ScorePercent); + end; + + if PlayersPlay = 2 then begin + SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent); + SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent); + end; + + if PlayersPlay = 3 then begin + SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent); + SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent); + SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent); + end; + + if PlayersPlay = 4 then begin + if ScreenAct = 1 then begin + SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent); + SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent); + end; + if ScreenAct = 2 then begin + SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[2].ScorePercent); + SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[3].ScorePercent); + end; + end; + + if PlayersPlay = 6 then begin + if ScreenAct = 1 then begin + SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent); + SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent); + SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent); + end; + if ScreenAct = 2 then begin + SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[3].ScorePercent); + SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[4].ScorePercent); + SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[5].ScorePercent); + end; + end; + end; + //end Singbar Mod + + //PhrasenBonus - Line Bonus Mod + if Ini.LineBonus > 0 then begin + A := GetTickCount div 33; + if (A <> Tickold2) AND (Player[0].LineBonus_Visible) then begin + Tickold2 := A; + for E := 0 to (PlayersPlay - 1) do begin + //Change Alpha + Player[E].LineBonus_Alpha := Player[E].LineBonus_Alpha - 0.02; + if Player[E].LineBonus_Alpha <= 0 then + begin + Player[E].LineBonus_Age := 0; + Player[E].LineBonus_Visible := False + end + else + begin + inc(Player[E].LineBonus_Age, 1); + //Change Position + if (Player[E].LineBonus_PosX < Player[E].LineBonus_TargetX) then + Player[E].LineBonus_PosX := Player[E].LineBonus_PosX + (2 - Player[E].LineBonus_Alpha * 1.5) + else if (Player[E].LineBonus_PosX > Player[E].LineBonus_TargetX) then + Player[E].LineBonus_PosX := Player[E].LineBonus_PosX - (2 - Player[E].LineBonus_Alpha * 1.5); + + if (Player[E].LineBonus_PosY < Player[E].LineBonus_TargetY) then + Player[E].LineBonus_PosY := Player[E].LineBonus_PosY + (2 - Player[E].LineBonus_Alpha * 1.5) + else if (Player[E].LineBonus_PosY > Player[E].LineBonus_TargetY) then + Player[E].LineBonus_PosY := Player[E].LineBonus_PosY - (2 - Player[E].LineBonus_Alpha * 1.5); + + end; // shift position of the pop up (if not dead) + end; // loop - for all players + end; // if - linebonus + + + if PlayersPlay = 1 then begin + SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); + end + + else if PlayersPlay = 2 then begin + SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); + SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); + end + + else if PlayersPlay = 3 then begin + SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); + SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); + SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age); + end + + else if PlayersPlay = 4 then begin + if ScreenAct = 1 then begin + SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); + SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); + end; + if ScreenAct = 2 then begin + SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age); + SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age); + end; + end; + + if PlayersPlay = 6 then begin + if ScreenAct = 1 then begin + SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); + SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); + SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age); + end; + if ScreenAct = 2 then begin + SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age); + SingDrawLineBonus( Player[4].LineBonus_PosX, Player[4].LineBonus_PosY, Player[4].LineBonus_Color, Player[4].LineBonus_Alpha, Player[4].LineBonus_Text, Player[4].LineBonus_Age); + SingDrawLineBonus( Player[5].LineBonus_PosX, Player[5].LineBonus_PosY, Player[5].LineBonus_Color, Player[5].LineBonus_Alpha, Player[5].LineBonus_Text, Player[5].LineBonus_Age); + end; + end; + end; + //PhrasenBonus - Line Bonus Mod End + +// Set the note heights according to the difficulty level + case Ini.Difficulty of + 0: + begin + NotesH := 11; // 9 + NotesW := 6; // 5 + end; + 1: + begin + NotesH := 8; // 7 + NotesW := 4; // 4 + end; + 2: + begin + NotesH := 5; + NotesW := 3; + end; + end; + +// Draw the Notes + if PlayersPlay = 1 then begin + SingDrawPlayerBGCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 0, 15); // Background glow - colorized in playercolor + SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15); // Plain unsung notes - colorized in playercolor + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 15); // imho the sung notes + end; + + if (PlayersPlay = 2) then begin + SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15); + SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15); + + SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15); + SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 1, 15); + + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15); + end; + + if PlayersPlay = 3 then begin + NotesW := NotesW * 0.8; + NotesH := NotesH * 0.8; + + SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12); + SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12); + SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12); + + SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12); + SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 1, 12); + SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 2, 12); + + SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12); + end; + + if PlayersPlay = 4 then begin + if ScreenAct = 1 then begin + SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15); + SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15); + end; + if ScreenAct = 2 then begin + SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 2, 15); + SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 3, 15); + end; + + if ScreenAct = 1 then begin + SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15); + SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 1, 15); + end; + if ScreenAct = 2 then begin + SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 2, 15); + SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 3, 15); + end; + + if ScreenAct = 1 then begin + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15); + end; + if ScreenAct = 2 then begin + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 2, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 3, 15); + end; + end; + + if PlayersPlay = 6 then begin + NotesW := NotesW * 0.8; + NotesH := NotesH * 0.8; + + if ScreenAct = 1 then begin + SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12); + SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12); + SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12); + end; + if ScreenAct = 2 then begin + SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 3, 12); + SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 4, 12); + SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 5, 12); + end; + + if ScreenAct = 1 then begin + SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12); + SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 1, 12); + SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 2, 12); + end; + if ScreenAct = 2 then begin + SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 3, 12); + SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 4, 12); + SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 5, 12); + end; + + if ScreenAct = 1 then begin + SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12); + end; + if ScreenAct = 2 then begin + SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 3, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 4, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 5, 12); + end; + end; + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); +end; + +// q'n'd for using the game mode dll's +procedure SingModiDraw (PlayerInfo: TPlayerInfo); +var + Pet: integer; + Pet2: integer; + TempR: real; + Rec: TRecR; + TexRec: TRecR; + NR: TRecR; + FS: real; + BarFrom: integer; + BarAlpha: real; + BarWspol: real; + TempCol: real; + Tekst: string; + LyricTemp: string; + PetCz: integer; + + //SingBar Mod + A: Integer; + E: Integer; + I: Integer; + //end Singbar Mod + +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; + + // time bar + SingDrawTimeBar(); + + if DLLMan.Selected.ShowNotes then + begin + if PlayersPlay = 1 then + SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15); + if (PlayersPlay = 2) or (PlayersPlay = 4) then begin + SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P1_NotesB - 105, Nr.Right + 10*ScreenX, 15); + SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15); + end; + + if (PlayersPlay = 3) or (PlayersPlay = 6) then begin + SingDrawNoteLines(Nr.Left + 10*ScreenX, 120, Nr.Right + 10*ScreenX, 12); + SingDrawNoteLines(Nr.Left + 10*ScreenX, 245, Nr.Right + 10*ScreenX, 12); + SingDrawNoteLines(Nr.Left + 10*ScreenX, 370, Nr.Right + 10*ScreenX, 12); + end; + end; + + // Draw Lyrics + ScreenSingModi.Lyrics.Draw(Czas.MidBeat); + + // todo: Lyrics +{ // rysuje pasek, podpowiadajacy poczatek spiwania w scenie + FS := 1.3; + BarFrom := Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start; + if BarFrom > 40 then BarFrom := 40; + if (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start > 8) and // dluga przerwa //16->12 for more help bars and then 12->8 for even more + (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat > 0) and // przed tekstem + (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat < 40) then begin // ale nie za wczesnie + BarWspol := (Czas.MidBeat - (Czesci[0].Czesc[Czesci[0].Akt].StartNote - BarFrom)) / BarFrom; + Rec.Left := NR.Left + BarWspol * (ScreenSingModi.LyricMain.ClientX - NR.Left - 50) + 10*ScreenX; + Rec.Right := Rec.Left + 50; + Rec.Top := Skin_LyricsT + 3; + Rec.Bottom := Rec.Top + 33;//SingScreen.LyricMain.Size * 3; + + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, Tex_Lyric_Help_Bar.TexNum); + glBegin(GL_QUADS); + glColor4f(1, 1, 1, 0); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glColor4f(1, 1, 1, 0.5); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + glDisable(GL_BLEND); + end; + } + + // oscilloscope | the thing that moves when you yell into your mic (imho) + if (((Ini.Oscilloscope = 1) AND (DLLMan.Selected.ShowRateBar_O)) AND (NOT DLLMan.Selected.ShowRateBar)) then begin + if PlayersPlay = 1 then + if PlayerInfo.Playerinfo[0].Enabled then + SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); + + if PlayersPlay = 2 then begin + if PlayerInfo.Playerinfo[0].Enabled then + SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); + if PlayerInfo.Playerinfo[1].Enabled then + SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1); + end; + + if PlayersPlay = 4 then begin + if ScreenAct = 1 then begin + if PlayerInfo.Playerinfo[0].Enabled then + SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0); + if PlayerInfo.Playerinfo[1].Enabled then + SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1); + end; + if ScreenAct = 2 then begin + if PlayerInfo.Playerinfo[2].Enabled then + SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2); + if PlayerInfo.Playerinfo[3].Enabled then + SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3); + end; + end; + + if PlayersPlay = 3 then begin + if PlayerInfo.Playerinfo[0].Enabled then + SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0); + if PlayerInfo.Playerinfo[1].Enabled then + SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1); + if PlayerInfo.Playerinfo[2].Enabled then + SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2); + end; + + if PlayersPlay = 6 then begin + if ScreenAct = 1 then begin + if PlayerInfo.Playerinfo[0].Enabled then + SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0); + if PlayerInfo.Playerinfo[1].Enabled then + SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1); + if PlayerInfo.Playerinfo[2].Enabled then + SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2); + end; + if ScreenAct = 2 then begin + if PlayerInfo.Playerinfo[3].Enabled then + SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3); + if PlayerInfo.Playerinfo[4].Enabled then + SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4); + if PlayerInfo.Playerinfo[5].Enabled then + SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5); + end; + end; + + end + + //SingBar Mod + // seems like we don't want the flicker thing, we want the linebonus rating bar beneath the scores + else if ((Ini.Oscilloscope = 2) AND (DLLMan.Selected.ShowRateBar_O)) OR (DLLMan.Selected.ShowRateBar) then begin + A := GetTickCount div 33; + if A <> Tickold then begin + Tickold := A; + for E := 0 to (PlayersPlay - 1) do begin //Set new Pos + Alpha + I := Player[E].ScorePercentTarget - Player[E].ScorePercent; + if I > 0 then Inc(Player[E].ScorePercent) + else if I < 0 then Dec(Player[E].ScorePercent); + end; //for + end; //if + + if PlayersPlay = 1 then begin + if PlayerInfo.Playerinfo[0].Enabled then + SingDrawSingbar(Theme.Sing.StaticP1SingBar.x, Theme.Sing.StaticP1SingBar.y, Theme.Sing.StaticP1SingBar.w, Theme.Sing.StaticP1SingBar.h , Player[0].ScorePercent); + end; + + if PlayersPlay = 2 then begin + if PlayerInfo.Playerinfo[0].Enabled then + SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent); + if PlayerInfo.Playerinfo[1].Enabled then + SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent); + end; + + if PlayersPlay = 3 then begin + if PlayerInfo.Playerinfo[0].Enabled then + SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent); + if PlayerInfo.Playerinfo[1].Enabled then + SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent); + if PlayerInfo.Playerinfo[2].Enabled then + SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent); + end; + + if PlayersPlay = 4 then begin + if ScreenAct = 1 then begin + if PlayerInfo.Playerinfo[0].Enabled then + SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent); + if PlayerInfo.Playerinfo[1].Enabled then + SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent); + end; + if ScreenAct = 2 then begin + if PlayerInfo.Playerinfo[2].Enabled then + SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[2].ScorePercent); + if PlayerInfo.Playerinfo[3].Enabled then + SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[3].ScorePercent); + end; + end; + + if PlayersPlay = 6 then begin + if ScreenAct = 1 then begin + if PlayerInfo.Playerinfo[0].Enabled then + SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent); + if PlayerInfo.Playerinfo[1].Enabled then + SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent); + if PlayerInfo.Playerinfo[2].Enabled then + SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent); + end; + if ScreenAct = 2 then begin + if PlayerInfo.Playerinfo[3].Enabled then + SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[3].ScorePercent); + if PlayerInfo.Playerinfo[4].Enabled then + SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[4].ScorePercent); + if PlayerInfo.Playerinfo[5].Enabled then + SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[5].ScorePercent); + end; + end; + end; + //end Singbar Mod + + //PhrasenBonus - Line Bonus Mod + if ((Ini.LineBonus > 0) AND (DLLMan.Selected.EnLineBonus_O)) OR (DLLMan.Selected.EnLineBonus) then begin + A := GetTickCount div 33; + if (A <> Tickold2) AND (Player[0].LineBonus_Visible) then begin + Tickold2 := A; + for E := 0 to (PlayersPlay - 1) do begin + //Change Alpha + Player[E].LineBonus_Alpha := Player[E].LineBonus_Alpha - 0.02; + + if Player[E].LineBonus_Alpha <= 0 then + begin + Player[E].LineBonus_Age := 0; + Player[E].LineBonus_Visible := False + end + else + begin + inc(Player[E].LineBonus_Age, 1); + //Change Position + if (Player[E].LineBonus_PosX < Player[E].LineBonus_TargetX) then // pop up has not yet reached it's position -> blend in + Player[E].LineBonus_PosX := Player[E].LineBonus_PosX + (2 - Player[E].LineBonus_Alpha * 1.5) + else if (Player[E].LineBonus_PosX > Player[E].LineBonus_TargetX) then // pop up has reached it's position -> blend out + Player[E].LineBonus_PosX := Player[E].LineBonus_PosX - (2 - Player[E].LineBonus_Alpha * 1.5); + + if (Player[E].LineBonus_PosY < Player[E].LineBonus_TargetY) then + Player[E].LineBonus_PosY := Player[E].LineBonus_PosY + (2 - Player[E].LineBonus_Alpha * 1.5) + else if (Player[E].LineBonus_PosY > Player[E].LineBonus_TargetY) then + Player[E].LineBonus_PosY := Player[E].LineBonus_PosY - (2 - Player[E].LineBonus_Alpha * 1.5); + + end; // pop up still visible, has not reached it's position - move it + end; // loop through all players + end; // if it's time to draw them + + if PlayersPlay = 1 then begin + if PlayerInfo.Playerinfo[0].Enabled then + SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); + end + + else if PlayersPlay = 2 then begin + if PlayerInfo.Playerinfo[0].Enabled then + SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); + if PlayerInfo.Playerinfo[1].Enabled then + SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); + end + + else if PlayersPlay = 3 then begin + if PlayerInfo.Playerinfo[0].Enabled then + SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); + if PlayerInfo.Playerinfo[1].Enabled then + SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); + if PlayerInfo.Playerinfo[2].Enabled then + SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age); + end + + else if PlayersPlay = 4 then begin + if ScreenAct = 1 then begin + if PlayerInfo.Playerinfo[0].Enabled then + SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); + if PlayerInfo.Playerinfo[1].Enabled then + SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); + end; + if ScreenAct = 2 then begin + if PlayerInfo.Playerinfo[2].Enabled then + SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age); + if PlayerInfo.Playerinfo[3].Enabled then + SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age); + end; + end; + + if PlayersPlay = 6 then begin + if ScreenAct = 1 then begin + if PlayerInfo.Playerinfo[0].Enabled then + SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age); + if PlayerInfo.Playerinfo[1].Enabled then + SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age); + if PlayerInfo.Playerinfo[2].Enabled then + SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age); + end; + if ScreenAct = 2 then begin + if PlayerInfo.Playerinfo[3].Enabled then + SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age); + if PlayerInfo.Playerinfo[4].Enabled then + SingDrawLineBonus( Player[4].LineBonus_PosX, Player[4].LineBonus_PosY, Player[4].LineBonus_Color, Player[4].LineBonus_Alpha, Player[4].LineBonus_Text, Player[4].LineBonus_Age); + if PlayerInfo.Playerinfo[5].Enabled then + SingDrawLineBonus( Player[5].LineBonus_PosX, Player[5].LineBonus_PosY, Player[5].LineBonus_Color, Player[5].LineBonus_Alpha, Player[5].LineBonus_Text, Player[5].LineBonus_Age); + end; + end; + end; +//PhrasenBonus - Line Bonus Mod End + +// resize the notes according to the difficulty level + case Ini.Difficulty of + 0: + begin + NotesH := 11; // 9 + NotesW := 6; // 5 + end; + 1: + begin + NotesH := 8; // 7 + NotesW := 4; // 4 + end; + 2: + begin + NotesH := 5; + NotesW := 3; + end; + end; + + if (DLLMAn.Selected.ShowNotes And DLLMan.Selected.LoadSong) then + begin + if (PlayersPlay = 1) And PlayerInfo.Playerinfo[0].Enabled then begin + SingDrawPlayerBGCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 0, 15); + SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 15); + end; + + if (PlayersPlay = 2) then begin + if PlayerInfo.Playerinfo[0].Enabled then + begin + SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15); + SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15); + end; + if PlayerInfo.Playerinfo[1].Enabled then + begin + SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15); + SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15); + end; + + end; + + if PlayersPlay = 3 then begin + NotesW := NotesW * 0.8; + NotesH := NotesH * 0.8; + + if PlayerInfo.Playerinfo[0].Enabled then + begin + SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12); + SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12); + end; + + if PlayerInfo.Playerinfo[1].Enabled then + begin + SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12); + SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 0, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12); + end; + + if PlayerInfo.Playerinfo[2].Enabled then + begin + SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12); + SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 0, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12); + end; + end; + + if PlayersPlay = 4 then begin + if ScreenAct = 1 then begin + SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15); + SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15); + end; + if ScreenAct = 2 then begin + SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 2, 15); + SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 3, 15); + end; + + SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15); + SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15); + + if ScreenAct = 1 then begin + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15); + end; + if ScreenAct = 2 then begin + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 2, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 3, 15); + end; + end; + + if PlayersPlay = 6 then begin + NotesW := NotesW * 0.8; + NotesH := NotesH * 0.8; + + if ScreenAct = 1 then begin + SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12); + SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12); + SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12); + end; + if ScreenAct = 2 then begin + SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 3, 12); + SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 4, 12); + SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 5, 12); + end; + + SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12); + SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 0, 12); + SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 0, 12); + + if ScreenAct = 1 then begin + SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12); + end; + if ScreenAct = 2 then begin + SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 3, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 4, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 5, 12); + end; + end; + end; + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); +end; + + +//SingBar Mod +procedure SingDrawSingbar(X, Y, W, H: real; Percent: integer); +var + R: Real; + G: Real; + B: Real; + A: cardinal; + I: Integer; + +begin; + + //SingBar Background + glColor4f(1, 1, 1, 0.8); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Back.TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(X, Y); + glTexCoord2f(0, 1); glVertex2f(X, Y+H); + glTexCoord2f(1, 1); glVertex2f(X+W, Y+H); + glTexCoord2f(1, 0); glVertex2f(X+W, Y); + glEnd; + + //SingBar coloured Bar + Case Percent of + 0..22: begin + R := 1; + G := 0; + B := 0; + end; + 23..42: begin + R := 1; + G := ((Percent-23)/100)*5; + B := 0; + end; + 43..57: begin + R := 1; + G := 1; + B := 0; + end; + 58..77: begin + R := 1-(Percent - 58)/100*5; + G := 1; + B := 0; + end; + 78..99: begin + R := 0; + G := 1; + B := 0; + end; + End; //Case + + glColor4f(R, G, B, 1); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Bar.TexNum); + //Size= Player[PlayerNum].ScorePercent of W + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(X, Y); + glTexCoord2f(0, 1); glVertex2f(X, Y+H); + glTexCoord2f(1, 1); glVertex2f(X+(W/100 * (Percent +1)), Y+H); + glTexCoord2f(1, 0); glVertex2f(X+(W/100 * (Percent +1)), Y); + glEnd; + + //SingBar Front + glColor4f(1, 1, 1, 0.6); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Front.TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(X, Y); + glTexCoord2f(0, 1); glVertex2f(X, Y+H); + glTexCoord2f(1, 1); glVertex2f(X+W, Y+H); + glTexCoord2f(1, 0); glVertex2f(X+W, Y); + glEnd; +end; +//end Singbar Mod + +//PhrasenBonus - Line Bonus Pop Up +procedure SingDrawLineBonus( const X, Y: Single; Color: TRGB; Alpha: Single; Text: string; Age: Integer); +var +Length, X2: Real; //Length of Text +Size: Integer; //Size of Popup +begin +if Alpha <> 0 then +begin + +//Set Font Propertys +SetFontStyle(2); //Font: Outlined1 +if Age < 5 then SetFontSize(Age + 1) else SetFontSize(6); +SetFontItalic(False); + +//Check Font Size +Length := glTextWidth ( PChar(Text)) + 3; //Little Space for a Better Look ^^ + +//Text +SetFontPos (X + 50 - (Length / 2), Y + 12); //Position + + +if Age < 5 then Size := Age * 10 else Size := 50; + + //Draw Background + //glColor4f(Color.R, Color.G, Color.B, Alpha); //Set Color + glColor4f(1, 1, 1, Alpha); + + + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + + //New Method, Not Variable + glBindTexture(GL_TEXTURE_2D, Tex_SingLineBonusBack[2].TexNum); + + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(X + 50 - Size, Y + 25 - (Size/2)); + glTexCoord2f(0, 1); glVertex2f(X + 50 - Size, Y + 25 + (Size/2)); + glTexCoord2f(1, 1); glVertex2f(X + 50 + Size, Y + 25 + (Size/2)); + glTexCoord2f(1, 0); glVertex2f(X + 50 + Size, Y + 25 - (Size/2)); + glEnd; + + glColor4f(1, 1, 1, Alpha); //Set Color + //Draw Text + glPrint (PChar(Text)); +end; +end; +//PhrasenBonus - Line Bonus Mod + +// Draw Note Bars for Editor +//There are 11 Resons for a new Procdedure: +// 1. It don't look good when you Draw the Golden Note Star Effect in the Editor +// 2. You can see the Freestyle Notes in the Editor SemiTransparent +// 3. Its easier and Faster then changing the old Procedure +procedure EditDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer); +var + Rec: TRecR; + Pet: integer; + TempR: real; +begin + glColor3f(1, 1, 1); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote); + with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt] do begin + for Pet := 0 to HighNut do begin + with Nuta[Pet] do begin + + // Golden Note Patch + case Wartosc of + 0: glColor4f(1, 1, 1, 0.35); + 1: glColor4f(1, 1, 1, 0.85); + 2: glColor4f(1, 1, 0.3, 0.85); + end; // case + + + + // lewa czesc - left part + Rec.Left := (Start-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left + 0.5 + 10*ScreenX; + Rec.Right := Rec.Left + NotesW; + Rec.Top := Top - (Ton-BaseNote)*Space/2 - NotesH; + Rec.Bottom := Rec.Top + 2 * NotesH; + glBindTexture(GL_TEXTURE_2D, Tex_Left[Color].TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + + // srodkowa czesc - middle part + Rec.Left := Rec.Right; + Rec.Right := (Start+Dlugosc-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left - NotesW - 0.5 + 10*ScreenX; + + glBindTexture(GL_TEXTURE_2D, Tex_Mid[Color].TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + + // prawa czesc - right part + Rec.Left := Rec.Right; + Rec.Right := Rec.Right + NotesW; + + glBindTexture(GL_TEXTURE_2D, Tex_Right[Color].TexNum); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top); + glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom); + glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom); + glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top); + glEnd; + + end; // with + end; // for + end; // with + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); +end; + +procedure SingDrawTimeBar(); +var x,y: real; + width, height: real; +begin + x := Theme.Sing.StaticTimeProgress.x; + y := Theme.Sing.StaticTimeProgress.y; + width:= Theme.Sing.StaticTimeProgress.w; + height:= Theme.Sing.StaticTimeProgress.h; + + glColor4f(Theme.Sing.StaticTimeProgress.ColR, + Theme.Sing.StaticTimeProgress.ColG, + Theme.Sing.StaticTimeProgress.ColB, 1); //Set Color + + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + + glBindTexture(GL_TEXTURE_2D, Tex_TimeProgress.TexNum); + + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(x,y); + glTexCoord2f((width*(Czas.Teraz/Czas.Razem))/8, 0); glVertex2f(x+width*(Czas.Teraz/Czas.Razem), y); + glTexCoord2f((width*(Czas.Teraz/Czas.Razem))/8, 1); glVertex2f(x+width*(Czas.Teraz/Czas.Razem), y+height); + glTexCoord2f(0, 1); glVertex2f(x, y+height); + glEnd; + + glDisable(GL_TEXTURE_2D); + glDisable(GL_BLEND); + glcolor4f(1,1,1,1); +end; + +end. + diff --git a/Game/Code/Classes/UGraphic.pas b/Game/Code/Classes/UGraphic.pas index aaa4b3d7..09bbc1c9 100644 --- a/Game/Code/Classes/UGraphic.pas +++ b/Game/Code/Classes/UGraphic.pas @@ -1,611 +1,611 @@ -unit UGraphic; - -interface - -{$I switches.inc} - -{$IFDEF FPC} - {$MODE DELPHI} -{$ENDIF} - -uses - SDL, - OpenGL12, - UTexture, - TextGL, - ULog, - SysUtils, - ULyrics, - UScreenLoading, - UScreenWelcome, - UScreenMain, - UScreenName, - UScreenLevel, - UScreenOptions, - UScreenOptionsGame, - UScreenOptionsGraphics, - UScreenOptionsSound, - UScreenOptionsLyrics, - UScreenOptionsThemes, - UScreenOptionsRecord, - UScreenOptionsAdvanced, - UScreenSong, - UScreenSing, - UScreenScore, - UScreenTop5, - UScreenEditSub, - UScreenEdit, - UScreenEditConvert, - UScreenEditHeader, - UScreenOpen, - UThemes, - USkins, - UScreenSongMenu, - UScreenSongJumpto, - {Party Screens} - UScreenSingModi, - UScreenPartyNewRound, - UScreenPartyScore, - UScreenPartyOptions, - UScreenPartyWin, - UScreenPartyPlayer, - {Stats Screens} - UScreenStatMain, - UScreenStatDetail, - {CreditsScreen} - UScreenCredits, - {Popup for errors, etc.} - UScreenPopup; - -type - TRecR = record - Top: real; - Left: real; - Right: real; - Bottom: real; - end; - -var - Screen: PSDL_Surface; - - LoadingThread: PSDL_Thread; - Mutex: PSDL_Mutex; - - RenderW: integer; - RenderH: integer; - ScreenW: integer; - ScreenH: integer; - Screens: integer; - ScreenAct: integer; - ScreenX: integer; - - ScreenLoading: TScreenLoading; - ScreenWelcome: TScreenWelcome; - ScreenMain: TScreenMain; - ScreenName: TScreenName; - ScreenLevel: TScreenLevel; - ScreenSong: TScreenSong; - ScreenSing: TScreenSing; - ScreenScore: TScreenScore; - ScreenTop5: TScreenTop5; - ScreenOptions: TScreenOptions; - ScreenOptionsGame: TScreenOptionsGame; - ScreenOptionsGraphics: TScreenOptionsGraphics; - ScreenOptionsSound: TScreenOptionsSound; - ScreenOptionsLyrics: TScreenOptionsLyrics; - ScreenOptionsThemes: TScreenOptionsThemes; - ScreenOptionsRecord: TScreenOptionsRecord; - ScreenOptionsAdvanced: TScreenOptionsAdvanced; - ScreenEditSub: TScreenEditSub; - ScreenEdit: TScreenEdit; - ScreenEditConvert: TScreenEditConvert; - ScreenEditHeader: TScreenEditHeader; - ScreenOpen: TScreenOpen; - - ScreenSongMenu: TScreenSongMenu; - ScreenSongJumpto: TScreenSongJumpto; - - //Party Screens - ScreenSingModi: TScreenSingModi; - ScreenPartyNewRound: TScreenPartyNewRound; - ScreenPartyScore: TScreenPartyScore; - ScreenPartyWin: TScreenPartyWin; - ScreenPartyOptions: TScreenPartyOptions; - ScreenPartyPlayer: TScreenPartyPlayer; - - //StatsScreens - ScreenStatMain: TScreenStatMain; - ScreenStatDetail: TScreenStatDetail; - - //CreditsScreen - ScreenCredits: TScreenCredits; - - //popup mod - ScreenPopupCheck: TScreenPopupCheck; - ScreenPopupError: TScreenPopupError; - - //Notes - Tex_Left: array[0..6] of TTexture; //rename to tex_note_left - Tex_Mid: array[0..6] of TTexture; //rename to tex_note_mid - Tex_Right: array[0..6] of TTexture; //rename to tex_note_right - - Tex_plain_Left: array[1..6] of TTexture; //rename to tex_notebg_left - Tex_plain_Mid: array[1..6] of TTexture; //rename to tex_notebg_mid - Tex_plain_Right: array[1..6] of TTexture; //rename to tex_notebg_right - - Tex_BG_Left: array[1..6] of TTexture; //rename to tex_noteglow_left - Tex_BG_Mid: array[1..6] of TTexture; //rename to tex_noteglow_mid - Tex_BG_Right: array[1..6] of TTexture; //rename to tex_noteglow_right - - Tex_Note_Star: TTexture; - Tex_Note_Perfect_Star: TTexture; - - - Tex_Ball: TTexture; - Tex_Lyric_Help_Bar: TTexture; - FullScreen: boolean; - - Tex_TimeProgress: TTexture; - - //Sing Bar Mod - Tex_SingBar_Back: TTexture; - Tex_SingBar_Bar: TTexture; - Tex_SingBar_Front: TTexture; - //end Singbar Mod - - //PhrasenBonus - Line Bonus Mod - Tex_SingLineBonusBack: array[0..8] of TTexture; - //End PhrasenBonus - Line Bonus Mod - -const - Skin_BGColorR = 1; - Skin_BGColorG = 1; - Skin_BGColorB = 1; - - Skin_SpectrumR = 0; - Skin_SpectrumG = 0; - Skin_SpectrumB = 0; - - Skin_Spectograph1R = 0.6; - Skin_Spectograph1G = 0.8; - Skin_Spectograph1B = 1; - - Skin_Spectograph2R = 0; - Skin_Spectograph2G = 0; - Skin_Spectograph2B = 0.2; - - Skin_SzczytR = 0.8; - Skin_SzczytG = 0; - Skin_SzczytB = 0; - - Skin_SzczytLimitR = 0; - Skin_SzczytLimitG = 0.8; - Skin_SzczytLimitB = 0; - - Skin_FontR = 0; - Skin_FontG = 0; - Skin_FontB = 0; - - Skin_FontHighlightR = 0.3; // 0.3 - Skin_FontHighlightG = 0.3; // 0.3 - Skin_FontHighlightB = 1; // 1 - - Skin_TimeR = 0.25; //0,0,0 - Skin_TimeG = 0.25; - Skin_TimeB = 0.25; - - Skin_OscR = 0; - Skin_OscG = 0; - Skin_OscB = 0; - - Skin_LyricsT = 494; // 500 / 510 / 400 - Skin_SpectrumT = 470; - Skin_SpectrumBot = 570; - Skin_SpectrumH = 100; - - Skin_P1_LinesR = 0.5; // 0.6 0.6 1 - Skin_P1_LinesG = 0.5; - Skin_P1_LinesB = 0.5; - - Skin_P2_LinesR = 0.5; // 1 0.6 0.6 - Skin_P2_LinesG = 0.5; - Skin_P2_LinesB = 0.5; - - Skin_P1_NotesB = 250; - Skin_P2_NotesB = 430; // 430 / 300 - - Skin_P1_ScoreT = 50; - Skin_P1_ScoreL = 20; - - Skin_P2_ScoreT = 50; - Skin_P2_ScoreL = 640; - -procedure Initialize3D (Title: string); -procedure Reinitialize3D; -procedure SwapBuffers; - -procedure LoadTextures; -procedure InitializeScreen; -procedure LoadLoadingScreen; -procedure LoadScreens; - -function LoadingThreadFunction: integer; - - -implementation - -uses UMain, - UIni, - UDisplay, - UCommandLine, - {$IFNDEF FPC} - Graphics, - {$ENDIF} - {$IFDEF win32} - windows, - {$ENDIF} - Classes; - -procedure LoadTextures; - - -var - P: integer; - R, G, B: real; - Col: integer; -begin - // zaladowanie tekstur - Log.LogStatus('Loading Textures', 'LoadTextures'); - Tex_Left[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayLeft')), 'BMP', 'Transparent', 0); //brauch man die noch? - Tex_Mid[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayMid')), 'BMP', 'Plain', 0); //brauch man die noch? - Tex_Right[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayRight')), 'BMP', 'Transparent', 0); //brauch man die noch? - - // P1-6 - for P := 1 to 6 do begin - LoadColor(R, G, B, 'P' + IntToStr(P) + 'Light'); - Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255); - Tex_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayLeft')), 'PNG', 'Colorized', Col); - Tex_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayMid')), 'PNG', 'Colorized', Col); - Tex_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayRight')), 'PNG', 'Colorized', Col); - - Tex_plain_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainLeft')), 'PNG', 'Colorized', Col); - Tex_plain_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainMid')), 'PNG', 'Colorized', Col); - Tex_plain_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainRight')), 'PNG', 'Colorized', Col); - - Tex_BG_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGLeft')), 'PNG', 'Colorized', Col); - Tex_BG_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGMid')), 'PNG', 'Colorized', Col); - Tex_BG_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGRight')), 'PNG', 'Colorized', Col); - end; - - Tex_Note_Perfect_Star := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePerfectStar')), 'JPG', 'Font Black', 0); - Tex_Note_Star := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteStar')) , 'JPG', 'Alpha Black Colored', $FFFFFF); - Tex_Ball := Texture.LoadTexture(pchar(Skin.GetTextureFileName('Ball')), 'BMP', 'Transparent', $FF00FF); - Tex_Lyric_Help_Bar := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LyricHelpBar')), 'BMP', 'Transparent', $FF00FF); - - - //TimeBar mod - Tex_TimeProgress := Texture.LoadTexture(pchar(Skin.GetTextureFileName('TimeBar'))); - //eoa TimeBar mod - - //SingBar Mod - Tex_SingBar_Back := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarBack')), 'JPG', 'Plain', 0); - Tex_SingBar_Bar := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarBar')), 'JPG', 'Plain', 0); - Tex_SingBar_Front := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarFront')), 'JPG', 'Font', 0); - //end Singbar Mod - - //Line Bonus PopUp - for P := 0 to 8 do - begin - Tex_SingLineBonusBack[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LineBonusBack')), 'PNG', 'Colorized', $FFFFFF); - end; - {//Set Texture to Font High - Tex_SingLineBonusL.H := 32; Tex_SingLineBonusL.W := 8; - Tex_SingLineBonusM.H := 32; //Tex_SingLineBonusM.TexW := Tex_SingLineBonusM.TexW/2; - Tex_SingLineBonusR.H := 32; Tex_SingLineBonusR.W := 8; } - //PhrasenBonus - Line Bonus Mod End - - // tworzenie czcionek - Log.LogStatus('Building Fonts', 'LoadTextures'); - BuildFont; -end; - -procedure Initialize3D (Title: string); -var -// Icon: TIcon; - Res: TResourceStream; - ISurface: PSDL_Surface; - Pixel: PByteArray; - I: Integer; -begin - Log.LogStatus('LoadOpenGL', 'Initialize3D'); - Log.BenchmarkStart(2); - - LoadOpenGL; - - Log.LogStatus('SDL_Init', 'Initialize3D'); - if ( SDL_Init(SDL_INIT_VIDEO or SDL_INIT_AUDIO)= -1 ) then begin - Log.LogError('SDL_Init Failed', 'Initialize3D'); - exit; - end; - - { //Load Icon - Res := TResourceStream.CreateFromID(HInstance, 3, RT_ICON); - Icon := TIcon.Create; - Icon.LoadFromStream(Res); - Res.Free; - Icon. - //Create icon Surface - SDL_CreateRGBSurfaceFrom ( - SDL_SWSURFACE, - Icon.Width, - Icon.Height, - 32, - 128 or 64, - 32 or 16, - 8 or 4, - 2 or 1); - //SDL_BlitSurface( - - - SDL_WM_SetIcon(SDL_LoadBMP('DEFAULT_WINDOW_ICON'), 0); //} - - SDL_WM_SetCaption(PChar(Title), nil); - - InitializeScreen; - - Log.BenchmarkEnd(2); - Log.LogBenchmark('--> Setting Screen', 2); - - // ladowanie tekstur - Log.BenchmarkStart(2); - Texture := TTextureUnit.Create; - Texture.Limit := 1024*1024; - - LoadTextures; - Log.BenchmarkEnd(2); - Log.LogBenchmark('--> Loading Textures', 2); - - Log.BenchmarkStart(2); - Lyric := TLyric.Create; - Log.BenchmarkEnd(2); - Log.LogBenchmark('--> Loading Fonts', 2); - - Log.BenchmarkStart(2); - Display := TDisplay.Create; - SDL_EnableUnicode(1); - Log.BenchmarkEnd(2); Log.LogBenchmark('====> Creating Display', 2); - - Log.LogStatus('Loading Screens', 'Initialize3D'); - Log.BenchmarkStart(3); - - LoadLoadingScreen; - // now that we have something to display while loading, - // start thread that loads the rest of ultrastar -// Mutex := SDL_CreateMutex; -// SDL_UnLockMutex(Mutex); - - // funktioniert so noch nicht, da der ladethread unverändert auf opengl zugreifen will - // siehe dazu kommentar unten - //LoadingThread := SDL_CreateThread(@LoadingThread, nil); - - // das hier würde dann im ladethread ausgeführt - LoadScreens; - - - // TODO!!!!!!1 - // hier käme jetzt eine schleife, die - // * den ladescreen malt (ab und zu) - // * den "fortschritt" des ladescreens steuert - // * zwischendrin schaut, ob der ladethread texturen geladen hat (mutex prüfen) und - // * die texturen in die opengl lädt, sowie - // * dem ladethread signalisiert, dass der speicher für die textur - // zum laden der nächsten textur weiterverwendet werden kann (über weiteren mutex) - // * über einen 3. mutex so lange läuft, bis der ladethread signalisiert, - // dass er alles geladen hat fertig ist - // - // dafür muss loadtexture so umgeschrieben werden, dass es, statt selbst irgendwelche - // opengl funktionen aufzurufen, entsprechend mutexe verändert - // der hauptthread muss auch irgendwoher erfahren, was an opengl funktionen auszuführen ist, - // mit welchen parametern (texturtyp, entspr. texturobjekt, textur-zwischenspeicher-adresse, ... - - - //wait for loading thread to finish - // funktioniert so auch noch nicht - //SDL_WaitThread(LoadingThread, I); -// SDL_DestroyMutex(Mutex); - - Display.ActualScreen^.FadeTo(@ScreenMain); - - Log.BenchmarkEnd(2); - Log.LogBenchmark('--> Loading Screens', 2); - - Log.LogStatus('Finish', 'Initialize3D'); -end; - -procedure SwapBuffers; -begin - SDL_GL_SwapBuffers; - glMatrixMode(GL_PROJECTION); - glLoadIdentity; - glOrtho(0, RenderW, RenderH, 0, -1, 100); - glMatrixMode(GL_MODELVIEW); -end; - -procedure Reinitialize3D; -begin -// InitializeScreen; -// LoadTextures; -// LoadScreens; -end; - -procedure InitializeScreen; -var - S: string; - I: integer; - W, H: integer; - Depth: Integer; -begin - if (Params.Screens <> -1) then - Screens := Params.Screens + 1 - else - Screens := Ini.Screens + 1; - - SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - - // If there is a resolution in Parameters, use it, else use the Ini value - I := Params.Resolution; - if (I <> -1) then - S := IResolution[I] - else - S := IResolution[Ini.Resolution]; - - I := Pos('x', S); - W := StrToInt(Copy(S, 1, I-1)) * Screens; - H := StrToInt(Copy(S, I+1, 1000)); - - {if ParamStr(1) = '-fsblack' then begin - W := 800; - H := 600; - end; - if ParamStr(1) = '-320x240' then begin - W := 320; - H := 240; - end; } - - If (Params.Depth <> -1) then - Depth := Params.Depth - else - Depth := Ini.Depth; - - - Log.LogStatus('SDL_SetVideoMode', 'Initialize3D'); -// SDL_SetRefreshrate(85); -// SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); - if (Ini.FullScreen = 0) and (Not Params.FullScreen) then - screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL) - else begin - screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN); - SDL_ShowCursor(0); - end; - if (screen = nil) then begin - Log.LogError('SDL_SetVideoMode Failed', 'Initialize3D'); - exit; - end; - - // clear screen once window is being shown - glClearColor(1, 1, 1, 1); - glClear(GL_COLOR_BUFFER_BIT); - SwapBuffers; - - // zmienne - RenderW := 800; - RenderH := 600; - ScreenW := W; - ScreenH := H; -end; - -procedure LoadLoadingScreen; -begin - ScreenLoading := TScreenLoading.Create; - ScreenLoading.onShow; - Display.ActualScreen := @ScreenLoading; - swapbuffers; - ScreenLoading.Draw; - Display.Draw; - SwapBuffers; -end; - -procedure LoadScreens; -begin -{ ScreenLoading := TScreenLoading.Create; - ScreenLoading.onShow; - Display.ActualScreen := @ScreenLoading; - ScreenLoading.Draw; - Display.Draw; - SwapBuffers; -} - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Loading', 3); Log.BenchmarkStart(3); -{ ScreenWelcome := TScreenWelcome.Create; //'BG', 4, 3); - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Welcome', 3); Log.BenchmarkStart(3);} - ScreenMain := TScreenMain.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Main', 3); Log.BenchmarkStart(3); - ScreenName := TScreenName.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Name', 3); Log.BenchmarkStart(3); - ScreenLevel := TScreenLevel.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Level', 3); Log.BenchmarkStart(3); - ScreenSong := TScreenSong.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song', 3); Log.BenchmarkStart(3); - ScreenSongMenu := TScreenSongMenu.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song Menu', 3); Log.BenchmarkStart(3); - ScreenSing := TScreenSing.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing', 3); Log.BenchmarkStart(3); - ScreenScore := TScreenScore.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Score', 3); Log.BenchmarkStart(3); - ScreenTop5 := TScreenTop5.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Top5', 3); Log.BenchmarkStart(3); - ScreenOptions := TScreenOptions.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options', 3); Log.BenchmarkStart(3); - ScreenOptionsGame := TScreenOptionsGame.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Game', 3); Log.BenchmarkStart(3); - ScreenOptionsGraphics := TScreenOptionsGraphics.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Graphics', 3); Log.BenchmarkStart(3); - ScreenOptionsSound := TScreenOptionsSound.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Sound', 3); Log.BenchmarkStart(3); - ScreenOptionsLyrics := TScreenOptionsLyrics.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Lyrics', 3); Log.BenchmarkStart(3); - ScreenOptionsThemes := TScreenOptionsThemes.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Themes', 3); Log.BenchmarkStart(3); - ScreenOptionsRecord := TScreenOptionsRecord.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Record', 3); Log.BenchmarkStart(3); - ScreenOptionsAdvanced := TScreenOptionsAdvanced.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Advanced', 3); Log.BenchmarkStart(3); - ScreenEditSub := TScreenEditSub.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Sub', 3); Log.BenchmarkStart(3); - ScreenEdit := TScreenEdit.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit', 3); Log.BenchmarkStart(3); - ScreenEditConvert := TScreenEditConvert.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen EditConvert', 3); Log.BenchmarkStart(3); -// ScreenEditHeader := TScreenEditHeader.Create(Skin.ScoreBG); -// Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Header', 3); Log.BenchmarkStart(3); - ScreenOpen := TScreenOpen.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Open', 3); Log.BenchmarkStart(3); - ScreenSingModi := TScreenSingModi.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing with Modi support', 3); Log.BenchmarkStart(3); - ScreenSongMenu := TScreenSongMenu.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongMenu', 3); Log.BenchmarkStart(3); - ScreenSongJumpto := TScreenSongJumpto.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongJumpto', 3); Log.BenchmarkStart(3); - ScreenPopupCheck := TScreenPopupCheck.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Check)', 3); Log.BenchmarkStart(3); - ScreenPopupError := TScreenPopupError.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Error)', 3); Log.BenchmarkStart(3); - ScreenPartyNewRound := TScreenPartyNewRound.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyNewRound', 3); Log.BenchmarkStart(3); - ScreenPartyScore := TScreenPartyScore.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyScore', 3); Log.BenchmarkStart(3); - ScreenPartyWin := TScreenPartyWin.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyWin', 3); Log.BenchmarkStart(3); - ScreenPartyOptions := TScreenPartyOptions.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyOptions', 3); Log.BenchmarkStart(3); - ScreenPartyPlayer := TScreenPartyPlayer.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyPlayer', 3); Log.BenchmarkStart(3); - ScreenStatMain := TScreenStatMain.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Main', 3); Log.BenchmarkStart(3); - ScreenStatDetail := TScreenStatDetail.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Detail', 3); Log.BenchmarkStart(3); - ScreenCredits := TScreenCredits.Create; - Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Credits', 3); Log.BenchmarkStart(3); - - end; - -function LoadingThreadFunction: integer; -begin - LoadScreens; - Result:= 1; -end; - -end. +unit UGraphic; + +interface + +{$I switches.inc} + +{$IFDEF FPC} + {$MODE DELPHI} +{$ENDIF} + +uses + SDL, + OpenGL12, + UTexture, + TextGL, + ULog, + SysUtils, + ULyrics, + UScreenLoading, + UScreenWelcome, + UScreenMain, + UScreenName, + UScreenLevel, + UScreenOptions, + UScreenOptionsGame, + UScreenOptionsGraphics, + UScreenOptionsSound, + UScreenOptionsLyrics, + UScreenOptionsThemes, + UScreenOptionsRecord, + UScreenOptionsAdvanced, + UScreenSong, + UScreenSing, + UScreenScore, + UScreenTop5, + UScreenEditSub, + UScreenEdit, + UScreenEditConvert, + UScreenEditHeader, + UScreenOpen, + UThemes, + USkins, + UScreenSongMenu, + UScreenSongJumpto, + {Party Screens} + UScreenSingModi, + UScreenPartyNewRound, + UScreenPartyScore, + UScreenPartyOptions, + UScreenPartyWin, + UScreenPartyPlayer, + {Stats Screens} + UScreenStatMain, + UScreenStatDetail, + {CreditsScreen} + UScreenCredits, + {Popup for errors, etc.} + UScreenPopup; + +type + TRecR = record + Top: real; + Left: real; + Right: real; + Bottom: real; + end; + +var + Screen: PSDL_Surface; + + LoadingThread: PSDL_Thread; + Mutex: PSDL_Mutex; + + RenderW: integer; + RenderH: integer; + ScreenW: integer; + ScreenH: integer; + Screens: integer; + ScreenAct: integer; + ScreenX: integer; + + ScreenLoading: TScreenLoading; + ScreenWelcome: TScreenWelcome; + ScreenMain: TScreenMain; + ScreenName: TScreenName; + ScreenLevel: TScreenLevel; + ScreenSong: TScreenSong; + ScreenSing: TScreenSing; + ScreenScore: TScreenScore; + ScreenTop5: TScreenTop5; + ScreenOptions: TScreenOptions; + ScreenOptionsGame: TScreenOptionsGame; + ScreenOptionsGraphics: TScreenOptionsGraphics; + ScreenOptionsSound: TScreenOptionsSound; + ScreenOptionsLyrics: TScreenOptionsLyrics; + ScreenOptionsThemes: TScreenOptionsThemes; + ScreenOptionsRecord: TScreenOptionsRecord; + ScreenOptionsAdvanced: TScreenOptionsAdvanced; + ScreenEditSub: TScreenEditSub; + ScreenEdit: TScreenEdit; + ScreenEditConvert: TScreenEditConvert; + ScreenEditHeader: TScreenEditHeader; + ScreenOpen: TScreenOpen; + + ScreenSongMenu: TScreenSongMenu; + ScreenSongJumpto: TScreenSongJumpto; + + //Party Screens + ScreenSingModi: TScreenSingModi; + ScreenPartyNewRound: TScreenPartyNewRound; + ScreenPartyScore: TScreenPartyScore; + ScreenPartyWin: TScreenPartyWin; + ScreenPartyOptions: TScreenPartyOptions; + ScreenPartyPlayer: TScreenPartyPlayer; + + //StatsScreens + ScreenStatMain: TScreenStatMain; + ScreenStatDetail: TScreenStatDetail; + + //CreditsScreen + ScreenCredits: TScreenCredits; + + //popup mod + ScreenPopupCheck: TScreenPopupCheck; + ScreenPopupError: TScreenPopupError; + + //Notes + Tex_Left: array[0..6] of TTexture; //rename to tex_note_left + Tex_Mid: array[0..6] of TTexture; //rename to tex_note_mid + Tex_Right: array[0..6] of TTexture; //rename to tex_note_right + + Tex_plain_Left: array[1..6] of TTexture; //rename to tex_notebg_left + Tex_plain_Mid: array[1..6] of TTexture; //rename to tex_notebg_mid + Tex_plain_Right: array[1..6] of TTexture; //rename to tex_notebg_right + + Tex_BG_Left: array[1..6] of TTexture; //rename to tex_noteglow_left + Tex_BG_Mid: array[1..6] of TTexture; //rename to tex_noteglow_mid + Tex_BG_Right: array[1..6] of TTexture; //rename to tex_noteglow_right + + Tex_Note_Star: TTexture; + Tex_Note_Perfect_Star: TTexture; + + + Tex_Ball: TTexture; + Tex_Lyric_Help_Bar: TTexture; + FullScreen: boolean; + + Tex_TimeProgress: TTexture; + + //Sing Bar Mod + Tex_SingBar_Back: TTexture; + Tex_SingBar_Bar: TTexture; + Tex_SingBar_Front: TTexture; + //end Singbar Mod + + //PhrasenBonus - Line Bonus Mod + Tex_SingLineBonusBack: array[0..8] of TTexture; + //End PhrasenBonus - Line Bonus Mod + +const + Skin_BGColorR = 1; + Skin_BGColorG = 1; + Skin_BGColorB = 1; + + Skin_SpectrumR = 0; + Skin_SpectrumG = 0; + Skin_SpectrumB = 0; + + Skin_Spectograph1R = 0.6; + Skin_Spectograph1G = 0.8; + Skin_Spectograph1B = 1; + + Skin_Spectograph2R = 0; + Skin_Spectograph2G = 0; + Skin_Spectograph2B = 0.2; + + Skin_SzczytR = 0.8; + Skin_SzczytG = 0; + Skin_SzczytB = 0; + + Skin_SzczytLimitR = 0; + Skin_SzczytLimitG = 0.8; + Skin_SzczytLimitB = 0; + + Skin_FontR = 0; + Skin_FontG = 0; + Skin_FontB = 0; + + Skin_FontHighlightR = 0.3; // 0.3 + Skin_FontHighlightG = 0.3; // 0.3 + Skin_FontHighlightB = 1; // 1 + + Skin_TimeR = 0.25; //0,0,0 + Skin_TimeG = 0.25; + Skin_TimeB = 0.25; + + Skin_OscR = 0; + Skin_OscG = 0; + Skin_OscB = 0; + + Skin_LyricsT = 494; // 500 / 510 / 400 + Skin_SpectrumT = 470; + Skin_SpectrumBot = 570; + Skin_SpectrumH = 100; + + Skin_P1_LinesR = 0.5; // 0.6 0.6 1 + Skin_P1_LinesG = 0.5; + Skin_P1_LinesB = 0.5; + + Skin_P2_LinesR = 0.5; // 1 0.6 0.6 + Skin_P2_LinesG = 0.5; + Skin_P2_LinesB = 0.5; + + Skin_P1_NotesB = 250; + Skin_P2_NotesB = 430; // 430 / 300 + + Skin_P1_ScoreT = 50; + Skin_P1_ScoreL = 20; + + Skin_P2_ScoreT = 50; + Skin_P2_ScoreL = 640; + +procedure Initialize3D (Title: string); +procedure Reinitialize3D; +procedure SwapBuffers; + +procedure LoadTextures; +procedure InitializeScreen; +procedure LoadLoadingScreen; +procedure LoadScreens; + +function LoadingThreadFunction: integer; + + +implementation + +uses UMain, + UIni, + UDisplay, + UCommandLine, + {$IFNDEF FPC} + Graphics, + {$ENDIF} + {$IFDEF win32} + windows, + {$ENDIF} + Classes; + +procedure LoadTextures; + + +var + P: integer; + R, G, B: real; + Col: integer; +begin + // zaladowanie tekstur + Log.LogStatus('Loading Textures', 'LoadTextures'); + Tex_Left[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayLeft')), 'BMP', 'Transparent', 0); //brauch man die noch? + Tex_Mid[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayMid')), 'BMP', 'Plain', 0); //brauch man die noch? + Tex_Right[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayRight')), 'BMP', 'Transparent', 0); //brauch man die noch? + + // P1-6 + for P := 1 to 6 do begin + LoadColor(R, G, B, 'P' + IntToStr(P) + 'Light'); + Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255); + Tex_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayLeft')), 'PNG', 'Colorized', Col); + Tex_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayMid')), 'PNG', 'Colorized', Col); + Tex_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayRight')), 'PNG', 'Colorized', Col); + + Tex_plain_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainLeft')), 'PNG', 'Colorized', Col); + Tex_plain_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainMid')), 'PNG', 'Colorized', Col); + Tex_plain_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainRight')), 'PNG', 'Colorized', Col); + + Tex_BG_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGLeft')), 'PNG', 'Colorized', Col); + Tex_BG_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGMid')), 'PNG', 'Colorized', Col); + Tex_BG_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGRight')), 'PNG', 'Colorized', Col); + end; + + Tex_Note_Perfect_Star := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePerfectStar')), 'JPG', 'Font Black', 0); + Tex_Note_Star := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteStar')) , 'JPG', 'Alpha Black Colored', $FFFFFF); + Tex_Ball := Texture.LoadTexture(pchar(Skin.GetTextureFileName('Ball')), 'BMP', 'Transparent', $FF00FF); + Tex_Lyric_Help_Bar := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LyricHelpBar')), 'BMP', 'Transparent', $FF00FF); + + + //TimeBar mod + Tex_TimeProgress := Texture.LoadTexture(pchar(Skin.GetTextureFileName('TimeBar'))); + //eoa TimeBar mod + + //SingBar Mod + Tex_SingBar_Back := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarBack')), 'JPG', 'Plain', 0); + Tex_SingBar_Bar := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarBar')), 'JPG', 'Plain', 0); + Tex_SingBar_Front := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarFront')), 'JPG', 'Font', 0); + //end Singbar Mod + + //Line Bonus PopUp + for P := 0 to 8 do + begin + Tex_SingLineBonusBack[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LineBonusBack')), 'PNG', 'Colorized', $FFFFFF); + end; + {//Set Texture to Font High + Tex_SingLineBonusL.H := 32; Tex_SingLineBonusL.W := 8; + Tex_SingLineBonusM.H := 32; //Tex_SingLineBonusM.TexW := Tex_SingLineBonusM.TexW/2; + Tex_SingLineBonusR.H := 32; Tex_SingLineBonusR.W := 8; } + //PhrasenBonus - Line Bonus Mod End + + // tworzenie czcionek + Log.LogStatus('Building Fonts', 'LoadTextures'); + BuildFont; +end; + +procedure Initialize3D (Title: string); +var +// Icon: TIcon; + Res: TResourceStream; + ISurface: PSDL_Surface; + Pixel: PByteArray; + I: Integer; +begin + Log.LogStatus('LoadOpenGL', 'Initialize3D'); + Log.BenchmarkStart(2); + + LoadOpenGL; + + Log.LogStatus('SDL_Init', 'Initialize3D'); + if ( SDL_Init(SDL_INIT_VIDEO or SDL_INIT_AUDIO)= -1 ) then begin + Log.LogError('SDL_Init Failed', 'Initialize3D'); + exit; + end; + + { //Load Icon + Res := TResourceStream.CreateFromID(HInstance, 3, RT_ICON); + Icon := TIcon.Create; + Icon.LoadFromStream(Res); + Res.Free; + Icon. + //Create icon Surface + SDL_CreateRGBSurfaceFrom ( + SDL_SWSURFACE, + Icon.Width, + Icon.Height, + 32, + 128 or 64, + 32 or 16, + 8 or 4, + 2 or 1); + //SDL_BlitSurface( + + + SDL_WM_SetIcon(SDL_LoadBMP('DEFAULT_WINDOW_ICON'), 0); //} + + SDL_WM_SetCaption(PChar(Title), nil); + + InitializeScreen; + + Log.BenchmarkEnd(2); + Log.LogBenchmark('--> Setting Screen', 2); + + // ladowanie tekstur + Log.BenchmarkStart(2); + Texture := TTextureUnit.Create; + Texture.Limit := 1024*1024; + + LoadTextures; + Log.BenchmarkEnd(2); + Log.LogBenchmark('--> Loading Textures', 2); + +{ Log.BenchmarkStart(2); + Lyric:= TLyric.Create; + Log.BenchmarkEnd(2); + Log.LogBenchmark('--> Loading Fonts', 2); +} + Log.BenchmarkStart(2); + Display := TDisplay.Create; + SDL_EnableUnicode(1); + Log.BenchmarkEnd(2); Log.LogBenchmark('====> Creating Display', 2); + + Log.LogStatus('Loading Screens', 'Initialize3D'); + Log.BenchmarkStart(3); + + LoadLoadingScreen; + // now that we have something to display while loading, + // start thread that loads the rest of ultrastar +// Mutex := SDL_CreateMutex; +// SDL_UnLockMutex(Mutex); + + // funktioniert so noch nicht, da der ladethread unverändert auf opengl zugreifen will + // siehe dazu kommentar unten + //LoadingThread := SDL_CreateThread(@LoadingThread, nil); + + // das hier würde dann im ladethread ausgeführt + LoadScreens; + + + // TODO!!!!!!1 + // hier käme jetzt eine schleife, die + // * den ladescreen malt (ab und zu) + // * den "fortschritt" des ladescreens steuert + // * zwischendrin schaut, ob der ladethread texturen geladen hat (mutex prüfen) und + // * die texturen in die opengl lädt, sowie + // * dem ladethread signalisiert, dass der speicher für die textur + // zum laden der nächsten textur weiterverwendet werden kann (über weiteren mutex) + // * über einen 3. mutex so lange läuft, bis der ladethread signalisiert, + // dass er alles geladen hat fertig ist + // + // dafür muss loadtexture so umgeschrieben werden, dass es, statt selbst irgendwelche + // opengl funktionen aufzurufen, entsprechend mutexe verändert + // der hauptthread muss auch irgendwoher erfahren, was an opengl funktionen auszuführen ist, + // mit welchen parametern (texturtyp, entspr. texturobjekt, textur-zwischenspeicher-adresse, ... + + + //wait for loading thread to finish + // funktioniert so auch noch nicht + //SDL_WaitThread(LoadingThread, I); +// SDL_DestroyMutex(Mutex); + + Display.ActualScreen^.FadeTo(@ScreenMain); + + Log.BenchmarkEnd(2); + Log.LogBenchmark('--> Loading Screens', 2); + + Log.LogStatus('Finish', 'Initialize3D'); +end; + +procedure SwapBuffers; +begin + SDL_GL_SwapBuffers; + glMatrixMode(GL_PROJECTION); + glLoadIdentity; + glOrtho(0, RenderW, RenderH, 0, -1, 100); + glMatrixMode(GL_MODELVIEW); +end; + +procedure Reinitialize3D; +begin +// InitializeScreen; +// LoadTextures; +// LoadScreens; +end; + +procedure InitializeScreen; +var + S: string; + I: integer; + W, H: integer; + Depth: Integer; +begin + if (Params.Screens <> -1) then + Screens := Params.Screens + 1 + else + Screens := Ini.Screens + 1; + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + // If there is a resolution in Parameters, use it, else use the Ini value + I := Params.Resolution; + if (I <> -1) then + S := IResolution[I] + else + S := IResolution[Ini.Resolution]; + + I := Pos('x', S); + W := StrToInt(Copy(S, 1, I-1)) * Screens; + H := StrToInt(Copy(S, I+1, 1000)); + + {if ParamStr(1) = '-fsblack' then begin + W := 800; + H := 600; + end; + if ParamStr(1) = '-320x240' then begin + W := 320; + H := 240; + end; } + + If (Params.Depth <> -1) then + Depth := Params.Depth + else + Depth := Ini.Depth; + + + Log.LogStatus('SDL_SetVideoMode', 'Initialize3D'); +// SDL_SetRefreshrate(85); +// SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + if (Ini.FullScreen = 0) and (Not Params.FullScreen) then + screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL) + else begin + screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN); + SDL_ShowCursor(0); + end; + if (screen = nil) then begin + Log.LogError('SDL_SetVideoMode Failed', 'Initialize3D'); + exit; + end; + + // clear screen once window is being shown + glClearColor(1, 1, 1, 1); + glClear(GL_COLOR_BUFFER_BIT); + SwapBuffers; + + // zmienne + RenderW := 800; + RenderH := 600; + ScreenW := W; + ScreenH := H; +end; + +procedure LoadLoadingScreen; +begin + ScreenLoading := TScreenLoading.Create; + ScreenLoading.onShow; + Display.ActualScreen := @ScreenLoading; + swapbuffers; + ScreenLoading.Draw; + Display.Draw; + SwapBuffers; +end; + +procedure LoadScreens; +begin +{ ScreenLoading := TScreenLoading.Create; + ScreenLoading.onShow; + Display.ActualScreen := @ScreenLoading; + ScreenLoading.Draw; + Display.Draw; + SwapBuffers; +} + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Loading', 3); Log.BenchmarkStart(3); +{ ScreenWelcome := TScreenWelcome.Create; //'BG', 4, 3); + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Welcome', 3); Log.BenchmarkStart(3);} + ScreenMain := TScreenMain.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Main', 3); Log.BenchmarkStart(3); + ScreenName := TScreenName.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Name', 3); Log.BenchmarkStart(3); + ScreenLevel := TScreenLevel.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Level', 3); Log.BenchmarkStart(3); + ScreenSong := TScreenSong.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song', 3); Log.BenchmarkStart(3); + ScreenSongMenu := TScreenSongMenu.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song Menu', 3); Log.BenchmarkStart(3); + ScreenSing := TScreenSing.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing', 3); Log.BenchmarkStart(3); + ScreenScore := TScreenScore.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Score', 3); Log.BenchmarkStart(3); + ScreenTop5 := TScreenTop5.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Top5', 3); Log.BenchmarkStart(3); + ScreenOptions := TScreenOptions.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options', 3); Log.BenchmarkStart(3); + ScreenOptionsGame := TScreenOptionsGame.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Game', 3); Log.BenchmarkStart(3); + ScreenOptionsGraphics := TScreenOptionsGraphics.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Graphics', 3); Log.BenchmarkStart(3); + ScreenOptionsSound := TScreenOptionsSound.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Sound', 3); Log.BenchmarkStart(3); + ScreenOptionsLyrics := TScreenOptionsLyrics.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Lyrics', 3); Log.BenchmarkStart(3); + ScreenOptionsThemes := TScreenOptionsThemes.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Themes', 3); Log.BenchmarkStart(3); + ScreenOptionsRecord := TScreenOptionsRecord.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Record', 3); Log.BenchmarkStart(3); + ScreenOptionsAdvanced := TScreenOptionsAdvanced.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Advanced', 3); Log.BenchmarkStart(3); + ScreenEditSub := TScreenEditSub.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Sub', 3); Log.BenchmarkStart(3); + ScreenEdit := TScreenEdit.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit', 3); Log.BenchmarkStart(3); + ScreenEditConvert := TScreenEditConvert.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen EditConvert', 3); Log.BenchmarkStart(3); +// ScreenEditHeader := TScreenEditHeader.Create(Skin.ScoreBG); +// Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Header', 3); Log.BenchmarkStart(3); + ScreenOpen := TScreenOpen.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Open', 3); Log.BenchmarkStart(3); + ScreenSingModi := TScreenSingModi.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing with Modi support', 3); Log.BenchmarkStart(3); + ScreenSongMenu := TScreenSongMenu.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongMenu', 3); Log.BenchmarkStart(3); + ScreenSongJumpto := TScreenSongJumpto.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongJumpto', 3); Log.BenchmarkStart(3); + ScreenPopupCheck := TScreenPopupCheck.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Check)', 3); Log.BenchmarkStart(3); + ScreenPopupError := TScreenPopupError.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Error)', 3); Log.BenchmarkStart(3); + ScreenPartyNewRound := TScreenPartyNewRound.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyNewRound', 3); Log.BenchmarkStart(3); + ScreenPartyScore := TScreenPartyScore.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyScore', 3); Log.BenchmarkStart(3); + ScreenPartyWin := TScreenPartyWin.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyWin', 3); Log.BenchmarkStart(3); + ScreenPartyOptions := TScreenPartyOptions.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyOptions', 3); Log.BenchmarkStart(3); + ScreenPartyPlayer := TScreenPartyPlayer.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyPlayer', 3); Log.BenchmarkStart(3); + ScreenStatMain := TScreenStatMain.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Main', 3); Log.BenchmarkStart(3); + ScreenStatDetail := TScreenStatDetail.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Detail', 3); Log.BenchmarkStart(3); + ScreenCredits := TScreenCredits.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Credits', 3); Log.BenchmarkStart(3); + + end; + +function LoadingThreadFunction: integer; +begin + LoadScreens; + Result:= 1; +end; + +end. diff --git a/Game/Code/Classes/ULyrics.pas b/Game/Code/Classes/ULyrics.pas index 64762265..5cf6114d 100644 --- a/Game/Code/Classes/ULyrics.pas +++ b/Game/Code/Classes/ULyrics.pas @@ -1,390 +1,537 @@ unit ULyrics; interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -uses SysUtils, - OpenGL12, - UMusic; +uses OpenGL12, UTexture, UThemes, UMusic; type - TWord = record - X: real; - Y: real; - Size: real; - Width: real; - Text: string; - ColR: real; - ColG: real; - ColB: real; - Scale: real; - Done: real; - FontStyle: integer; - Italic: boolean; - Selected: boolean; + TLyricWord = record + X: Real; //X Pos of the Word + Width: Real; //Width of the Text + TexPos: Real; //Pos of the Word (0 to 1) in the Sentence Texture + TexWidth: Real; //width of the Word in Sentence Texture (0 to 1) + Start: Cardinal; //Start of the Words in Quarters (Beats) + Length: Cardinal; //Length of the Word in Quarters + Text: String; //Text of this Word + Freestyle: Boolean; //Is this Word Freestyle + end; + ALyricWord = array of TLyricWord; + + PLyricLine = ^TLyricLine; + TLyricLine = record + Text: String; //Text of the Line + Tex: glUInt; //Texture of the Text from this Line + Width: Real; //Width of the Lyricline in Tex + Size: Byte; //Size of the Font in the Texture + Words: ALyricWord; //Words from this Line + Start: Cardinal; //Start in Quarters of teh Line + Length: Cardinal; //Length in Quarters (From Start of First Note to the End of Last Note) + Freestyle: Boolean; //Complete Line is Freestyle ? + Players: Byte; //Which Players Sing this Line (1: Player1; 2: Player2; 4: Player3; [..]) + Done: Boolean; //Is Sentence Sung end; - TLyric = class + TLyricEngine = class private - AlignI: integer; - XR: real; - YR: real; - SizeR: real; - SelectedI: integer; - ScaleR: real; - StyleI: integer; // 0 - one selection, 1 - long selection, 2 - one selection with fade to normal text, 3 - long selection with fade with color from left - FontStyleI: integer; // font number - Word: array of TWord; - procedure SetX(Value: real); - procedure SetY(Value: real); - function GetClientX: real; - procedure SetAlign(Value: integer); - function GetSize: real; - procedure SetSize(Value: real); - procedure SetSelected(Value: integer); - procedure SetDone(Value: real); - procedure SetScale(Value: real); - procedure SetStyle(Value: integer); - procedure SetFStyle(Value: integer); - procedure Refresh; - procedure DrawNormal(W: integer); - procedure DrawPlain(W: integer); - procedure DrawScaled(W: integer); - procedure DrawSlide(W: integer); + EoLastSentence: Real; //When did the Last Sentence End (in Beats) + UpperLine: TLyricLine; //Line in the Upper Part of the Lyric Display + LowerLine: TLyricLine; //Line in the Lower Part of teh Lyric Display + QueueLine: TLyricLine; //Line that is in Queue and will be added when next Line is Finished + PUpperLine, PLowerLine, PQueueLine: PLyricLine; + + IndicatorTex: TTexture; //Texture for Lyric Indikator(Bar that indicates when the Line start) + BallTex: TTexture; //Texture of the Ball for cur. Word hover in Ballmode + PlayerIconTex: array[0..5] of //Textures for PlayerIcon Index: Playernum; Index2: Enabled/Disabled + array [0..1] of + TTexture; + + inQueue: Boolean; + LCounter: Word; + + //Some helper Procedures for Lyric Drawing + procedure DrawLyrics (Beat: Real); + procedure DrawLyricsLine(const X, W, Y: Real; Size: Byte; const Line: TLyricLine; Beat: Real); + procedure DrawPlayerIcon(const Player: Byte; const Enabled: Boolean; const X, Y, Size, Alpha: Real); public - ColR: real; - ColG: real; - ColB: real; - ColSR: real; - ColSG: real; - ColSB: real; - Italic: boolean; - Text: string; // LCD - - procedure AddWord(Text: string); // Moved from published, lazarus didnt like it - procedure AddCzesc(NrCzesci: integer); - - function SelectedLetter: integer; // LCD - function SelectedLength: integer; // LCD - - procedure Clear; - procedure Draw; - - published - property X: real write SetX; - property Y: real write SetY; - property ClientX: real read GetClientX; - property Align: integer write SetAlign; - property Size: real read GetSize write SetSize; - property Selected: integer read SelectedI write SetSelected; - property Done: real write SetDone; - property Scale: real write SetScale; - property Style: integer write SetStyle; - property FontStyle: integer write SetFStyle; + //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_akt: TRGBA; //Color of teh active Word + FontStyle: Byte; //Font for the Lyric Text + FontReSize: Boolean; //ReSize Lyrics if they don't fit Screen + + HoverEffekt: Byte; //Effekt of Hovering active Word: 0 - one selection, 1 - long selection, 2 - one selection with fade to normal text, 3 - long selection with fade with color from left + FadeInEffekt: Byte; //Effekt for Line Fading in: 0: No Effekt; 1: Fade Effekt; 2: Move Upwards from Bottom to Pos + FadeOutEffekt: Byte; //Effekt for Line Fading out: 0: No Effekt; 1: Fade Effekt; 2: Move Upwards + + UseLinearFilter:Boolean; //Should Linear Tex Filter be used + + //Song specific Settings + BPM: Real; + Resolution: Integer; + + + //properties to easily update this Class within other Parts of Code + property LineinQueue: Boolean read inQueue; //True when there is a Line in Queue + property LineCounter: Word read LCounter; //Lines that was Progressed so far (after last Clear) + + Constructor Create; overload; //Constructor, just get Memory + Constructor Create(ULX,ULY,ULW,ULS,LLX,LLY,LLW,LLS:Real); overload; + Procedure LoadTextures; //Load Player Textures and Create + + Procedure AddLine(Line: PLine); //Adds a Line to the Queue if there is Space + Procedure Draw (Beat: Real); //Procedure Draws Lyrics; Beat is curent Beat in Quarters + Procedure Clear (const cBPM: Real = 0; const cResolution: Integer = 0); //Clears all cached Song specific Information + + Destructor Free; //Frees Memory end; -var - Lyric: TLyric; +const LyricTexStart = 2/512; implementation -uses TextGL, UGraphic, UDrawTexture; +uses SysUtils, USkins, TextGL, UGraphic, UDisplay, dialogs; -procedure TLyric.SetX(Value: real); +//----------- +//Helper procs to use TRGB in Opengl ...maybe this should be somewhere else +//----------- +procedure glColorRGB(Color: TRGB); overload; begin - XR := Value; + glColor3f(Color.R, Color.G, Color.B); end; -procedure TLyric.SetY(Value: real); +procedure glColorRGB(Color: TRGBA); overload; begin - YR := Value; + glColor4f(Color.R, Color.G, Color.B, Color.A); end; -function TLyric.GetClientX: real; + + +//--------------- +// Create - Constructor, just get Memory +//--------------- +Constructor TLyricEngine.Create; begin - Result := Word[0].X; + BPM := 0; + Resolution := 0; + LCounter := 0; + inQueue := False; + + UpperLine.Done := True; + LowerLine.Done := True; + QueueLine.Done := True; + PUpperline:=@UpperLine; + PLowerLine:=@LowerLine; + PQueueLine:=@QueueLine; + + UseLinearFilter := True; end; -procedure TLyric.SetAlign(Value: integer); +Constructor TLyricEngine.Create(ULX,ULY,ULW,ULS,LLX,LLY,LLW,LLS:Real); begin - AlignI := Value; -// if AlignInt = 0 then beep; + Create; + UpperLineX := ULX; + UpperLineW := ULW; + UpperLineY := ULY; + UpperLineSize := Trunc(ULS); + + LowerLineX := LLX; + LowerLineW := LLW; + LowerLineY := LLY; + LowerLineSize := Trunc(LLS); + LoadTextures; end; -function TLyric.GetSize: real; + +//--------------- +// Free - Frees Memory +//--------------- +Destructor TLyricEngine.Free; begin - Result := SizeR; + end; -procedure TLyric.SetSize(Value: real); +//--------------- +// Clear - Clears all cached Song specific Information +//--------------- +Procedure TLyricEngine.Clear (const cBPM: Real; const cResolution: Integer); begin - SizeR := Value; + BPM := cBPM; + Resolution := cResolution; + LCounter := 0; + inQueue := False; + + UpperLine.Done := True; + LowerLine.Done := True; + QueueLine.Done := True; + + PUpperline:=@UpperLine; + PLowerLine:=@LowerLine; + PQueueLine:=@QueueLine; end; -procedure TLyric.SetSelected(Value: integer); + +//--------------- +// LoadTextures - Load Player Textures and Create Lyric Textures +//--------------- +Procedure TLyricEngine.LoadTextures; var - W: integer; -begin - if (StyleI = 0) or (StyleI = 2) or (StyleI = 4) then begin - if (SelectedI > -1) and (SelectedI <= High(Word)) then begin - Word[SelectedI].Selected := false; - Word[SelectedI].ColR := ColR; - Word[SelectedI].ColG := ColG; - Word[SelectedI].ColB := ColB; - Word[SelectedI].Done := 0; - end; + I: Integer; + PTexData: Pointer; - SelectedI := Value; - if (Value > -1) and (Value <= High(Word)) then begin - Word[Value].Selected := true; - Word[Value].ColR := ColSR; - Word[Value].ColG := ColSG; - Word[Value].ColB := ColSB; - Word[Value].Scale := ScaleR; - end; - end; + function CreateLineTex: glUint; + begin + GetMem(pTexData, 1024*128*4); //get Memory to save Tex in - if (StyleI = 1) or (StyleI = 3) then begin - if (SelectedI > -1) and (SelectedI <= High(Word)) then begin - for W := SelectedI to High(Word) do begin - Word[W].Selected := false; - Word[W].ColR := ColR; - Word[W].ColG := ColG; - Word[W].ColB := ColB; - Word[W].Done := 0; - end; - end; + //generate and bind Texture + glGenTextures(1, Result); + glBindTexture(GL_TEXTURE_2D, Result); - SelectedI := Value; - if (Value > -1) and (Value <= High(Word)) then begin - for W := 0 to Value do begin - Word[W].Selected := true; - Word[W].ColR := ColSR; - Word[W].ColG := ColSG; - Word[W].ColB := ColSB; - Word[W].Scale := ScaleR; - Word[W].Done := 1; - end; + //Get Memory + glTexImage2D(GL_TEXTURE_2D, 0, 4, 1024, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, pTexData); + + 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; + + //Free now unused Memory + FreeMem(pTexData); end; +begin + //Load Texture for Lyric Indikator(Bar that indicates when the Line start) + IndicatorTex := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LyricHelpBar')), 'BMP', 'Transparent', $FF00FF); - Refresh; -end; + //Load Texture of the Ball for cur. Word hover in Ballmode + BallTex := Texture.LoadTexture(pchar(Skin.GetTextureFileName('Ball')), 'BMP', 'Transparent', $FF00FF); -procedure TLyric.SetDone(Value: real); -var - W: integer; -begin - W := SelectedI; - if W > -1 then - Word[W].Done := Value; -end; + //Load PlayerTexs + For I := 0 to 1 do + begin + PlayerIconTex[I][0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LyricIcon_P' + InttoStr(I+1))), 'PNG', 'Transparent', 0); + PlayerIconTex[I][1] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LyricIconD_P' + InttoStr(I+1))), 'PNG', 'Transparent', 0); + end; -procedure TLyric.SetScale(Value: real); -begin - ScaleR := Value; -end; + //atm just unset other texs + For I := 2 to 5 do + begin + PlayerIconTex[I][0].TexNum := high(Cardinal); //Set to C's -1 + PlayerIconTex[I][1].TexNum := high(Cardinal); + end; -procedure TLyric.SetStyle(Value: integer); -begin - StyleI := Value; + //Create LineTexs + UpperLine.Tex := CreateLineTex; + LowerLine.Tex := CreateLineTex; + QueueLine.Tex := CreateLineTex; end; -procedure TLyric.SetFStyle(Value: integer); -begin - FontStyleI := Value; -end; -procedure TLyric.AddWord(Text: string); +//--------------- +// AddLine - Adds LyricLine to queue +//--------------- +Procedure TLyricEngine.AddLine(Line: PLine); var - WordNum: integer; + LyricLine: PLyricLine; + I: Integer; + countNotes: Cardinal; + PosX: Real; + Viewport: Array[0..3] of Integer; begin - WordNum := Length(Word); - SetLength(Word, WordNum + 1); - if WordNum = 0 then begin - Word[WordNum].X := XR; - end else begin - Word[WordNum].X := Word[WordNum - 1].X + Word[WordNum - 1].Width; + //Only Add Lines if there is enough space + If not LineinQueue then + begin + //Set Pointer to Line to Write + If (LineCounter = 0) then + LyricLine := PUpperLine //Set Upper Line + else if (LineCounter = 1) then + LyricLine := PLowerLine //Set Lower Line + else + begin + LyricLine := PQueueLine; //Set Queue Line + inQueue := True; //now there is a Queued Line + end; + end + else + begin + LyricLine:=PUpperLine; + PUpperLine:=PLowerLine; + PLowerLine:=PQueueLine; + PQueueLine:=LyricLine; end; - Word[WordNum].Y := YR; - Word[WordNum].Size := SizeR; - Word[WordNum].FontStyle := FontStyleI; // new - SetFontStyle(FontStyleI); - SetFontSize(SizeR); - Word[WordNum].Width := glTextWidth(pchar(Text)); - Word[WordNum].Text := Text; - Word[WordNum].ColR := ColR; - Word[WordNum].ColG := ColG; - Word[WordNum].ColB := ColB; - Word[WordNum].Scale := 1; - Word[WordNum].Done := 0; - Word[WordNum].Italic := Italic; - - Refresh; -end; + //Check if Sentence has Notes + If (Length(Line.Nuta) > 0) then + begin + //Copy Values from SongLine to LyricLine + CountNotes := high(Line.Nuta); + LyricLine.Start := Line.Nuta[0].Start; + LyricLine.Length := Line.Nuta[CountNotes].Start + Line.Nuta[CountNotes].Dlugosc - LyricLine.Start; + LyricLine.Freestyle := True; //is set by And Notes Freestyle while copying Notes + LyricLine.Text := ''; //Also Set while copying Notes + LyricLine.Players := 127; //All Players for now, no Duett Mode available + //Copy Words + SetLength(LyricLine.Words, CountNotes + 1); + For I := 0 to CountNotes do + begin + LyricLine.Freestyle := LyricLine.Freestyle AND Line.Nuta[I].FreeStyle; + LyricLine.Words[I].Start := Line.Nuta[I].Start; + LyricLine.Words[I].Length := Line.Nuta[I].Dlugosc; + LyricLine.Words[I].Text := Line.Nuta[I].Tekst; + LyricLine.Words[I].Freestyle := Line.Nuta[I].FreeStyle; + LyricLine.Text := LyricLine.Text + LyricLine.Words[I].Text + end; -procedure TLyric.AddCzesc(NrCzesci: integer); -var - N: integer; -begin - Clear; - for N := 0 to Czesci[0].Czesc[NrCzesci].HighNut do begin - Italic := Czesci[0].Czesc[NrCzesci].Nuta[N].FreeStyle; - AddWord(Czesci[0].Czesc[NrCzesci].Nuta[N].Tekst); - Text := Text + Czesci[0].Czesc[NrCzesci].Nuta[N].Tekst; - end; - Selected := -1; -end; + //Set Font Params + SetFontStyle(FontStyle); + SetFontPos(0, 0); + LyricLine.Size := UpperLineSize; + SetFontSize(LyricLine.Size); + SetFontItalic(False); + glColor4f(1, 1, 1, 1); -procedure TLyric.Clear; -begin -{ ColR := Skin_FontR; - ColG := Skin_FontG; - ColB := Skin_FontB;} - SetLength(Word, 0); - Text := ''; - SelectedI := -1; -end; + //Change Fontsize to Fit the Screen + While (LyricLine.Width > 508) do + begin + Dec(LyricLine.Size); -procedure TLyric.Refresh; -var - W: integer; - TotWidth: real; -begin - if AlignI = 1 then begin - TotWidth := 0; - for W := 0 to High(Word) do - TotWidth := TotWidth + Word[W].Width; - - Word[0].X := XR - TotWidth / 2; - for W := 1 to High(Word) do - Word[W].X := Word[W - 1].X + Word[W - 1].Width; + if (LyricLine.Size <=1) then + Break; + + SetFontSize(LyricLine.Size); + LyricLine.Width := glTextWidth(PChar(LyricLine.Text)); + end; + + //Set Word Positions and Line Size + PosX := 2 {LowerLineX + LowerLineW/2 + 80 - LyricLine.Width/2}; + For I := 0 to High(LyricLine.Words) do + begin + LyricLine.Words[I].X := PosX; + LyricLine.Words[I].Width := glTextWidth(PChar(LyricLine.Words[I].Text)); + LyricLine.Words[I].TexPos := PosX / 512; + LyricLine.Words[I].TexWidth := LyricLine.Words[I].TexWidth / 512; + + PosX := PosX + LyricLine.Words[I].Width; + end; + + //Create LyricTexture + //Prepare Ogl + glGetIntegerv(GL_VIEWPORT, @ViewPort); + glClearColor(0.0,0.0,0.0,0); + glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); + {glMatrixMode(GL_PROJECTION); + glLoadIdentity; + glOrtho(0, 1024, 64, 0, -1, 100); + glMatrixMode(GL_MODELVIEW);} + glViewport(0, 0, 512, 512); + + //Draw Lyrics + SetFontPos(0, 0); + glPrint(PChar(LyricLine.Text)); + + Display.ScreenShot; + //Copy to Texture + glBindTexture(GL_TEXTURE_2D, LyricLine.Tex); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 448, 512, 64, 0); + + //Clear Buffer + glClearColor(0,0,0,0); + glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); + + glViewPort(ViewPort[0], ViewPort[1], ViewPort[2], ViewPort[3]); + {glMatrixMode(GL_PROJECTION); + glLoadIdentity; + glOrtho(0, RenderW, RenderH, 0, -1, 100); + glMatrixMode(GL_MODELVIEW); } end; -end; -procedure TLyric.Draw; -var - W: integer; -begin - case StyleI of - 0: - begin - for W := 0 to High(Word) do - DrawNormal(W); - end; - 1: - begin - for W := 0 to High(Word) do - DrawPlain(W); - end; - 2: // zoom - begin - for W := 0 to High(Word) do - if not Word[W].Selected then - DrawNormal(W); - - for W := 0 to High(Word) do - if Word[W].Selected then - DrawScaled(W); - end; - 3: // slide - begin - for W := 0 to High(Word) do begin - if not Word[W].Selected then - DrawNormal(W) - else - DrawSlide(W); - end; - end; - 4: // ball - begin - for W := 0 to High(Word) do - DrawNormal(W); - - for W := 0 to High(Word) do - if Word[W].Selected then begin - Tex_Ball.X := (Word[W].X - 10) + Word[W].Done * Word[W].Width; - Tex_Ball.Y := 480 - 10*sin(Word[W].Done * pi); - Tex_Ball.W := 20; - Tex_Ball.H := 20; - DrawTexture(Tex_Ball); - end; - end; - end; // case + //Increase the Counter + Inc(LCounter); end; -procedure TLyric.DrawNormal(W: integer); -begin - SetFontStyle(Word[W].FontStyle); - SetFontPos(Word[W].X+ 10*ScreenX, Word[W].Y); - SetFontSize(Word[W].Size); - SetFontItalic(Word[W].Italic); - glColor3f(Word[W].ColR, Word[W].ColG, Word[W].ColB); - glPrint(pchar(Word[W].Text)); -end; -procedure TLyric.DrawPlain(W: integer); -var - D: real; +//--------------- +// 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 - D := Word[W].Done; // przyrost - SetFontStyle(Word[W].FontStyle); - SetFontPos(Word[W].X, Word[W].Y); - SetFontSize(Word[W].Size); - SetFontItalic(Word[W].Italic); + DrawLyrics(Beat); - if D = 0 then - glColor3f(ColR, ColG, ColB) - else - glColor3f(ColSR, ColSG, ColSB); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_Alpha {GL_ONE_MINUS_SRC_COLOR}, GL_ONE_MINUS_SRC_Alpha); + glBindTexture(GL_TEXTURE_2D, PUpperLine^.Tex); + + glColor4f(1,1,0,1); + glBegin(GL_QUADS); + glTexCoord2f(0, 1); glVertex2f(100, 100); + glTexCoord2f(0, 0); glVertex2f(100, 200); + glTexCoord2f(1, 0); glVertex2f(612, 200); + glTexCoord2f(1, 1); glVertex2f(612, 100); + glEnd; + + glBindTexture(GL_TEXTURE_2D, PLowerLine^.Tex); + + glColor4f(1,0,1,1); + glBegin(GL_QUADS); + glTexCoord2f(0, 1); glVertex2f(100, 200); + glTexCoord2f(0, 0); glVertex2f(100, 300); + glTexCoord2f(1, 0); glVertex2f(612, 300); + glTexCoord2f(1, 1); glVertex2f(612, 200); + glEnd; + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); - glPrint(pchar(Word[W].Text)); end; -procedure TLyric.DrawScaled(W: integer); -var - D: real; +//--------------- +// DrawLyrics(private) - Helper for Draw; main Drawing procedure +//--------------- +procedure TLyricEngine.DrawLyrics (Beat: Real); begin - // previous plus dynamic scaling effect - D := 1-Word[W].Done; // przyrost - SetFontStyle(Word[W].FontStyle); - SetFontPos(Word[W].X - D * Word[W].Width * (Word[W].Scale - 1) / 2 + (D+1)*10*ScreenX, Word[W].Y - D * 1.5 * Word[W].Size *(Word[W].Scale - 1)); - SetFontSize(Word[W].Size + D * (Word[W].Size * Word[W].Scale - Word[W].Size)); - SetFontItalic(Word[W].Italic); - glColor3f(Word[W].ColR, Word[W].ColG, Word[W].ColB); - glPrint(pchar(Word[W].Text)) + DrawLyricsLine(UpperLineX, UpperLineW, UpperlineY, 15, Upperline, Beat); + DrawLyricsLine(LowerLineX, LowerLineW, LowerlineY, 15, Lowerline, Beat); end; -procedure TLyric.DrawSlide(W: integer); -var - D: real; +//--------------- +// DrawPlayerIcon(private) - Helper for Draw; Draws a Playericon +//--------------- +procedure TLyricEngine.DrawPlayerIcon(const Player: Byte; const Enabled: Boolean; const X, Y, Size, Alpha: Real); +var IEnabled: Byte; begin - D := Word[W].Done; // przyrost - SetFontStyle(Word[W].FontStyle); - SetFontPos(Word[W].X, Word[W].Y); - SetFontSize(Word[W].Size); - SetFontItalic(Word[W].Italic); - glColor3f(Word[W].ColR, Word[W].ColG, Word[W].ColB); - glPrintDone(pchar(Word[W].Text), D, ColR, ColG, ColB); + Case Enabled of + True: IEnabled := 0; + False: IEnabled:= 1; + end; + + 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; - -function TLyric.SelectedLetter; // LCD +//--------------- +// DrawLyricsLine(private) - Helper for Draw; Draws one LyricLine +//--------------- +procedure TLyricEngine.DrawLyricsLine(const X, W, Y: Real; Size: Byte; const Line: TLyricLine; Beat: Real); var - W: integer; + I: Integer; + CurWord: Integer; + Progress: Real; + LyricX: Real; //Left Corner on X Axis + LyricX2: Real;//Right Corner " " + LyricScale: Real; //Up or Downscale the Lyrics need + IconSize: Real; + IconAlpha: Real; begin - Result := 1; - for W := 0 to SelectedI-1 do - Result := Result + Length(Word[W].Text); -end; +{ For I := 0 to High(Line.Words) do + begin + //Set Font Params + SetFontStyle(FontStyle); + SetFontSize(Size); + SetFontItalic(Line.Words[I].Freestyle); + glColor4f(1, 1, 1, 1); + + SetFontPos(Line.Words[I].X, Y); + + glPrint(PChar(Line.Words[I].Text)); + end; } + + LyricScale := Size / Line.Size; + + //Draw Icons + IconSize := (2 * Size); + //IconAlpha := 1; + IconAlpha := Frac(Beat/(Resolution*4)); + + {DrawPlayerIcon (0, True, X, Y, IconSize, IconAlpha); + DrawPlayerIcon (1, True, X + IconSize + 1, Y, IconSize, IconAlpha); + DrawPlayerIcon (2, True, X + (IconSize + 1)*2, Y, IconSize, IconAlpha);} + + //Check if a Word in the Sentence is active + if ((Line.Start > Beat) AND (Line.Start + Line.Length < Beat)) then + begin + //Get Start Position: + { Start of Line - Width of all Icons + LineWidth/2 (Center} + LyricX := X + (W - ((IconSize + 1) * 6))/2 + ((IconSize + 1) * 3); + + LyricX2 := LyricX + Line.Width; + + //Draw complete Sentence + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_COLOR {GL_ONE_MINUS_SRC_COLOR}, GL_ONE_MINUS_SRC_COLOR); + glBindTexture(GL_TEXTURE_2D, Line.Tex); + + glColorRGB(LineColor_en); + glBegin(GL_QUADS); + glTexCoord2f(0, 1); glVertex2f(LyricX, Y); + glTexCoord2f(0, 0); glVertex2f(LyricX, Y + 64 * W / 512); + glTexCoord2f(1, 0); glVertex2f(LyricX + LyricX2, Y + 64 * W / 512); + glTexCoord2f(1, 1); glVertex2f(LyricX + LyricX2, Y); + glEnd; + + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + end + else + begin -function TLyric.SelectedLength: integer; // LCD -begin - Result := Length(Word[SelectedI].Text); + end; + + {//Search for active Word + For I := 0 to High(Line.Words) do + if (Line.Words[I].Start < Beat) then + begin + CurWord := I - 1; + end; + + if (CurWord < 0) then Exit; + + //Draw Part until cur Word + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_COLOR {GL_ONE_MINUS_SRC_COLOR}{, GL_ONE_MINUS_SRC_COLOR); + glBindTexture(GL_TEXTURE_2D, Line.Tex); + + glColorRGB(LineColor_en); + glBegin(GL_QUADS); + glTexCoord2f(0, 1); glVertex2f(X, Y); + glTexCoord2f(0, 0); glVertex2f(X, Y + 64 * W / 512); + glTexCoord2f(Line.Words[CurWord].TexPos, 0); glVertex2f(X + W, Y + 64 * W / 512); + glTexCoord2f(Line.Words[CurWord].TexPos, 1); glVertex2f(X + W, Y); + glEnd; + + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D);} end; + end. + diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas index f06345ec..1970730a 100644 --- a/Game/Code/Classes/UMain.pas +++ b/Game/Code/Classes/UMain.pas @@ -1,792 +1,796 @@ -unit UMain; - -interface - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - -{$I switches.inc} - -uses - SDL, - UGraphic, - UMusic, - URecord, - UTime, - SysUtils, - UDisplay, - UIni, - ULog, - ULyrics, - UScreenSing, - OpenGL12, - {$IFDEF UseSerialPort} - zlportio {you can disable it and all PortWriteB calls}, - {$ENDIF} - ULCD, - ULight, - UThemes; - -type - TPlayer = record - Name: string; - - Score: real; - ScoreLine: real; - ScoreGolden: real; - - ScoreI: integer; - ScoreLineI: integer; - ScoreGoldenI: integer; - ScoreTotalI: integer; - - - - //SingBar Mod - ScoreLast: Real;//Last Line Score - ScorePercent: integer;//Aktual Fillstate of the SingBar - ScorePercentTarget: integer;//Target Fillstate of the SingBar - //end Singbar Mod - - //PhrasenBonus - Line Bonus Mod - LineBonus_PosX: Single; - LineBonus_PosY: Single; - LineBonus_Alpha: Single; - LineBonus_Visible: boolean; - LineBonus_Text: string; - LineBonus_Color: TRGB; - LineBonus_Age: Integer; - LineBonus_Rating: Integer; - //Variable vor Positioning -> Set on ScreenShow, different when Playercount Changes - LineBonus_TargetX: integer; - LineBonus_TargetY: integer; - LineBonus_StartX: integer; - LineBonus_StartY: integer; - //PhrasenBonus - Line Bonus Mod End - - //PerfectLineTwinkle Mod (effect) - LastSentencePerfect: Boolean; - //PerfectLineTwinkle Mod end - - -// Meter: real; - - HighNut: integer; - IlNut: integer; - Nuta: array of record - Start: integer; - Dlugosc: integer; - Detekt: real; // dokladne miejsce, w ktorym wykryto ta nute - Ton: real; - Perfect: boolean; // true if the note matches the original one, lit the star - - - - // Half size Notes Patch - Hit: boolean; // true if the note Hits the Line - //end Half size Notes Patch - - - - end; - end; - - -var - //Absolute Paths - GamePath: string; - SoundPath: string; - SongPath: string; - LogPath: string; - ThemePath: string; - ScreenshotsPath: string; - CoversPath: string; - LanguagesPath: string; - PluginPath: string; - PlayListPath: string; - - OGL: Boolean; - Done: Boolean; - Event: TSDL_event; - FileName: string; - Restart: boolean; - - // gracz i jego nuty - Player: array of TPlayer; - PlayersPlay: integer; - -procedure InitializePaths; - -procedure MainLoop; -procedure CheckEvents; -procedure Sing(Sender: TScreenSing); -procedure NewSentence(Sender: TScreenSing); -procedure NewBeat(Sender: TScreenSing); // executed when on then new beat -procedure NewBeatC(Sender: TScreenSing); // executed when on then new beat for click -procedure NewBeatD(Sender: TScreenSing); // executed when on then new beat for detection -//procedure NewHalf; // executed when in the half between beats -procedure NewNote(Sender: TScreenSing); // detect note -function GetMidBeat(Time: real): real; -function GetTimeFromBeat(Beat: integer): real; -procedure ClearScores(PlayerNum: integer); - -implementation -uses USongs, UJoystick, math, UCommandLine; - -procedure MainLoop; -var - Delay: integer; -begin - SDL_EnableKeyRepeat(125, 125); - While not Done do - Begin - // joypad - if (Ini.Joypad = 1) OR (Params.Joypad) then - Joy.Update; - - // keyboard events - CheckEvents; - - // display - done := not Display.Draw; - SwapBuffers; - - // light - Light.Refresh; - - // delay - CountMidTime; -// if 1000*TimeMid > 100 then beep; - Delay := Floor(1000 / 100 - 1000 * TimeMid); - if Delay >= 1 then - SDL_Delay(Delay); // dynamic, maximum is 100 fps - CountSkipTime; - - // reinitialization of graphics - if Restart then begin - Reinitialize3D; - Restart := false; - end; - - End; - UnloadOpenGL; -End; - -Procedure CheckEvents; -//var -// p: pointer; -Begin - if not Assigned(Display.NextScreen) then - While SDL_PollEvent( @event ) = 1 Do - Begin -// beep; - Case Event.type_ Of - SDL_QUITEV: begin - Display.Fade := 0; - Display.NextScreenWithCheck := nil; - Display.CheckOK := True; - end; -{ SDL_MOUSEBUTTONDOWN: - With Event.button Do - Begin - If State = SDL_BUTTON_LEFT Then - Begin - // - End; - End; // With} - SDL_KEYDOWN: - begin - //ScreenShot hack. If Print is pressed-> Make screenshot and Save to Screenshots Path - if (Event.key.keysym.sym = SDLK_SYSREQ) then - Display.ScreenShot - - // popup hack... if there is a visible popup then let it handle input instead of underlying screen - // shoud be done in a way to be sure the topmost popup has preference (maybe error, then check) - else if (ScreenPopupError <> NIL) and (ScreenPopupError.Visible) then - done := not ScreenPopupError.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True) - else if (ScreenPopupCheck <> NIL) AND (ScreenPopupCheck.Visible) then - done := not ScreenPopupCheck.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True) - // end of popup hack - - else - begin - // check for Screen want to Exit - done := Not Display.ActualScreen^.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True); - - //If Screen wants to Exit - if done then - begin - //If Question Option is enabled then Show Exit Popup - if (Ini.AskbeforeDel = 1) then - begin - Display.ActualScreen^.CheckFadeTo(NIL,'MSG_QUIT_USDX'); - end - else //When asking for exit is disabled then simply exit - begin - Display.Fade := 0; - Display.NextScreenWithCheck := nil; - Display.CheckOK := True; - end; - end; - - end; // if (Not Display.ActualScreen^.ParseInput(Event.key.keysym.scancode, True)) then - end; -// SDL_JOYAXISMOTION: -// begin -// beep -// end; - SDL_JOYBUTTONDOWN: - begin - beep - end; - End; // Case Event.type_ - End; // While -End; // CheckEvents - -function GetTimeForBeats(BPM, Beats: real): real; -begin - Result := 60 / BPM * Beats; -end; - -function GetBeats(BPM, msTime: real): real; -begin - Result := BPM * msTime / 60; -end; - -procedure GetMidBeatSub(BPMNum: integer; var Time: real; var CurBeat: real); -var - NewTime: real; -begin - if High(AktSong.BPM) = BPMNum then begin - // last BPM - CurBeat := AktSong.BPM[BPMNum].StartBeat + GetBeats(AktSong.BPM[BPMNum].BPM, Time); - Time := 0; - end else begin - // not last BPM - // count how much time is it for start of the new BPM and store it in NewTime - NewTime := GetTimeForBeats(AktSong.BPM[BPMNum].BPM, AktSong.BPM[BPMNum+1].StartBeat - AktSong.BPM[BPMNum].StartBeat); - - // compare it to remaining time - if (Time - NewTime) > 0 then begin - // there is still remaining time - CurBeat := AktSong.BPM[BPMNum].StartBeat; - Time := Time - NewTime; - end else begin - // there is no remaining time - CurBeat := AktSong.BPM[BPMNum].StartBeat + GetBeats(AktSong.BPM[BPMNum].BPM, Time); - Time := 0; - end; // if - end; // if -end; - -function GetMidBeat(Time: real): real; -var - CurBeat: real; - CurBPM: integer; -// TopBeat: real; -// TempBeat: real; -// TempTime: real; -begin - Result := 0; - if Length(AktSong.BPM) = 1 then Result := Time * AktSong.BPM[0].BPM / 60; - - (* 2 BPMs *) -{ if Length(AktSong.BPM) > 1 then begin - (* new system *) - CurBeat := 0; - TopBeat := GetBeats(AktSong.BPM[0].BPM, Time); - if TopBeat > AktSong.BPM[1].StartBeat then begin - // analyze second BPM - Time := Time - GetTimeForBeats(AktSong.BPM[0].BPM, AktSong.BPM[1].StartBeat - CurBeat); - CurBeat := AktSong.BPM[1].StartBeat; - TopBeat := GetBeats(AktSong.BPM[1].BPM, Time); - Result := CurBeat + TopBeat; - - end else begin - (* pierwszy przedzial *) - Result := TopBeat; - end; - end; // if} - - (* more BPMs *) - if Length(AktSong.BPM) > 1 then begin - - CurBeat := 0; - CurBPM := 0; - while (Time > 0) do begin - GetMidBeatSub(CurBPM, Time, CurBeat); - Inc(CurBPM); - end; - - Result := CurBeat; - end; // if -end; - -function GetTimeFromBeat(Beat: integer): real; -var - CurBPM: integer; -begin - Result := 0; - if Length(AktSong.BPM) = 1 then Result := AktSong.GAP / 1000 + Beat * 60 / AktSong.BPM[0].BPM; - - (* more BPMs *) - if Length(AktSong.BPM) > 1 then begin - Result := AktSong.GAP / 1000; - CurBPM := 0; - while (CurBPM <= High(AktSong.BPM)) and (Beat > AktSong.BPM[CurBPM].StartBeat) do begin - if (CurBPM < High(AktSong.BPM)) and (Beat >= AktSong.BPM[CurBPM+1].StartBeat) then begin - // full range - Result := Result + (60 / AktSong.BPM[CurBPM].BPM) * (AktSong.BPM[CurBPM+1].StartBeat - AktSong.BPM[CurBPM].StartBeat); - end; - - if (CurBPM = High(AktSong.BPM)) or (Beat < AktSong.BPM[CurBPM+1].StartBeat) then begin - // in the middle - Result := Result + (60 / AktSong.BPM[CurBPM].BPM) * (Beat - AktSong.BPM[CurBPM].StartBeat); - end; - Inc(CurBPM); - end; - -{ while (Time > 0) do begin - GetMidBeatSub(CurBPM, Time, CurBeat); - Inc(CurBPM); - end;} - end; // if} -end; - -procedure Sing(Sender: TScreenSing); -var - Pet: integer; - PetGr: integer; - CP: integer; - Done: real; - N: integer; -begin - Czas.Teraz := Czas.Teraz + TimeSkip; - - Czas.OldBeat := Czas.AktBeat; - Czas.MidBeat := GetMidBeat(Czas.Teraz - (AktSong.Gap{ + 90 I've forgotten for what it is}) / 1000); // new system with variable BPM in function - Czas.AktBeat := Floor(Czas.MidBeat); - -// Czas.OldHalf := Czas.AktHalf; -// Czas.MidHalf := Czas.MidBeat + 0.5; -// Czas.AktHalf := Floor(Czas.MidHalf); - - Czas.OldBeatC := Czas.AktBeatC; - Czas.MidBeatC := GetMidBeat(Czas.Teraz - (AktSong.Gap) / 1000); - Czas.AktBeatC := Floor(Czas.MidBeatC); - - Czas.OldBeatD := Czas.AktBeatD; - Czas.MidBeatD := -0.5+GetMidBeat(Czas.Teraz - (AktSong.Gap + 120 + 20) / 1000); // MidBeat with addition GAP - Czas.AktBeatD := Floor(Czas.MidBeatD); - Czas.FracBeatD := Frac(Czas.MidBeatD); - - // sentences routines - for PetGr := 0 to 0 do begin;//High(Gracz) do begin - CP := PetGr; - // ustawianie starej czesci - Czas.OldCzesc := Czesci[CP].Akt; - - // wybieranie aktualnej czesci - for Pet := 0 to Czesci[CP].High do - if Czas.AktBeat >= Czesci[CP].Czesc[Pet].Start then Czesci[CP].Akt := Pet; - - // czysczenie nut gracza, gdy to jest nowa plansza - // (optymizacja raz na halfbeat jest zla) - if Czesci[CP].Akt <> Czas.OldCzesc then NewSentence(Sender); - - end; // for PetGr - - // wykonuje operacje raz na beat - if (Czas.AktBeat >= 0) and (Czas.OldBeat <> Czas.AktBeat) then - NewBeat(Sender); - - // make some operations on clicks - if {(Czas.AktBeatC >= 0) and }(Czas.OldBeatC <> Czas.AktBeatC) then - NewBeatC(Sender); - - // make some operations when detecting new voice pitch - if (Czas.AktBeatD >= 0) and (Czas.OldBeatD <> Czas.AktBeatD) then - NewBeatD(Sender); - - // wykonuje operacje w polowie beatu -// if (Czas.AktHalf >= 1) and (Czas.OldHalf <> Czas.AktHalf) then -// NewHalf; - - // plynnie przesuwa text - Done := 1; - for N := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do - if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start <= Czas.MidBeat) - and (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start + Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc >= Czas.MidBeat) then - Done := (Czas.MidBeat - Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start) / (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc); - - N := Czesci[0].Czesc[Czesci[0].Akt].HighNut; - - // wylacza ostatnia nute po przejsciu - if (Ini.LyricsEffect = 1) and (Done = 1) and - (Czas.MidBeat > Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start + Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc) - then Sender.LyricMain.Selected := -1; - - if Done > 1 then Done := 1; - Sender.LyricMain.Done := Done; - - // use Done with LCD -{ with ScreenSing do begin - if LyricMain.Selected >= 0 then begin - LCD.MoveCursor(1, LyricMain.SelectedLetter + Round((LyricMain.SelectedLength-1) * Done)); - LCD.ShowCursor; - end; - end;} - - -end; - -procedure NewSentence(Sender: TScreenSing); -var -G: Integer; -begin - // czyszczenie nut graczy - for G := 0 to High(Player) do begin - Player[G].IlNut := 0; - Player[G].HighNut := -1; - SetLength(Player[G].Nuta, 0); - end; - - // wstawianie tekstow - with Sender do begin - LyricMain.AddCzesc(Czesci[0].Akt); - if Czesci[0].Akt < Czesci[0].High then - LyricSub.AddCzesc(Czesci[0].Akt+1) - else - LyricSub.Clear; - end; - - Sender.UpdateLCD; - - //On Sentence Change... - Sender.onSentenceChange(Czesci[0].Akt); -end; - -procedure NewBeat(Sender: TScreenSing); -var - Pet: integer; -// TempBeat: integer; -begin - // ustawia zaznaczenie tekstu -// SingScreen.LyricMain.Selected := -1; - for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do - if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeat) then begin - // operates on currently beated note - Sender.LyricMain.Selected := Pet; - -// LCD.MoveCursor(1, ScreenSing.LyricMain.SelectedLetter); -// LCD.ShowCursor; - - LCD.MoveCursorBR(Sender.LyricMain.SelectedLetter); - LCD.ShowCursor; - - end; -end; - -procedure NewBeatC; -var - Pet: integer; -// LPT_1: integer; -// LPT_2: integer; -begin -// LPT_1 := 1; -// LPT_2 := 1; - - // beat click - if (Ini.BeatClick = 1) and ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod Czesci[0].Resolution = 0) then - Music.PlayClick; - - // debug system on LPT - if ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod Czesci[0].Resolution = 0) then begin - //LPT_1 := 0; -// Light.LightOne(0, 150); - - Light.LightOne(1, 200); // beat light - if ParamStr(1) = '-doublelights' then - Light.LightOne(0, 200); // beat light - - -{ if ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod (Czesci[0].Resolution * 2) = 0) then - Light.LightOne(0, 150) - else - Light.LightOne(1, 150)} - end; - - for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do - if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeatC) then begin - // click assist - if Ini.ClickAssist = 1 then - Music.PlayClick; - - //LPT_2 := 0; - if ParamStr(1) <> '-doublelights' then - Light.LightOne(0, 150); //125 - - - // drum machine -(* TempBeat := Czas.AktBeat;// + 2; - if (TempBeat mod 8 = 0) then Music.PlayDrum; - if (TempBeat mod 8 = 4) then Music.PlayClap; -// if (TempBeat mod 4 = 2) then Music.PlayHihat; - if (TempBeat mod 4 <> 0) then Music.PlayHihat;*) - end; - - {$IFDEF UseSerialPort} - // PortWriteB($378, LPT_1 + LPT_2 * 2); // 0 zapala - {$ENDIF} -end; - -procedure NewBeatD(Sender: TScreenSing); -begin - NewNote(Sender); -end; - -//procedure NewHalf; -//begin -// NewNote; -//end; - -procedure NewNote(Sender: TScreenSing); -var - CP: integer; // current player - S: integer; // sentence - SMin: integer; - SMax: integer; - SDet: integer; // temporary: sentence of detected note - Pet: integer; - Mozna: boolean; - Nowa: boolean; - Range: integer; - NoteHit:boolean; -begin -// Log.LogStatus('Beat ' + IntToStr(Czas.AktBeat) + ' HalfBeat ' + IntToStr(Czas.AktHalf), 'NewBeat'); -// beep; - - // analizuje dla obu graczy ten sam sygnal (Sound.OneSrcForBoth) - // albo juz lepiej nie - for CP := 0 to PlayersPlay-1 do begin - - // analyze buffer - Sound[CP].AnalizujBufor; - - // adds some noise -// Czas.Ton := Czas.Ton + Round(Random(3)) - 1; - - // 0.5.0: count min and max sentence range for checking (detection is delayed to the notes we see on the screen) - SMin := Czesci[0].Akt-1; - if SMin < 0 then SMin := 0; - SMax := Czesci[0].Akt; - - // check if we can add new note - Mozna := false; - SDet:=SMin; - for S := SMin to SMax do - for Pet := 0 to Czesci[0].Czesc[S].HighNut do - if ((Czesci[0].Czesc[S].Nuta[Pet].Start <= Czas.AktBeatD) - and (Czesci[0].Czesc[S].Nuta[Pet].Start + Czesci[0].Czesc[S].Nuta[Pet].Dlugosc - 1 >= Czas.AktBeatD)) - and (not Czesci[0].Czesc[S].Nuta[Pet].FreeStyle) // but don't allow when it's FreeStyle note - and (Czesci[0].Czesc[S].Nuta[Pet].Dlugosc > 0) // and make sure the note lenghts is at least 1 - then begin - SDet := S; - Mozna := true; - Break; - end; - - S := SDet; - - - - - -// Czas.SzczytJest := true; -// Czas.Ton := 27; - - // gdy moze, to dodaje nute - if (Sound[CP].SzczytJest) and (Mozna) then begin - // operowanie na ostatniej nucie - for Pet := 0 to Czesci[0].Czesc[S].HighNut do - if (Czesci[0].Czesc[S].Nuta[Pet].Start <= Czas.OldBeatD+1) - and (Czesci[0].Czesc[S].Nuta[Pet].Start + - Czesci[0].Czesc[S].Nuta[Pet].Dlugosc > Czas.OldBeatD+1) then begin - // to robi, tylko dla pary nut (oryginalnej i gracza) - - // przesuwanie tonu w odpowiednia game - while (Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton > 6) do - Sound[CP].Ton := Sound[CP].Ton - 12; - while (Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton < -6) do - Sound[CP].Ton := Sound[CP].Ton + 12; - - // Half size Notes Patch - NoteHit := false; - - //if Ini.Difficulty = 0 then Range := 2; - //if Ini.Difficulty = 1 then Range := 1; - //if Ini.Difficulty = 2 then Range := 0; - Range := 2 - Ini.Difficulty; - if abs(Czesci[0].Czesc[S].Nuta[Pet].Ton - Sound[CP].Ton) <= Range then begin - Sound[CP].Ton := Czesci[0].Czesc[S].Nuta[Pet].Ton; - - - // Half size Notes Patch - NoteHit := true; - - - if (Ini.LineBonus = 0) then - begin - // add points without LineBonus - case Czesci[0].Czesc[S].Nuta[Pet].Wartosc of - 1: Player[CP].Score := Player[CP].Score + 10000 / Czesci[0].Wartosc * - Czesci[0].Czesc[S].Nuta[Pet].Wartosc; - 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 10000 / Czesci[0].Wartosc * - Czesci[0].Czesc[S].Nuta[Pet].Wartosc; - end; - end - else - begin - // add points with Line Bonus - case Czesci[0].Czesc[S].Nuta[Pet].Wartosc of - 1: Player[CP].Score := Player[CP].Score + 9000 / Czesci[0].Wartosc * - Czesci[0].Czesc[S].Nuta[Pet].Wartosc; - 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 9000 / Czesci[0].Wartosc * - Czesci[0].Czesc[S].Nuta[Pet].Wartosc; - end; - end; - - Player[CP].ScoreI := Floor(Player[CP].Score / 10) * 10; - Player[CP].ScoreGoldenI := Floor(Player[CP].ScoreGolden / 10) * 10; - - Player[CP].ScoreTotalI := Player[CP].ScoreI + Player[CP].ScoreGoldenI + Player[CP].ScoreLineI; - end; - - end; // operowanie - - // sprawdzanie czy to nowa nuta, czy przedluzenie - if S = SMax then begin - Nowa := true; - // jezeli ostatnia ma ten sam ton - if (Player[CP].IlNut > 0 ) and (Player[CP].Nuta[Player[CP].HighNut].Ton = Sound[CP].Ton) - and (Player[CP].Nuta[Player[CP].HighNut].Start + Player[CP].Nuta[Player[CP].HighNut].Dlugosc = Czas.AktBeatD) - then Nowa := false; - // jezeli jest jakas nowa nuta na sprawdzanym beacie - for Pet := 0 to Czesci[0].Czesc[S].HighNut do - if (Czesci[0].Czesc[S].Nuta[Pet].Start = Czas.AktBeatD) then - Nowa := true; - - // dodawanie nowej nuty - if Nowa then begin - // nowa nuta - Player[CP].IlNut := Player[CP].IlNut + 1; - Player[CP].HighNut := Player[CP].HighNut + 1; - SetLength(Player[CP].Nuta, Player[CP].IlNut); - Player[CP].Nuta[Player[CP].HighNut].Start := Czas.AktBeatD; - Player[CP].Nuta[Player[CP].HighNut].Dlugosc := 1; - Player[CP].Nuta[Player[CP].HighNut].Ton := Sound[CP].Ton; // Ton || TonDokl - Player[CP].Nuta[Player[CP].HighNut].Detekt := Czas.MidBeat; - - - // Half Note Patch - Player[CP].Nuta[Player[CP].HighNut].Hit := NoteHit; - - - // Log.LogStatus('Nowa Nuta ' + IntToStr(Gracz.Nuta[Gracz.HighNut].Start), 'NewBeat'); - - end else begin - // przedluzenie nuty - Player[CP].Nuta[Player[CP].HighNut].Dlugosc := Player[CP].Nuta[Player[CP].HighNut].Dlugosc + 1; - end; - - - // check for perfect note and then lit the star (on Draw) - for Pet := 0 to Czesci[0].Czesc[S].HighNut do - if (Czesci[0].Czesc[S].Nuta[Pet].Start = Player[CP].Nuta[Player[CP].HighNut].Start) - and (Czesci[0].Czesc[S].Nuta[Pet].Dlugosc = Player[CP].Nuta[Player[CP].HighNut].Dlugosc) - and (Czesci[0].Czesc[S].Nuta[Pet].Ton = Player[CP].Nuta[Player[CP].HighNut].Ton) then begin - Player[CP].Nuta[Player[CP].HighNut].Perfect := true; - end; - - end;// else beep; // if S = SMax - - end; // if moze - end; // for CP -// Log.LogStatus('EndBeat', 'NewBeat'); - -//On Sentence End -> For LineBonus + SingBar -if (sDet >= low(Czesci[0].Czesc)) AND (sDet <= high(Czesci[0].Czesc)) then -if ((Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Start + Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Dlugosc - 1) = Czas.AktBeatD) then - Sender.onSentenceEnd(sDet); - -end; - -procedure ClearScores(PlayerNum: integer); -begin - Player[PlayerNum].Score := 0; - Player[PlayerNum].ScoreI := 0; - Player[PlayerNum].ScoreLine := 0; - Player[PlayerNum].ScoreLineI := 0; - Player[PlayerNum].ScoreGolden := 0; - Player[PlayerNum].ScoreGoldenI := 0; - Player[PlayerNum].ScoreTotalI := 0; - - - //SingBar Mod - Player[PlayerNum].ScoreLast := 0; - Player[PlayerNum].ScorePercent := 50;// Sets to 50% when song starts - Player[PlayerNum].ScorePercentTarget := 50;// Sets to 50% when song starts - //end SingBar Mod - - //PhrasenBonus - Line Bonus Mod - Player[PlayerNum].LineBonus_Visible := False; //Hide Line Bonus - Player[PlayerNum].LineBonus_Alpha := 0; - Player[PlayerNum].LineBonus_TargetX := 70 + PlayerNum*500; - Player[PlayerNum].LineBonus_TargetY := 30; - //PhrasenBonus - Line Bonus Mod End -end; - -//-------------------- -// Function sets all Absolute Paths e.g. Song Path and makes sure the Directorys exist -//-------------------- -procedure InitializePaths; - - // Initialize a Path Variable - // After Setting Paths, make sure that Paths exist - function initialize_path( out aPathVar : String; const aLocation : String ): boolean; - var - lWriteable: Boolean; - begin - aPathVar := aLocation; - - If DirectoryExists(aPathVar) then - lWriteable := ForceDirectories(aPathVar) - else - lWriteable := false; - - if not lWriteable then - Log.LogError('Error: Dir ('+ aLocation +') is Readonly'); - - result := lWriteable; - end; - -begin - - GamePath := ExtractFilePath(ParamStr(0)); - - initialize_path( LogPath , GamePath ); - initialize_path( SoundPath , GamePath + 'Sounds' + PathDelim ); - initialize_path( SongPath , GamePath + 'Songs' + PathDelim ); - initialize_path( ThemePath , GamePath + 'Themes' + PathDelim ); - initialize_path( ScreenshotsPath , GamePath + 'Screenshots' + PathDelim ); - initialize_path( CoversPath , GamePath + 'Covers' + PathDelim ); - initialize_path( LanguagesPath , GamePath + 'Languages' + PathDelim ); - initialize_path( PluginPath , GamePath + 'Plugins' + PathDelim ); - initialize_path( PlaylistPath , GamePath + 'Playlists' + PathDelim ); - - DecimalSeparator := ','; -end; - -end. - +unit UMain; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses + SDL, + UGraphic, + UMusic, + URecord, + UTime, + SysUtils, + UDisplay, + UIni, + ULog, + ULyrics, + UScreenSing, + OpenGL12, + {$IFDEF UseSerialPort} + zlportio {you can disable it and all PortWriteB calls}, + {$ENDIF} + ULCD, + ULight, + UThemes; + +type + TPlayer = record + Name: string; + + Score: real; + ScoreLine: real; + ScoreGolden: real; + + ScoreI: integer; + ScoreLineI: integer; + ScoreGoldenI: integer; + ScoreTotalI: integer; + + + + //SingBar Mod + ScoreLast: Real;//Last Line Score + ScorePercent: integer;//Aktual Fillstate of the SingBar + ScorePercentTarget: integer;//Target Fillstate of the SingBar + //end Singbar Mod + + //PhrasenBonus - Line Bonus Mod + LineBonus_PosX: Single; + LineBonus_PosY: Single; + LineBonus_Alpha: Single; + LineBonus_Visible: boolean; + LineBonus_Text: string; + LineBonus_Color: TRGB; + LineBonus_Age: Integer; + LineBonus_Rating: Integer; + //Variable vor Positioning -> Set on ScreenShow, different when Playercount Changes + LineBonus_TargetX: integer; + LineBonus_TargetY: integer; + LineBonus_StartX: integer; + LineBonus_StartY: integer; + //PhrasenBonus - Line Bonus Mod End + + //PerfectLineTwinkle Mod (effect) + LastSentencePerfect: Boolean; + //PerfectLineTwinkle Mod end + + +// Meter: real; + + HighNut: integer; + IlNut: integer; + Nuta: array of record + Start: integer; + Dlugosc: integer; + Detekt: real; // dokladne miejsce, w ktorym wykryto ta nute + Ton: real; + Perfect: boolean; // true if the note matches the original one, lit the star + + + + // Half size Notes Patch + Hit: boolean; // true if the note Hits the Line + //end Half size Notes Patch + + + + end; + end; + + +var + //Absolute Paths + GamePath: string; + SoundPath: string; + SongPath: string; + LogPath: string; + ThemePath: string; + ScreenshotsPath: string; + CoversPath: string; + LanguagesPath: string; + PluginPath: string; + PlayListPath: string; + + OGL: Boolean; + Done: Boolean; + Event: TSDL_event; + FileName: string; + Restart: boolean; + + // gracz i jego nuty + Player: array of TPlayer; + PlayersPlay: integer; + +procedure InitializePaths; + +procedure MainLoop; +procedure CheckEvents; +procedure Sing(Sender: TScreenSing); +procedure NewSentence(Sender: TScreenSing); +procedure NewBeat(Sender: TScreenSing); // executed when on then new beat +procedure NewBeatC(Sender: TScreenSing); // executed when on then new beat for click +procedure NewBeatD(Sender: TScreenSing); // executed when on then new beat for detection +//procedure NewHalf; // executed when in the half between beats +procedure NewNote(Sender: TScreenSing); // detect note +function GetMidBeat(Time: real): real; +function GetTimeFromBeat(Beat: integer): real; +procedure ClearScores(PlayerNum: integer); + +implementation +uses USongs, UJoystick, math, UCommandLine; + +procedure MainLoop; +var + Delay: integer; +begin + SDL_EnableKeyRepeat(125, 125); + While not Done do + Begin + // joypad + if (Ini.Joypad = 1) OR (Params.Joypad) then + Joy.Update; + + // keyboard events + CheckEvents; + + // display + done := not Display.Draw; + SwapBuffers; + + // light + Light.Refresh; + + // delay + CountMidTime; +// if 1000*TimeMid > 100 then beep; + Delay := Floor(1000 / 100 - 1000 * TimeMid); + if Delay >= 1 then + SDL_Delay(Delay); // dynamic, maximum is 100 fps + CountSkipTime; + + // reinitialization of graphics + if Restart then begin + Reinitialize3D; + Restart := false; + end; + + End; + UnloadOpenGL; +End; + +Procedure CheckEvents; +//var +// p: pointer; +Begin + if not Assigned(Display.NextScreen) then + While SDL_PollEvent( @event ) = 1 Do + Begin +// beep; + Case Event.type_ Of + SDL_QUITEV: begin + Display.Fade := 0; + Display.NextScreenWithCheck := nil; + Display.CheckOK := True; + end; +{ SDL_MOUSEBUTTONDOWN: + With Event.button Do + Begin + If State = SDL_BUTTON_LEFT Then + Begin + // + End; + End; // With} + SDL_KEYDOWN: + begin + //ScreenShot hack. If Print is pressed-> Make screenshot and Save to Screenshots Path + if (Event.key.keysym.sym = SDLK_SYSREQ) then + Display.ScreenShot + + // popup hack... if there is a visible popup then let it handle input instead of underlying screen + // shoud be done in a way to be sure the topmost popup has preference (maybe error, then check) + else if (ScreenPopupError <> NIL) and (ScreenPopupError.Visible) then + done := not ScreenPopupError.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True) + else if (ScreenPopupCheck <> NIL) AND (ScreenPopupCheck.Visible) then + done := not ScreenPopupCheck.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True) + // end of popup hack + + else + begin + // check for Screen want to Exit + done := Not Display.ActualScreen^.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True); + + //If Screen wants to Exit + if done then + begin + //If Question Option is enabled then Show Exit Popup + if (Ini.AskbeforeDel = 1) then + begin + Display.ActualScreen^.CheckFadeTo(NIL,'MSG_QUIT_USDX'); + end + else //When asking for exit is disabled then simply exit + begin + Display.Fade := 0; + Display.NextScreenWithCheck := nil; + Display.CheckOK := True; + end; + end; + + end; // if (Not Display.ActualScreen^.ParseInput(Event.key.keysym.scancode, True)) then + end; +// SDL_JOYAXISMOTION: +// begin +// beep +// end; + SDL_JOYBUTTONDOWN: + begin + beep + end; + End; // Case Event.type_ + End; // While +End; // CheckEvents + +function GetTimeForBeats(BPM, Beats: real): real; +begin + Result := 60 / BPM * Beats; +end; + +function GetBeats(BPM, msTime: real): real; +begin + Result := BPM * msTime / 60; +end; + +procedure GetMidBeatSub(BPMNum: integer; var Time: real; var CurBeat: real); +var + NewTime: real; +begin + if High(AktSong.BPM) = BPMNum then begin + // last BPM + CurBeat := AktSong.BPM[BPMNum].StartBeat + GetBeats(AktSong.BPM[BPMNum].BPM, Time); + Time := 0; + end else begin + // not last BPM + // count how much time is it for start of the new BPM and store it in NewTime + NewTime := GetTimeForBeats(AktSong.BPM[BPMNum].BPM, AktSong.BPM[BPMNum+1].StartBeat - AktSong.BPM[BPMNum].StartBeat); + + // compare it to remaining time + if (Time - NewTime) > 0 then begin + // there is still remaining time + CurBeat := AktSong.BPM[BPMNum].StartBeat; + Time := Time - NewTime; + end else begin + // there is no remaining time + CurBeat := AktSong.BPM[BPMNum].StartBeat + GetBeats(AktSong.BPM[BPMNum].BPM, Time); + Time := 0; + end; // if + end; // if +end; + +function GetMidBeat(Time: real): real; +var + CurBeat: real; + CurBPM: integer; +// TopBeat: real; +// TempBeat: real; +// TempTime: real; +begin + Result := 0; + if Length(AktSong.BPM) = 1 then Result := Time * AktSong.BPM[0].BPM / 60; + + (* 2 BPMs *) +{ if Length(AktSong.BPM) > 1 then begin + (* new system *) + CurBeat := 0; + TopBeat := GetBeats(AktSong.BPM[0].BPM, Time); + if TopBeat > AktSong.BPM[1].StartBeat then begin + // analyze second BPM + Time := Time - GetTimeForBeats(AktSong.BPM[0].BPM, AktSong.BPM[1].StartBeat - CurBeat); + CurBeat := AktSong.BPM[1].StartBeat; + TopBeat := GetBeats(AktSong.BPM[1].BPM, Time); + Result := CurBeat + TopBeat; + + end else begin + (* pierwszy przedzial *) + Result := TopBeat; + end; + end; // if} + + (* more BPMs *) + if Length(AktSong.BPM) > 1 then begin + + CurBeat := 0; + CurBPM := 0; + while (Time > 0) do begin + GetMidBeatSub(CurBPM, Time, CurBeat); + Inc(CurBPM); + end; + + Result := CurBeat; + end; // if +end; + +function GetTimeFromBeat(Beat: integer): real; +var + CurBPM: integer; +begin + Result := 0; + if Length(AktSong.BPM) = 1 then Result := AktSong.GAP / 1000 + Beat * 60 / AktSong.BPM[0].BPM; + + (* more BPMs *) + if Length(AktSong.BPM) > 1 then begin + Result := AktSong.GAP / 1000; + CurBPM := 0; + while (CurBPM <= High(AktSong.BPM)) and (Beat > AktSong.BPM[CurBPM].StartBeat) do begin + if (CurBPM < High(AktSong.BPM)) and (Beat >= AktSong.BPM[CurBPM+1].StartBeat) then begin + // full range + Result := Result + (60 / AktSong.BPM[CurBPM].BPM) * (AktSong.BPM[CurBPM+1].StartBeat - AktSong.BPM[CurBPM].StartBeat); + end; + + if (CurBPM = High(AktSong.BPM)) or (Beat < AktSong.BPM[CurBPM+1].StartBeat) then begin + // in the middle + Result := Result + (60 / AktSong.BPM[CurBPM].BPM) * (Beat - AktSong.BPM[CurBPM].StartBeat); + end; + Inc(CurBPM); + end; + +{ while (Time > 0) do begin + GetMidBeatSub(CurBPM, Time, CurBeat); + Inc(CurBPM); + end;} + end; // if} +end; + +procedure Sing(Sender: TScreenSing); +var + Pet: integer; + PetGr: integer; + CP: integer; + Done: real; + N: integer; +begin + Czas.Teraz := Czas.Teraz + TimeSkip; + + Czas.OldBeat := Czas.AktBeat; + Czas.MidBeat := GetMidBeat(Czas.Teraz - (AktSong.Gap{ + 90 I've forgotten for what it is}) / 1000); // new system with variable BPM in function + Czas.AktBeat := Floor(Czas.MidBeat); + +// Czas.OldHalf := Czas.AktHalf; +// Czas.MidHalf := Czas.MidBeat + 0.5; +// Czas.AktHalf := Floor(Czas.MidHalf); + + Czas.OldBeatC := Czas.AktBeatC; + Czas.MidBeatC := GetMidBeat(Czas.Teraz - (AktSong.Gap) / 1000); + Czas.AktBeatC := Floor(Czas.MidBeatC); + + Czas.OldBeatD := Czas.AktBeatD; + Czas.MidBeatD := -0.5+GetMidBeat(Czas.Teraz - (AktSong.Gap + 120 + 20) / 1000); // MidBeat with addition GAP + Czas.AktBeatD := Floor(Czas.MidBeatD); + Czas.FracBeatD := Frac(Czas.MidBeatD); + + // sentences routines + for PetGr := 0 to 0 do begin;//High(Gracz) do begin + CP := PetGr; + // ustawianie starej czesci + Czas.OldCzesc := Czesci[CP].Akt; + + // wybieranie aktualnej czesci + for Pet := 0 to Czesci[CP].High do + if Czas.AktBeat >= Czesci[CP].Czesc[Pet].Start then Czesci[CP].Akt := Pet; + + // czysczenie nut gracza, gdy to jest nowa plansza + // (optymizacja raz na halfbeat jest zla) + if Czesci[CP].Akt <> Czas.OldCzesc then NewSentence(Sender); + + end; // for PetGr + + // wykonuje operacje raz na beat + if (Czas.AktBeat >= 0) and (Czas.OldBeat <> Czas.AktBeat) then + NewBeat(Sender); + + // make some operations on clicks + if {(Czas.AktBeatC >= 0) and }(Czas.OldBeatC <> Czas.AktBeatC) then + NewBeatC(Sender); + + // make some operations when detecting new voice pitch + if (Czas.AktBeatD >= 0) and (Czas.OldBeatD <> Czas.AktBeatD) then + NewBeatD(Sender); + + // wykonuje operacje w polowie beatu +// if (Czas.AktHalf >= 1) and (Czas.OldHalf <> Czas.AktHalf) then +// NewHalf; + + // plynnie przesuwa text + Done := 1; + for N := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do + if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start <= Czas.MidBeat) + and (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start + Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc >= Czas.MidBeat) then + Done := (Czas.MidBeat - Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start) / (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc); + + N := Czesci[0].Czesc[Czesci[0].Akt].HighNut; + + // wylacza ostatnia nute po przejsciu + {// todo: Lyrics + if (Ini.LyricsEffect = 1) and (Done = 1) and + (Czas.MidBeat > Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start + Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc) + then Sender.LyricMain.Selected := -1; + + if Done > 1 then Done := 1; + Sender.LyricMain.Done := Done; } + + // use Done with LCD +{ with ScreenSing do begin + if LyricMain.Selected >= 0 then begin + LCD.MoveCursor(1, LyricMain.SelectedLetter + Round((LyricMain.SelectedLength-1) * Done)); + LCD.ShowCursor; + end; + end;} + + +end; + +procedure NewSentence(Sender: TScreenSing); +var +G: Integer; +begin + // czyszczenie nut graczy + for G := 0 to High(Player) do begin + Player[G].IlNut := 0; + Player[G].HighNut := -1; + SetLength(Player[G].Nuta, 0); + end; + + // Add Words to Lyrics + with Sender do begin + {LyricMain.AddCzesc(Czesci[0].Akt); + if Czesci[0].Akt < Czesci[0].High then + LyricSub.AddCzesc(Czesci[0].Akt+1) + else + LyricSub.Clear;} + while (not Lyrics.LineinQueue) AND (Lyrics.LineCounter <= High(Czesci[0].Czesc)) do + Lyrics.AddLine(@Czesci[0].Czesc[Lyrics.LineCounter]); + end; + + Sender.UpdateLCD; + + //On Sentence Change... + Sender.onSentenceChange(Czesci[0].Akt); +end; + +procedure NewBeat(Sender: TScreenSing); +var + Pet: integer; +// TempBeat: integer; +begin + // ustawia zaznaczenie tekstu +// SingScreen.LyricMain.Selected := -1; + for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do + if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeat) then begin + // operates on currently beated note + //Todo: Lyrics + //Sender.LyricMain.Selected := Pet; + +// LCD.MoveCursor(1, ScreenSing.LyricMain.SelectedLetter); +// LCD.ShowCursor; + + //LCD.MoveCursorBR(Sender.LyricMain.SelectedLetter); + LCD.ShowCursor; + + end; +end; + +procedure NewBeatC; +var + Pet: integer; +// LPT_1: integer; +// LPT_2: integer; +begin +// LPT_1 := 1; +// LPT_2 := 1; + + // beat click + if (Ini.BeatClick = 1) and ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod Czesci[0].Resolution = 0) then + Music.PlayClick; + + // debug system on LPT + if ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod Czesci[0].Resolution = 0) then begin + //LPT_1 := 0; +// Light.LightOne(0, 150); + + Light.LightOne(1, 200); // beat light + if ParamStr(1) = '-doublelights' then + Light.LightOne(0, 200); // beat light + + +{ if ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod (Czesci[0].Resolution * 2) = 0) then + Light.LightOne(0, 150) + else + Light.LightOne(1, 150)} + end; + + for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do + if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeatC) then begin + // click assist + if Ini.ClickAssist = 1 then + Music.PlayClick; + + //LPT_2 := 0; + if ParamStr(1) <> '-doublelights' then + Light.LightOne(0, 150); //125 + + + // drum machine +(* TempBeat := Czas.AktBeat;// + 2; + if (TempBeat mod 8 = 0) then Music.PlayDrum; + if (TempBeat mod 8 = 4) then Music.PlayClap; +// if (TempBeat mod 4 = 2) then Music.PlayHihat; + if (TempBeat mod 4 <> 0) then Music.PlayHihat;*) + end; + + {$IFDEF UseSerialPort} + // PortWriteB($378, LPT_1 + LPT_2 * 2); // 0 zapala + {$ENDIF} +end; + +procedure NewBeatD(Sender: TScreenSing); +begin + NewNote(Sender); +end; + +//procedure NewHalf; +//begin +// NewNote; +//end; + +procedure NewNote(Sender: TScreenSing); +var + CP: integer; // current player + S: integer; // sentence + SMin: integer; + SMax: integer; + SDet: integer; // temporary: sentence of detected note + Pet: integer; + Mozna: boolean; + Nowa: boolean; + Range: integer; + NoteHit:boolean; +begin +// Log.LogStatus('Beat ' + IntToStr(Czas.AktBeat) + ' HalfBeat ' + IntToStr(Czas.AktHalf), 'NewBeat'); +// beep; + + // analizuje dla obu graczy ten sam sygnal (Sound.OneSrcForBoth) + // albo juz lepiej nie + for CP := 0 to PlayersPlay-1 do begin + + // analyze buffer + Sound[CP].AnalizujBufor; + + // adds some noise +// Czas.Ton := Czas.Ton + Round(Random(3)) - 1; + + // 0.5.0: count min and max sentence range for checking (detection is delayed to the notes we see on the screen) + SMin := Czesci[0].Akt-1; + if SMin < 0 then SMin := 0; + SMax := Czesci[0].Akt; + + // check if we can add new note + Mozna := false; + SDet:=SMin; + for S := SMin to SMax do + for Pet := 0 to Czesci[0].Czesc[S].HighNut do + if ((Czesci[0].Czesc[S].Nuta[Pet].Start <= Czas.AktBeatD) + and (Czesci[0].Czesc[S].Nuta[Pet].Start + Czesci[0].Czesc[S].Nuta[Pet].Dlugosc - 1 >= Czas.AktBeatD)) + and (not Czesci[0].Czesc[S].Nuta[Pet].FreeStyle) // but don't allow when it's FreeStyle note + and (Czesci[0].Czesc[S].Nuta[Pet].Dlugosc > 0) // and make sure the note lenghts is at least 1 + then begin + SDet := S; + Mozna := true; + Break; + end; + + S := SDet; + + + + + +// Czas.SzczytJest := true; +// Czas.Ton := 27; + + // gdy moze, to dodaje nute + if (Sound[CP].SzczytJest) and (Mozna) then begin + // operowanie na ostatniej nucie + for Pet := 0 to Czesci[0].Czesc[S].HighNut do + if (Czesci[0].Czesc[S].Nuta[Pet].Start <= Czas.OldBeatD+1) + and (Czesci[0].Czesc[S].Nuta[Pet].Start + + Czesci[0].Czesc[S].Nuta[Pet].Dlugosc > Czas.OldBeatD+1) then begin + // to robi, tylko dla pary nut (oryginalnej i gracza) + + // przesuwanie tonu w odpowiednia game + while (Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton > 6) do + Sound[CP].Ton := Sound[CP].Ton - 12; + while (Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton < -6) do + Sound[CP].Ton := Sound[CP].Ton + 12; + + // Half size Notes Patch + NoteHit := false; + + //if Ini.Difficulty = 0 then Range := 2; + //if Ini.Difficulty = 1 then Range := 1; + //if Ini.Difficulty = 2 then Range := 0; + Range := 2 - Ini.Difficulty; + if abs(Czesci[0].Czesc[S].Nuta[Pet].Ton - Sound[CP].Ton) <= Range then begin + Sound[CP].Ton := Czesci[0].Czesc[S].Nuta[Pet].Ton; + + + // Half size Notes Patch + NoteHit := true; + + + if (Ini.LineBonus = 0) then + begin + // add points without LineBonus + case Czesci[0].Czesc[S].Nuta[Pet].Wartosc of + 1: Player[CP].Score := Player[CP].Score + 10000 / Czesci[0].Wartosc * + Czesci[0].Czesc[S].Nuta[Pet].Wartosc; + 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 10000 / Czesci[0].Wartosc * + Czesci[0].Czesc[S].Nuta[Pet].Wartosc; + end; + end + else + begin + // add points with Line Bonus + case Czesci[0].Czesc[S].Nuta[Pet].Wartosc of + 1: Player[CP].Score := Player[CP].Score + 9000 / Czesci[0].Wartosc * + Czesci[0].Czesc[S].Nuta[Pet].Wartosc; + 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 9000 / Czesci[0].Wartosc * + Czesci[0].Czesc[S].Nuta[Pet].Wartosc; + end; + end; + + Player[CP].ScoreI := Floor(Player[CP].Score / 10) * 10; + Player[CP].ScoreGoldenI := Floor(Player[CP].ScoreGolden / 10) * 10; + + Player[CP].ScoreTotalI := Player[CP].ScoreI + Player[CP].ScoreGoldenI + Player[CP].ScoreLineI; + end; + + end; // operowanie + + // sprawdzanie czy to nowa nuta, czy przedluzenie + if S = SMax then begin + Nowa := true; + // jezeli ostatnia ma ten sam ton + if (Player[CP].IlNut > 0 ) and (Player[CP].Nuta[Player[CP].HighNut].Ton = Sound[CP].Ton) + and (Player[CP].Nuta[Player[CP].HighNut].Start + Player[CP].Nuta[Player[CP].HighNut].Dlugosc = Czas.AktBeatD) + then Nowa := false; + // jezeli jest jakas nowa nuta na sprawdzanym beacie + for Pet := 0 to Czesci[0].Czesc[S].HighNut do + if (Czesci[0].Czesc[S].Nuta[Pet].Start = Czas.AktBeatD) then + Nowa := true; + + // dodawanie nowej nuty + if Nowa then begin + // nowa nuta + Player[CP].IlNut := Player[CP].IlNut + 1; + Player[CP].HighNut := Player[CP].HighNut + 1; + SetLength(Player[CP].Nuta, Player[CP].IlNut); + Player[CP].Nuta[Player[CP].HighNut].Start := Czas.AktBeatD; + Player[CP].Nuta[Player[CP].HighNut].Dlugosc := 1; + Player[CP].Nuta[Player[CP].HighNut].Ton := Sound[CP].Ton; // Ton || TonDokl + Player[CP].Nuta[Player[CP].HighNut].Detekt := Czas.MidBeat; + + + // Half Note Patch + Player[CP].Nuta[Player[CP].HighNut].Hit := NoteHit; + + + // Log.LogStatus('Nowa Nuta ' + IntToStr(Gracz.Nuta[Gracz.HighNut].Start), 'NewBeat'); + + end else begin + // przedluzenie nuty + Player[CP].Nuta[Player[CP].HighNut].Dlugosc := Player[CP].Nuta[Player[CP].HighNut].Dlugosc + 1; + end; + + + // check for perfect note and then lit the star (on Draw) + for Pet := 0 to Czesci[0].Czesc[S].HighNut do + if (Czesci[0].Czesc[S].Nuta[Pet].Start = Player[CP].Nuta[Player[CP].HighNut].Start) + and (Czesci[0].Czesc[S].Nuta[Pet].Dlugosc = Player[CP].Nuta[Player[CP].HighNut].Dlugosc) + and (Czesci[0].Czesc[S].Nuta[Pet].Ton = Player[CP].Nuta[Player[CP].HighNut].Ton) then begin + Player[CP].Nuta[Player[CP].HighNut].Perfect := true; + end; + + end;// else beep; // if S = SMax + + end; // if moze + end; // for CP +// Log.LogStatus('EndBeat', 'NewBeat'); + +//On Sentence End -> For LineBonus + SingBar +if (sDet >= low(Czesci[0].Czesc)) AND (sDet <= high(Czesci[0].Czesc)) then +if ((Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Start + Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Dlugosc - 1) = Czas.AktBeatD) then + Sender.onSentenceEnd(sDet); + +end; + +procedure ClearScores(PlayerNum: integer); +begin + Player[PlayerNum].Score := 0; + Player[PlayerNum].ScoreI := 0; + Player[PlayerNum].ScoreLine := 0; + Player[PlayerNum].ScoreLineI := 0; + Player[PlayerNum].ScoreGolden := 0; + Player[PlayerNum].ScoreGoldenI := 0; + Player[PlayerNum].ScoreTotalI := 0; + + + //SingBar Mod + Player[PlayerNum].ScoreLast := 0; + Player[PlayerNum].ScorePercent := 50;// Sets to 50% when song starts + Player[PlayerNum].ScorePercentTarget := 50;// Sets to 50% when song starts + //end SingBar Mod + + //PhrasenBonus - Line Bonus Mod + Player[PlayerNum].LineBonus_Visible := False; //Hide Line Bonus + Player[PlayerNum].LineBonus_Alpha := 0; + Player[PlayerNum].LineBonus_TargetX := 70 + PlayerNum*500; + Player[PlayerNum].LineBonus_TargetY := 30; + //PhrasenBonus - Line Bonus Mod End +end; + +//-------------------- +// Function sets all Absolute Paths e.g. Song Path and makes sure the Directorys exist +//-------------------- +procedure InitializePaths; + + // Initialize a Path Variable + // After Setting Paths, make sure that Paths exist + function initialize_path( out aPathVar : String; const aLocation : String ): boolean; + var + lWriteable: Boolean; + begin + aPathVar := aLocation; + + If DirectoryExists(aPathVar) then + lWriteable := ForceDirectories(aPathVar) + else + lWriteable := false; + + if not lWriteable then + Log.LogError('Error: Dir ('+ aLocation +') is Readonly'); + + result := lWriteable; + end; + +begin + + GamePath := ExtractFilePath(ParamStr(0)); + + initialize_path( LogPath , GamePath ); + initialize_path( SoundPath , GamePath + 'Sounds' + PathDelim ); + initialize_path( SongPath , GamePath + 'Songs' + PathDelim ); + initialize_path( ThemePath , GamePath + 'Themes' + PathDelim ); + initialize_path( ScreenshotsPath , GamePath + 'Screenshots' + PathDelim ); + initialize_path( CoversPath , GamePath + 'Covers' + PathDelim ); + initialize_path( LanguagesPath , GamePath + 'Languages' + PathDelim ); + initialize_path( PluginPath , GamePath + 'Plugins' + PathDelim ); + initialize_path( PlaylistPath , GamePath + 'Playlists' + PathDelim ); + + DecimalSeparator := ','; +end; + +end. + diff --git a/Game/Code/Classes/UMusic.pas b/Game/Code/Classes/UMusic.pas index e2e1f27e..b9ed47b4 100644 --- a/Game/Code/Classes/UMusic.pas +++ b/Game/Code/Classes/UMusic.pas @@ -1,731 +1,735 @@ -unit UMusic; - -interface - -{$I switches.inc} - -{$IFDEF FPC} - {$MODE Delphi} -{$ENDIF} - - -uses Classes, - {$IFDEF win32} - windows, - {$ENDIF} - UCommon, - Messages, - SysUtils, - {$IFNDEF FPC} - Forms, - {$ENDIF} - {$IFDEF useBASS} - bass, - {$ENDIF} - ULog, - USongs; - - -procedure InitializeSound; - -type - TSoundCard = record - Name: string; - Source: array of string; - end; - - TFFTData = array [0..256] of Single; - - TCustomSoundEntry = record - Filename : String; - Handle : hStream; - end; - - - TMusic = class - private - BassStart: hStream; // Wait, I've replaced this with BASS - BassBack: hStream; // It has almost all features we need - BassSwoosh: hStream; - BassChange: hStream; // Almost? It aleady has them all :) - BassOption: hStream; - BassClick: hStream; - BassDrum: hStream; - BassHihat: hStream; - BassClap: hStream; - BassShuffle: hStream; - - //Custom Sounds - CustomSounds: array of TCustomSoundEntry; - - - Loaded: boolean; - Loop: boolean; - public - Bass: hStream; - procedure InitializePlayback; - procedure InitializeRecord; - procedure SetVolume(Volume: integer); - procedure SetMusicVolume(Volume: integer); - procedure SetLoop(Enabled: boolean); - function Open(Name: string): boolean; // true if succeed - procedure Rewind; - procedure MoveTo(Time: real); - procedure Play; - procedure Pause; //Pause Mod - procedure Stop; - procedure Close; - function Finished: boolean; - function Length: real; - function Position: real; - procedure PlayStart; - procedure PlayBack; - procedure PlaySwoosh; - procedure PlayChange; - procedure PlayOption; - procedure PlayClick; - procedure PlayDrum; - procedure PlayHihat; - procedure PlayClap; - procedure PlayShuffle; - procedure StopShuffle; - procedure CaptureStart; - procedure CaptureStop; - procedure CaptureCard(RecordI, PlayerLeft, PlayerRight: byte); - procedure StopCard(Card: byte); - function LoadSoundFromFile(var hStream: hStream; Name: string): boolean; - - //Equalizer - function GetFFTData: TFFTData; - - //Custom Sounds - function LoadCustomSound(const Filename: String): Cardinal; - procedure PlayCustomSound(const Index: Cardinal); - -end; - -const - RecordSystem = 1; - -type - TMuzyka = record - Path: string; - Start: integer; // start of song in ms - IlNut: integer; - DlugoscNut: integer; - end; - - TCzesci = record - Akt: integer; // aktualna czesc utworu do rysowania - High: integer; - Ilosc: integer; - Resolution: integer; - NotesGAP: integer; - Wartosc: integer; - Czesc: array of record - Start: integer; - StartNote: integer; - Lyric: string; - LyricWidth: real; - Koniec: integer; - BaseNote: integer; - HighNut: integer; - IlNut: integer; - TotalNotes: integer; - Nuta: array of record - Color: integer; - Start: integer; - Dlugosc: integer; - Ton: integer; - TonGamy: integer; - Tekst: string; - FreeStyle: boolean; - Wartosc: integer; // zwykla nuta x1, zlota nuta x2 - end; - end; - end; - - TCzas = record // wszystko, co dotyczy aktualnej klatki - OldBeat: integer; // poprzednio wykryty beat w utworze - AktBeat: integer; // aktualny beat w utworze - MidBeat: real; // dokladny AktBeat - - // now we use this for super synchronization! - // only used when analyzing voice - OldBeatD: integer; // poprzednio wykryty beat w utworze - AktBeatD: integer; // aktualny beat w utworze - MidBeatD: real; // dokladny AktBeatD - FracBeatD: real; // fractional part of MidBeatD - - // we use this for audiable clicks - OldBeatC: integer; // poprzednio wykryty beat w utworze - AktBeatC: integer; // aktualny beat w utworze - MidBeatC: real; // dokladny AktBeatC - FracBeatC: real; // fractional part of MidBeatC - - - OldCzesc: integer; // poprzednio wyswietlana czesc - // akt jest w czesci.akt - - Teraz: real; // aktualny czas w utworze - Razem: real; // caly czas utworu - end; - -var - Music: TMusic; - - // muzyka - Muzyka: TMuzyka; - - // czesci z nutami; - Czesci: array of TCzesci; - - // czas - Czas: TCzas; - - fHWND: Thandle; - -type - TMPModes = (mpNotReady, mpStopped, mpPlaying, mpRecording, mpSeeking, - mpPaused, mpOpen); - -const - ModeStr: array[TMPModes] of string = ('Not ready', 'Stopped', 'Playing', 'Recording', 'Seeking', 'Paused', 'Open'); - -implementation - -uses - {$IFDEF FPC} - lclintf, - {$ENDIF} - UGraphic, - URecord, - UFiles, - UIni, - UMain, - UThemes; - -procedure InitializeSound; -begin - Log.LogStatus('Initializing Playback', 'InitializeSound'); Music.InitializePlayback; - Log.LogStatus('Initializing Record', 'InitializeSound'); Music.InitializeRecord; -end; - -procedure TMusic.InitializePlayback; -var - Pet: integer; - S: integer; -begin - Log.BenchmarkStart(4); - Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize'); - - Loaded := false; - Loop := false; - - fHWND := AllocateHWND( nil); // TODO : JB_lazarus - can we do something different here ?? lazarus didnt like this function - - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - if not BASS_Init(1, 44100, 0, fHWND, nil) then - begin - {$IFNDEF FPC} - // TODO : JB_lazarus find a way to do this nice.. - Application.MessageBox ('Could not initialize BASS', 'Error'); - {$ENDIF} - Exit; - end; - {$ENDIF} - - Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4); - - // config playing buffer -// BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 10); -// BASS_SetConfig(BASS_CONFIG_BUFFER, 100); - - Log.LogStatus('Loading Sounds', 'Music Initialize'); - - Log.BenchmarkStart(4); - LoadSoundFromFile(BassStart, SoundPath + 'Common Start.mp3'); - LoadSoundFromFile(BassBack, SoundPath + 'Common Back.mp3'); - LoadSoundFromFile(BassSwoosh, SoundPath + 'menu swoosh.mp3'); - LoadSoundFromFile(BassChange, SoundPath + 'select music change music 50.mp3'); - LoadSoundFromFile(BassOption, SoundPath + 'option change col.mp3'); - LoadSoundFromFile(BassClick, SoundPath + 'rimshot022b.mp3'); - -// LoadSoundFromFile(BassDrum, SoundPath + 'bassdrumhard076b.mp3'); -// LoadSoundFromFile(BassHihat, SoundPath + 'hihatclosed068b.mp3'); -// LoadSoundFromFile(BassClap, SoundPath + 'claps050b.mp3'); - -// LoadSoundFromFile(BassShuffle, SoundPath + 'Shuffle.mp3'); - - Log.BenchmarkEnd(4); Log.LogBenchmark('--> Loading Sounds', 4); -end; - -procedure TMusic.InitializeRecord; -var - S: integer; - device: integer; - descr: string; - input: integer; - input2: integer; - flags: integer; - mic: array[0..15] of integer; - SC: integer; // soundcard - SCI: integer; // soundcard input -begin - if RecordSystem = 1 then begin - SetLength(Sound, 6 {max players});//Ini.Players+1); - for S := 0 to High(Sound) do begin //Ini.Players do begin - Sound[S] := TSound.Create; - Sound[S].Num := S; - Sound[S].BufferNew := TMemoryStream.Create; - SetLength(Sound[S].BufferLong, 1); - Sound[S].BufferLong[0] := TMemoryStream.Create; - Sound[S].n := 4*1024; - end; - - - // check for recording devices; - {device := 0; - descr := BASS_RecordGetDeviceDescription(device); - - SetLength(SoundCard, 0); - while (descr <> '') do begin - SC := High(SoundCard) + 1; - SetLength(SoundCard, SC+1); - - Log.LogAnalyze('Device #'+IntToStr(device)+': '+ descr); - SoundCard[SC].Description := Descr; - - // check for recording inputs - mic[device] := -1; // default to no change - input := 0; - BASS_RecordInit(device); - Log.LogAnalyze('Input #' + IntToStr(Input) + ': ' + BASS_RecordGetInputName(input)); - flags := BASS_RecordGetInput(input); - - SetLength(SoundCard[SC].Input, 0); - while (flags <> -1) do begin - SCI := High(SoundCard[SC].Input) + 1; - SetLength(SoundCard[SC].Input, SCI+1); - - Log.LogAnalyze('Input #' + IntToStr(Input) + ': ' + BASS_RecordGetInputName(input)); - SoundCard[SC].Input[SCI].Name := BASS_RecordGetInputName(Input); - - if (flags and BASS_INPUT_TYPE_MASK) = BASS_INPUT_TYPE_MIC then begin - mic[device] := input; // auto set microphone - end; - Inc(Input); - flags := BASS_RecordGetInput(input); - end; - - if mic[device] <> -1 then begin - Log.LogAnalyze('Found the mic at input ' + IntToStr(Mic[device])) - end else begin - Log.LogAnalyze('Mic not found'); - mic[device] := 0; // setting to the first one (for kxproject) - end; - SoundCard[SC].InputSeleceted := Mic[Device]; - - - BASS_RecordFree; - - inc(Device); - descr := BASS_RecordGetDeviceDescription(Device); - end; // while} - end; // if -end; - -procedure TMusic.SetVolume(Volume: integer); -begin - //Old Sets Wave Volume - //BASS_SetVolume(Volume); - //New: Sets Volume only for this Application - - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - BASS_SetConfig(BASS_CONFIG_GVOL_SAMPLE, Volume); - BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume); - BASS_SetConfig(BASS_CONFIG_GVOL_MUSIC, Volume); - {$ENDIF} -end; - -procedure TMusic.SetMusicVolume(Volume: Integer); -begin - //Max Volume Prevention - if Volume > 100 then - Volume := 100; - - //Set Volume - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - BASS_ChannelSetAttributes (Bass, -1, Volume, -101); - {$ENDIF} -end; - -procedure TMusic.SetLoop(Enabled: boolean); -begin - Loop := Enabled; -end; - -function TMusic.Open(Name: string): boolean; -begin - Loaded := false; - if FileExists(Name) then - begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - Bass := Bass_StreamCreateFile(false, pchar(Name), 0, 0, 0); - {$ENDIF} - - Loaded := true; - //Set Max Volume - SetMusicVolume (100); - end; - - Result := Loaded; -end; - -procedure TMusic.Rewind; -begin - if Loaded then begin - end; -end; - -procedure TMusic.MoveTo(Time: real); -var - bytes: integer; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - bytes := BASS_ChannelSeconds2Bytes(Bass, Time); - BASS_ChannelSetPosition(Bass, bytes); - {$ENDIF} -end; - -procedure TMusic.Play; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - if Loaded then - begin - if Loop then - BASS_ChannelPlay(Bass, True); // start from beginning... actually bass itself does not loop, nor does this TMusic Class - - BASS_ChannelPlay(Bass, False); // for setting position before playing - end; - {$ENDIF} -end; - -procedure TMusic.Pause; //Pause Mod -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - if Loaded then begin - BASS_ChannelPause(Bass); // Pauses Song - end; - {$ENDIF} -end; - -procedure TMusic.Stop; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - Bass_ChannelStop(Bass); - {$ENDIF} -end; - -procedure TMusic.Close; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - Bass_StreamFree(Bass); - {$ENDIF} -end; - -function TMusic.Length: real; -var - bytes: integer; -begin - Result := 60; - - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - bytes := BASS_ChannelGetLength(Bass); - Result := BASS_ChannelBytes2Seconds(Bass, bytes); - {$ENDIF} -end; - -function TMusic.Position: real; -var - bytes: integer; -begin - Result := 0; - - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - bytes := BASS_ChannelGetPosition(BASS); - Result := BASS_ChannelBytes2Seconds(BASS, bytes); - {$ENDIF} -end; - -function TMusic.Finished: boolean; -begin - Result := false; - - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - if BASS_ChannelIsActive(BASS) = BASS_ACTIVE_STOPPED then - begin - Result := true; - end; - {$ENDIF} -end; - -procedure TMusic.PlayStart; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - BASS_ChannelPlay(BassStart, True); - {$ENDIF} -end; - -procedure TMusic.PlayBack; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - BASS_ChannelPlay(BassBack, True);// then - {$ENDIF} -end; - -procedure TMusic.PlaySwoosh; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - BASS_ChannelPlay(BassSwoosh, True); - {$ENDIF} -end; - -procedure TMusic.PlayChange; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - BASS_ChannelPlay(BassChange, True); - {$ENDIF} -end; - -procedure TMusic.PlayOption; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - BASS_ChannelPlay(BassOption, True); - {$ENDIF} -end; - -procedure TMusic.PlayClick; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - BASS_ChannelPlay(BassClick, True); - {$ENDIF} -end; - -procedure TMusic.PlayDrum; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - BASS_ChannelPlay(BassDrum, True); - {$ENDIF} -end; - -procedure TMusic.PlayHihat; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - BASS_ChannelPlay(BassHihat, True); - {$ENDIF} -end; - -procedure TMusic.PlayClap; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - BASS_ChannelPlay(BassClap, True); - {$ENDIF} -end; - -procedure TMusic.PlayShuffle; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - BASS_ChannelPlay(BassShuffle, True); - {$ENDIF} -end; - -procedure TMusic.StopShuffle; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - BASS_ChannelStop(BassShuffle); - {$ENDIF} -end; - -procedure TMusic.CaptureStart; -var - S: integer; - SC: integer; - P1: integer; - P2: integer; -begin - for S := 0 to High(Sound) do - Sound[S].BufferLong[0].Clear; - - for SC := 0 to High(Ini.CardList) do begin - P1 := Ini.CardList[SC].ChannelL; - P2 := Ini.CardList[SC].ChannelR; - if P1 > PlayersPlay then P1 := 0; - if P2 > PlayersPlay then P2 := 0; - if (P1 > 0) or (P2 > 0) then - CaptureCard(SC, P1, P2); - end; -end; - -procedure TMusic.CaptureStop; -var - SC: integer; - P1: integer; - P2: integer; -begin - - for SC := 0 to High(Ini.CardList) do begin - P1 := Ini.CardList[SC].ChannelL; - P2 := Ini.CardList[SC].ChannelR; - if P1 > PlayersPlay then P1 := 0; - if P2 > PlayersPlay then P2 := 0; - if (P1 > 0) or (P2 > 0) then StopCard(SC); - end; - -end; - -//procedure TMusic.CaptureCard(RecordI, SoundNum, PlayerLeft, PlayerRight: byte); -procedure TMusic.CaptureCard(RecordI, PlayerLeft, PlayerRight: byte); -var - Error: integer; - ErrorMsg: string; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - - if not BASS_RecordInit(RecordI) then begin - Error := BASS_ErrorGetCode; - - ErrorMsg := IntToStr(Error); - if Error = BASS_ERROR_DX then ErrorMsg := 'No DX5'; - if Error = BASS_ERROR_ALREADY then ErrorMsg := 'The device has already been initialized'; - if Error = BASS_ERROR_DEVICE then ErrorMsg := 'The device number specified is invalid'; - if Error = BASS_ERROR_DRIVER then ErrorMsg := 'There is no available device driver'; - - {Log.LogAnalyze('Error initializing record [' + IntToStr(RecordI) + ', ' - + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: ' - + ErrorMsg);} - Log.LogError('Error initializing record [' + IntToStr(RecordI) + ', ' - + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: ' - + ErrorMsg); - Log.LogError('Music -> CaptureCard: Error initializing record: ' + ErrorMsg); - - - end - else - begin - Recording.SoundCard[RecordI].BassRecordStream := BASS_RecordStart(44100, 2, MakeLong(0, 20) , @GetMicrophone, PlayerLeft + PlayerRight*256); - end; - - {$ENDIF} -end; - -procedure TMusic.StopCard(Card: byte); -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - BASS_RecordSetDevice(Card); - BASS_RecordFree; - {$ENDIF} -end; - -function TMusic.LoadSoundFromFile(var hStream: hStream; Name: string): boolean; -var - L: Integer; -begin - if FileExists(Name) then begin - Log.LogStatus('Loading Sound: "' + Name + '"', 'LoadSoundFromFile'); - try - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - hStream := BASS_StreamCreateFile(False, pchar(Name), 0, 0, 0); - {$ENDIF} - - //Add CustomSound - L := High(CustomSounds) + 1; - SetLength (CustomSounds, L + 1); - CustomSounds[L].Filename := Name; - CustomSounds[L].Handle := hStream; - except - Log.LogError('Failed to open using BASS', 'LoadSoundFromFile'); - end; - end else begin - Log.LogError('Sound not found: "' + Name + '"', 'LoadSoundFromFile'); - exit; - end; -end; - -//Equalizer -function TMusic.GetFFTData: TFFTData; -var -Data: TFFTData; -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - - //Get Channel Data Mono and 256 Values - BASS_ChannelGetData(Bass, @Result, BASS_DATA_FFT512); - //Result := Data; - - {$ENDIF} -end; - -function TMusic.LoadCustomSound(const Filename: String): Cardinal; -var - S: hStream; - I: Integer; - F: String; -begin - //Search for Sound in already loaded Sounds - F := UpperCase(SoundPath + FileName); - For I := 0 to High(CustomSounds) do - begin - if (UpperCase(CustomSounds[I].Filename) = F) then - begin - Result := I; - Exit; - end; - end; - - if LoadSoundFromFile(S, SoundPath + Filename) then - Result := High(CustomSounds) - else - Result := 0; -end; - -procedure TMusic.PlayCustomSound(const Index: Cardinal); -begin - {$IFDEF useBASS} - // TODO : jb_linux replace with something other than bass - - if Index <= High(CustomSounds) then - BASS_ChannelPlay(CustomSounds[Index].Handle, True); - - {$ENDIF} -end; - - -end. +unit UMusic; + +interface + +{$I switches.inc} + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + + +uses Classes, + {$IFDEF win32} + windows, + {$ENDIF} + UCommon, + Messages, + SysUtils, + {$IFNDEF FPC} + Forms, + {$ENDIF} + {$IFDEF useBASS} + bass, + {$ENDIF} + ULog, + USongs; + + +procedure InitializeSound; + +type + TSoundCard = record + Name: string; + Source: array of string; + end; + + TFFTData = array [0..256] of Single; + + TCustomSoundEntry = record + Filename : String; + Handle : hStream; + end; + + + TMusic = class + private + BassStart: hStream; // Wait, I've replaced this with BASS + BassBack: hStream; // It has almost all features we need + BassSwoosh: hStream; + BassChange: hStream; // Almost? It aleady has them all :) + BassOption: hStream; + BassClick: hStream; + BassDrum: hStream; + BassHihat: hStream; + BassClap: hStream; + BassShuffle: hStream; + + //Custom Sounds + CustomSounds: array of TCustomSoundEntry; + + + Loaded: boolean; + Loop: boolean; + public + Bass: hStream; + procedure InitializePlayback; + procedure InitializeRecord; + procedure SetVolume(Volume: integer); + procedure SetMusicVolume(Volume: integer); + procedure SetLoop(Enabled: boolean); + function Open(Name: string): boolean; // true if succeed + procedure Rewind; + procedure MoveTo(Time: real); + procedure Play; + procedure Pause; //Pause Mod + procedure Stop; + procedure Close; + function Finished: boolean; + function Length: real; + function Position: real; + procedure PlayStart; + procedure PlayBack; + procedure PlaySwoosh; + procedure PlayChange; + procedure PlayOption; + procedure PlayClick; + procedure PlayDrum; + procedure PlayHihat; + procedure PlayClap; + procedure PlayShuffle; + procedure StopShuffle; + procedure CaptureStart; + procedure CaptureStop; + procedure CaptureCard(RecordI, PlayerLeft, PlayerRight: byte); + procedure StopCard(Card: byte); + function LoadSoundFromFile(var hStream: hStream; Name: string): boolean; + + //Equalizer + function GetFFTData: TFFTData; + + //Custom Sounds + function LoadCustomSound(const Filename: String): Cardinal; + procedure PlayCustomSound(const Index: Cardinal); + +end; + +const + RecordSystem = 1; + +type + TMuzyka = record + Path: string; + Start: integer; // start of song in ms + IlNut: integer; + DlugoscNut: integer; + end; + + PLine = ^TLine; + TLine = record + Start: integer; + StartNote: integer; + Lyric: string; + LyricWidth: real; + Koniec: integer; + BaseNote: integer; + HighNut: integer; + IlNut: integer; + TotalNotes: integer; + Nuta: array of record + Color: integer; + Start: integer; + Dlugosc: integer; + Ton: integer; + TonGamy: integer; + Tekst: string; + FreeStyle: boolean; + Wartosc: integer; // zwykla nuta x1, zlota nuta x2 + end; + end; + ALine = array of TLine; + + TCzesci = record + Akt: integer; // aktualna czesc utworu do rysowania + High: integer; + Ilosc: integer; + Resolution: integer; + NotesGAP: integer; + Wartosc: integer; + Czesc: ALine; + end; + + TCzas = record // wszystko, co dotyczy aktualnej klatki + OldBeat: integer; // poprzednio wykryty beat w utworze + AktBeat: integer; // aktualny beat w utworze + MidBeat: real; // dokladny AktBeat + + // now we use this for super synchronization! + // only used when analyzing voice + OldBeatD: integer; // poprzednio wykryty beat w utworze + AktBeatD: integer; // aktualny beat w utworze + MidBeatD: real; // dokladny AktBeatD + FracBeatD: real; // fractional part of MidBeatD + + // we use this for audiable clicks + OldBeatC: integer; // poprzednio wykryty beat w utworze + AktBeatC: integer; // aktualny beat w utworze + MidBeatC: real; // dokladny AktBeatC + FracBeatC: real; // fractional part of MidBeatC + + + OldCzesc: integer; // poprzednio wyswietlana czesc + // akt jest w czesci.akt + + Teraz: real; // aktualny czas w utworze + Razem: real; // caly czas utworu + end; + +var + Music: TMusic; + + // muzyka + Muzyka: TMuzyka; + + // czesci z nutami; + Czesci: array of TCzesci; + + // czas + Czas: TCzas; + + fHWND: Thandle; + +type + TMPModes = (mpNotReady, mpStopped, mpPlaying, mpRecording, mpSeeking, + mpPaused, mpOpen); + +const + ModeStr: array[TMPModes] of string = ('Not ready', 'Stopped', 'Playing', 'Recording', 'Seeking', 'Paused', 'Open'); + +implementation + +uses + {$IFDEF FPC} + lclintf, + {$ENDIF} + UGraphic, + URecord, + UFiles, + UIni, + UMain, + UThemes; + +procedure InitializeSound; +begin + Log.LogStatus('Initializing Playback', 'InitializeSound'); Music.InitializePlayback; + Log.LogStatus('Initializing Record', 'InitializeSound'); Music.InitializeRecord; +end; + +procedure TMusic.InitializePlayback; +var + Pet: integer; + S: integer; +begin + Log.BenchmarkStart(4); + Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize'); + + Loaded := false; + Loop := false; + + fHWND := AllocateHWND( nil); // TODO : JB_lazarus - can we do something different here ?? lazarus didnt like this function + + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + if not BASS_Init(1, 44100, 0, fHWND, nil) then + begin + {$IFNDEF FPC} + // TODO : JB_lazarus find a way to do this nice.. + Application.MessageBox ('Could not initialize BASS', 'Error'); + {$ENDIF} + Exit; + end; + {$ENDIF} + + Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4); + + // config playing buffer +// BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 10); +// BASS_SetConfig(BASS_CONFIG_BUFFER, 100); + + Log.LogStatus('Loading Sounds', 'Music Initialize'); + + Log.BenchmarkStart(4); + LoadSoundFromFile(BassStart, SoundPath + 'Common Start.mp3'); + LoadSoundFromFile(BassBack, SoundPath + 'Common Back.mp3'); + LoadSoundFromFile(BassSwoosh, SoundPath + 'menu swoosh.mp3'); + LoadSoundFromFile(BassChange, SoundPath + 'select music change music 50.mp3'); + LoadSoundFromFile(BassOption, SoundPath + 'option change col.mp3'); + LoadSoundFromFile(BassClick, SoundPath + 'rimshot022b.mp3'); + +// LoadSoundFromFile(BassDrum, SoundPath + 'bassdrumhard076b.mp3'); +// LoadSoundFromFile(BassHihat, SoundPath + 'hihatclosed068b.mp3'); +// LoadSoundFromFile(BassClap, SoundPath + 'claps050b.mp3'); + +// LoadSoundFromFile(BassShuffle, SoundPath + 'Shuffle.mp3'); + + Log.BenchmarkEnd(4); Log.LogBenchmark('--> Loading Sounds', 4); +end; + +procedure TMusic.InitializeRecord; +var + S: integer; + device: integer; + descr: string; + input: integer; + input2: integer; + flags: integer; + mic: array[0..15] of integer; + SC: integer; // soundcard + SCI: integer; // soundcard input +begin + if RecordSystem = 1 then begin + SetLength(Sound, 6 {max players});//Ini.Players+1); + for S := 0 to High(Sound) do begin //Ini.Players do begin + Sound[S] := TSound.Create; + Sound[S].Num := S; + Sound[S].BufferNew := TMemoryStream.Create; + SetLength(Sound[S].BufferLong, 1); + Sound[S].BufferLong[0] := TMemoryStream.Create; + Sound[S].n := 4*1024; + end; + + + // check for recording devices; + {device := 0; + descr := BASS_RecordGetDeviceDescription(device); + + SetLength(SoundCard, 0); + while (descr <> '') do begin + SC := High(SoundCard) + 1; + SetLength(SoundCard, SC+1); + + Log.LogAnalyze('Device #'+IntToStr(device)+': '+ descr); + SoundCard[SC].Description := Descr; + + // check for recording inputs + mic[device] := -1; // default to no change + input := 0; + BASS_RecordInit(device); + Log.LogAnalyze('Input #' + IntToStr(Input) + ': ' + BASS_RecordGetInputName(input)); + flags := BASS_RecordGetInput(input); + + SetLength(SoundCard[SC].Input, 0); + while (flags <> -1) do begin + SCI := High(SoundCard[SC].Input) + 1; + SetLength(SoundCard[SC].Input, SCI+1); + + Log.LogAnalyze('Input #' + IntToStr(Input) + ': ' + BASS_RecordGetInputName(input)); + SoundCard[SC].Input[SCI].Name := BASS_RecordGetInputName(Input); + + if (flags and BASS_INPUT_TYPE_MASK) = BASS_INPUT_TYPE_MIC then begin + mic[device] := input; // auto set microphone + end; + Inc(Input); + flags := BASS_RecordGetInput(input); + end; + + if mic[device] <> -1 then begin + Log.LogAnalyze('Found the mic at input ' + IntToStr(Mic[device])) + end else begin + Log.LogAnalyze('Mic not found'); + mic[device] := 0; // setting to the first one (for kxproject) + end; + SoundCard[SC].InputSeleceted := Mic[Device]; + + + BASS_RecordFree; + + inc(Device); + descr := BASS_RecordGetDeviceDescription(Device); + end; // while} + end; // if +end; + +procedure TMusic.SetVolume(Volume: integer); +begin + //Old Sets Wave Volume + //BASS_SetVolume(Volume); + //New: Sets Volume only for this Application + + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_SetConfig(BASS_CONFIG_GVOL_SAMPLE, Volume); + BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume); + BASS_SetConfig(BASS_CONFIG_GVOL_MUSIC, Volume); + {$ENDIF} +end; + +procedure TMusic.SetMusicVolume(Volume: Integer); +begin + //Max Volume Prevention + if Volume > 100 then + Volume := 100; + + //Set Volume + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelSetAttributes (Bass, -1, Volume, -101); + {$ENDIF} +end; + +procedure TMusic.SetLoop(Enabled: boolean); +begin + Loop := Enabled; +end; + +function TMusic.Open(Name: string): boolean; +begin + Loaded := false; + if FileExists(Name) then + begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + Bass := Bass_StreamCreateFile(false, pchar(Name), 0, 0, 0); + {$ENDIF} + + Loaded := true; + //Set Max Volume + SetMusicVolume (100); + end; + + Result := Loaded; +end; + +procedure TMusic.Rewind; +begin + if Loaded then begin + end; +end; + +procedure TMusic.MoveTo(Time: real); +var + bytes: integer; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + bytes := BASS_ChannelSeconds2Bytes(Bass, Time); + BASS_ChannelSetPosition(Bass, bytes); + {$ENDIF} +end; + +procedure TMusic.Play; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + if Loaded then + begin + if Loop then + BASS_ChannelPlay(Bass, True); // start from beginning... actually bass itself does not loop, nor does this TMusic Class + + BASS_ChannelPlay(Bass, False); // for setting position before playing + end; + {$ENDIF} +end; + +procedure TMusic.Pause; //Pause Mod +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + if Loaded then begin + BASS_ChannelPause(Bass); // Pauses Song + end; + {$ENDIF} +end; + +procedure TMusic.Stop; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + Bass_ChannelStop(Bass); + {$ENDIF} +end; + +procedure TMusic.Close; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + Bass_StreamFree(Bass); + {$ENDIF} +end; + +function TMusic.Length: real; +var + bytes: integer; +begin + Result := 60; + + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + bytes := BASS_ChannelGetLength(Bass); + Result := BASS_ChannelBytes2Seconds(Bass, bytes); + {$ENDIF} +end; + +function TMusic.Position: real; +var + bytes: integer; +begin + Result := 0; + + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + bytes := BASS_ChannelGetPosition(BASS); + Result := BASS_ChannelBytes2Seconds(BASS, bytes); + {$ENDIF} +end; + +function TMusic.Finished: boolean; +begin + Result := false; + + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + if BASS_ChannelIsActive(BASS) = BASS_ACTIVE_STOPPED then + begin + Result := true; + end; + {$ENDIF} +end; + +procedure TMusic.PlayStart; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassStart, True); + {$ENDIF} +end; + +procedure TMusic.PlayBack; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassBack, True);// then + {$ENDIF} +end; + +procedure TMusic.PlaySwoosh; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassSwoosh, True); + {$ENDIF} +end; + +procedure TMusic.PlayChange; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassChange, True); + {$ENDIF} +end; + +procedure TMusic.PlayOption; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassOption, True); + {$ENDIF} +end; + +procedure TMusic.PlayClick; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassClick, True); + {$ENDIF} +end; + +procedure TMusic.PlayDrum; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassDrum, True); + {$ENDIF} +end; + +procedure TMusic.PlayHihat; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassHihat, True); + {$ENDIF} +end; + +procedure TMusic.PlayClap; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassClap, True); + {$ENDIF} +end; + +procedure TMusic.PlayShuffle; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassShuffle, True); + {$ENDIF} +end; + +procedure TMusic.StopShuffle; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelStop(BassShuffle); + {$ENDIF} +end; + +procedure TMusic.CaptureStart; +var + S: integer; + SC: integer; + P1: integer; + P2: integer; +begin + for S := 0 to High(Sound) do + Sound[S].BufferLong[0].Clear; + + for SC := 0 to High(Ini.CardList) do begin + P1 := Ini.CardList[SC].ChannelL; + P2 := Ini.CardList[SC].ChannelR; + if P1 > PlayersPlay then P1 := 0; + if P2 > PlayersPlay then P2 := 0; + if (P1 > 0) or (P2 > 0) then + CaptureCard(SC, P1, P2); + end; +end; + +procedure TMusic.CaptureStop; +var + SC: integer; + P1: integer; + P2: integer; +begin + + for SC := 0 to High(Ini.CardList) do begin + P1 := Ini.CardList[SC].ChannelL; + P2 := Ini.CardList[SC].ChannelR; + if P1 > PlayersPlay then P1 := 0; + if P2 > PlayersPlay then P2 := 0; + if (P1 > 0) or (P2 > 0) then StopCard(SC); + end; + +end; + +//procedure TMusic.CaptureCard(RecordI, SoundNum, PlayerLeft, PlayerRight: byte); +procedure TMusic.CaptureCard(RecordI, PlayerLeft, PlayerRight: byte); +var + Error: integer; + ErrorMsg: string; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + + if not BASS_RecordInit(RecordI) then begin + Error := BASS_ErrorGetCode; + + ErrorMsg := IntToStr(Error); + if Error = BASS_ERROR_DX then ErrorMsg := 'No DX5'; + if Error = BASS_ERROR_ALREADY then ErrorMsg := 'The device has already been initialized'; + if Error = BASS_ERROR_DEVICE then ErrorMsg := 'The device number specified is invalid'; + if Error = BASS_ERROR_DRIVER then ErrorMsg := 'There is no available device driver'; + + {Log.LogAnalyze('Error initializing record [' + IntToStr(RecordI) + ', ' + + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: ' + + ErrorMsg);} + Log.LogError('Error initializing record [' + IntToStr(RecordI) + ', ' + + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: ' + + ErrorMsg); + Log.LogError('Music -> CaptureCard: Error initializing record: ' + ErrorMsg); + + + end + else + begin + Recording.SoundCard[RecordI].BassRecordStream := BASS_RecordStart(44100, 2, MakeLong(0, 20) , @GetMicrophone, PlayerLeft + PlayerRight*256); + end; + + {$ENDIF} +end; + +procedure TMusic.StopCard(Card: byte); +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_RecordSetDevice(Card); + BASS_RecordFree; + {$ENDIF} +end; + +function TMusic.LoadSoundFromFile(var hStream: hStream; Name: string): boolean; +var + L: Integer; +begin + if FileExists(Name) then begin + Log.LogStatus('Loading Sound: "' + Name + '"', 'LoadSoundFromFile'); + try + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + hStream := BASS_StreamCreateFile(False, pchar(Name), 0, 0, 0); + {$ENDIF} + + //Add CustomSound + L := High(CustomSounds) + 1; + SetLength (CustomSounds, L + 1); + CustomSounds[L].Filename := Name; + CustomSounds[L].Handle := hStream; + except + Log.LogError('Failed to open using BASS', 'LoadSoundFromFile'); + end; + end else begin + Log.LogError('Sound not found: "' + Name + '"', 'LoadSoundFromFile'); + exit; + end; +end; + +//Equalizer +function TMusic.GetFFTData: TFFTData; +var +Data: TFFTData; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + + //Get Channel Data Mono and 256 Values + BASS_ChannelGetData(Bass, @Result, BASS_DATA_FFT512); + //Result := Data; + + {$ENDIF} +end; + +function TMusic.LoadCustomSound(const Filename: String): Cardinal; +var + S: hStream; + I: Integer; + F: String; +begin + //Search for Sound in already loaded Sounds + F := UpperCase(SoundPath + FileName); + For I := 0 to High(CustomSounds) do + begin + if (UpperCase(CustomSounds[I].Filename) = F) then + begin + Result := I; + Exit; + end; + end; + + if LoadSoundFromFile(S, SoundPath + Filename) then + Result := High(CustomSounds) + else + Result := 0; +end; + +procedure TMusic.PlayCustomSound(const Index: Cardinal); +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + + if Index <= High(CustomSounds) then + BASS_ChannelPlay(CustomSounds[Index].Handle, True); + + {$ENDIF} +end; + + +end. diff --git a/Game/Code/Classes/UThemes.pas b/Game/Code/Classes/UThemes.pas index 6436ee39..1e102987 100644 --- a/Game/Code/Classes/UThemes.pas +++ b/Game/Code/Classes/UThemes.pas @@ -18,6 +18,10 @@ type B: single; end; + TRGBA = record + R, G, B, A: Double; + end; + TThemeBackground = record Tex: string; end; diff --git a/Game/Code/Screens/UScreenEditSub.pas b/Game/Code/Screens/UScreenEditSub.pas index 3843fbf4..93a4892a 100644 --- a/Game/Code/Screens/UScreenEditSub.pas +++ b/Game/Code/Screens/UScreenEditSub.pas @@ -16,7 +16,7 @@ uses ULog, UTexture, UMenuText, - ULyrics, + ULyrics.bak, Math, OpenGL12, {$IFDEF UseMIDIPort} diff --git a/Game/Code/Screens/UScreenSing.pas b/Game/Code/Screens/UScreenSing.pas index 343a2e6d..ff6bfe20 100644 --- a/Game/Code/Screens/UScreenSing.pas +++ b/Game/Code/Screens/UScreenSing.pas @@ -1,1256 +1,1301 @@ -unit UScreenSing; - -interface - -{$I switches.inc} - -{$IFDEF FPC} - {$MODE DELPHI} -{$ENDIF} - - -uses UMenu, - UMusic, - SDL, - SysUtils, - UFiles, - UTime, - USongs, - UIni, - ULog, - UTexture, - ULyrics, - TextGL, - OpenGL12, - {$IFDEF useBASS} - bass, - {$ENDIF} - UThemes, - ULCD, - UGraphicClasses, - UVideo; - -type - TScreenSing = class(TMenu) - protected - paused: boolean; //Pause Mod - PauseTime: Real; - NumEmptySentences: integer; - public - //TextTime: integer; - - //TimeBar mod - StaticTimeProgress: integer; - TextTimeText: integer; - //eoa TimeBar mod - - StaticP1: integer; - StaticP1ScoreBG: integer; - TextP1: 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; - StaticP1TwoPScoreBG: integer; - TextP1TwoP: integer; - TextP1TwoPScore: integer; - //shown when game is in 3/6 player modus - StaticP1ThreeP: integer; - StaticP1ThreePScoreBG: integer; - TextP1ThreeP: integer; - TextP1ThreePScore: integer; - //eoa - - StaticP2R: integer; - StaticP2RScoreBG: integer; - TextP2R: integer; - TextP2RScore: integer; - - StaticP2M: integer; - StaticP2MScoreBG: integer; - TextP2M: integer; - TextP2MScore: integer; - - StaticP3R: integer; - StaticP3RScoreBG: integer; - TextP3R: integer; - TextP3RScore: integer; - - Tex_Background: TTexture; - FadeOut: boolean; - LyricMain: TLyric; - LyricSub: TLyric; - - constructor Create; override; - procedure onShow; override; - procedure onShowFinish; override; - function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override; - function Draw: boolean; override; - procedure Finish; virtual; - procedure UpdateLCD; - procedure Pause; //Pause Mod(Toggles Pause) - - //OnSentenceEnd for LineBonus + Singbar - procedure onSentenceEnd(S: Cardinal); - //OnSentenceChange (for Golden Notes) - procedure onSentenceChange(S: Cardinal); - end; - -implementation -uses UGraphic, UDraw, UMain, 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; ScanCode: byte; PressedDown: Boolean): Boolean; -begin - Result := true; - If (PressedDown) Then - begin // Key Down - case PressedKey of - SDLK_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; - end; - - SDLK_ESCAPE, - SDLK_BACKSPACE : - begin - //Record Sound Hack: - //Sound[0].BufferLong - - Finish; - Music.PlayBack; - FadeTo(@ScreenScore); - end; - - SDLK_P://Pause Mod - begin - Pause; - 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 //Pause einschalten - begin - // pause Time - PauseTime := Czas.Teraz; - Paused := true; - - // pause Music - Music.Pause; - - // pause Video - if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then - FFmpegTogglePause; - end - else //Pause ausschalten - begin - Czas.Teraz := PauseTime; //Position of Notes - - // Position of Music - Music.MoveTo (PauseTime); - // Play Music - Music.Play; - - // Video - if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then - FFmpegTogglePause; - //SkipSmpeg(PauseTime); - - Paused := false; - end; -end; -//Pause Mod End - -constructor TScreenSing.Create; -var - I: integer; - P: integer; -begin - inherited Create; - - LoadFromTheme(Theme.Sing); - - //TimeBar - StaticTimeProgress := AddStatic(Theme.Sing.StaticTimeProgress); - TextTimeText := AddText(Theme.Sing.TextTimeText); - -// 1 player | P1 - StaticP1 := AddStatic(Theme.Sing.StaticP1); - StaticP1ScoreBG := AddStatic(Theme.Sing.StaticP1ScoreBG); - TextP1 := AddText(Theme.Sing.TextP1); - TextP1Score := AddText(Theme.Sing.TextP1Score); - StaticP1SingBar := AddStatic(Theme.Sing.StaticP1SingBar); - -// 2 or 4 players | P1 - StaticP1TwoP := AddStatic(Theme.Sing.StaticP1TwoP); - StaticP1TwoPScoreBG := AddStatic(Theme.Sing.StaticP1TwoPScoreBG); - TextP1TwoP := AddText(Theme.Sing.TextP1TwoP); - TextP1TwoPScore := AddText(Theme.Sing.TextP1TwoPScore); - StaticP1TwoPSingBar := AddStatic(Theme.Sing.StaticP2RSingBar); - - // | P2 - StaticP2R := AddStatic(Theme.Sing.StaticP2R); - StaticP2RScoreBG := AddStatic(Theme.Sing.StaticP2RScoreBG); - TextP2R := AddText(Theme.Sing.TextP2R); - TextP2RScore := AddText(Theme.Sing.TextP2RScore); - StaticP2RSingBar := AddStatic(Theme.Sing.StaticP2RSingBar); - -// 3 or 6 players | P1 - StaticP1ThreeP := AddStatic(Theme.Sing.StaticP1ThreeP); - StaticP1ThreePScoreBG := AddStatic(Theme.Sing.StaticP1ThreePScoreBG); - TextP1ThreeP := AddText(Theme.Sing.TextP1ThreeP); - TextP1ThreePScore := AddText(Theme.Sing.TextP1ThreePScore); - StaticP1ThreePSingBar := AddStatic(Theme.Sing.StaticP1ThreePSingBar); - - // | P2 - StaticP2M := AddStatic(Theme.Sing.StaticP2M); - StaticP2MScoreBG := AddStatic(Theme.Sing.StaticP2MScoreBG); - TextP2M := AddText(Theme.Sing.TextP2M); - TextP2MScore := AddText(Theme.Sing.TextP2MScore); - StaticP2MSingBar := AddStatic(Theme.Sing.StaticP2MSingBar); - - // | P3 - StaticP3R := AddStatic(Theme.Sing.StaticP3R); - StaticP3RScoreBG := AddStatic(Theme.Sing.StaticP3RScoreBG); - TextP3R := AddText(Theme.Sing.TextP3R); - TextP3RScore := AddText(Theme.Sing.TextP3RScore); - StaticP3SingBar := AddStatic(Theme.Sing.StaticP3SingBar); - - if ScreenAct = 2 then begin - // katze und affe - - end; - - LyricMain := TLyric.Create; - LyricSub := TLyric.Create; - - UVideo.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 -begin - Log.LogStatus('Begin', 'onShow'); - FadeOut := false; // 0.5.0: early 0.5.0 problems were by this line commented - - // prepare players - SetLength(Player, PlayersPlay); -// Player[0].ScoreTotalI := 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; - Static[StaticP1ScoreBG].Visible := V1; - Text[TextP1].Visible := V1; - Text[TextP1Score].Visible := V1; - - - //This one is shown in 2/4P mode - Static[StaticP1TwoP].Visible := V1TwoP; - Static[StaticP1TwoPScoreBG].Visible := V1TwoP; - Text[TextP1TwoP].Visible := V1TwoP; - Text[TextP1TwoPScore].Visible := V1TwoP; - - Static[StaticP2R].Visible := V2R; - Static[StaticP2RScoreBG].Visible := V2R; - Text[TextP2R].Visible := V2R; - Text[TextP2RScore].Visible := V2R; - - - //This one is shown in 3/6P mode - Static[StaticP1ThreeP].Visible := V1ThreeP; - Static[StaticP1ThreePScoreBG].Visible := V1ThreeP; - Text[TextP1ThreeP].Visible := V1ThreeP; - Text[TextP1ThreePScore].Visible := V1ThreeP; - - Static[StaticP2M].Visible := V2M; - Static[StaticP2MScoreBG].Visible := V2M; - Text[TextP2M].Visible := V2M; - Text[TextP2MScore].Visible := V2M; - - Static[StaticP3R].Visible := V3R; - Static[StaticP3RScoreBG].Visible := V3R; - Text[TextP3R].Visible := V3R; - Text[TextP3RScore].Visible := V3R; - - // load notes - ResetSingTemp; -// Log.LogWarning(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName, '!!!'); - AktSong := CatSongs.Song[CatSongs.Selected]; - try - if not LoadSong(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName) 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 = 1 then - ScreenSong.SelectRandomSong; - ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG')); - Exit; - end; - except - //Error Loading Song -> Go back to Song Screen and Show some Error Message - FadeTo(@ScreenSong); - //Select New Song in Party Mode - if ScreenSong.Mode = 1 then - ScreenSong.SelectRandomSong; - ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG')); - Exit; - end; - AktSong.Path := CatSongs.Song[CatSongs.Selected].Path; -// AktSong.GAP := AktSong.GAP + 40 {4096 = 100ms for buffer} + 20 {microphone} + 60000 / AktSong.BPM[0].BPM / 2; // temporary until UMain will be fixed - - // set movie - if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then begin -(* OpenSmpeg(AktSong.Path + AktSong.Video); - SkipSmpeg(AktSong.VideoGAP + AktSong.Start);*) - - // todo: VideoGap and Start time verwursten - FFmpegOpenFile(pAnsiChar(AktSong.Path + AktSong.Video)); - FFmpegSkip(AktSong.VideoGAP + AktSong.Start); - AktSong.VideoLoaded := true; - end; - - // set background - if (AktSong.Background <> '') and (AktSong.VideoLoaded = false) then - try - Tex_Background := Texture.LoadTexture(AktSong.Path + AktSong.Background); - except - log.LogError('Background could not be loaded: ' + AktSong.Path + AktSong.Background); - Tex_Background.TexNum := -1; - end - else - Tex_Background.TexNum := -1; - - - - // play music (I) - Music.CaptureStart; - Music.MoveTo(AktSong.Start); -// Music.Play; - - // prepare timer (I) -// CountSkipTimeSet; - Czas.Teraz := AktSong.Start; - Czas.Razem := Music.Length; - if (AktSong.Finish > 0) then Czas.Razem := AktSong.Finish / 1000; - Czas.OldBeat := -1; - for P := 0 to High(Player) do - ClearScores(P); - - // main text - LyricMain.Clear; - LyricMain.X := 400; - LyricMain.Y := Skin_LyricsT; - LyricMain.Scale := 1.4; //1.4 - LyricMain.Align := 1; - - // sub text - LyricSub.Clear; - LyricSub.X := 400; - LyricSub.Y := Skin_LyricsT + 35; //42 //40 - LyricSub.Align := 1; - - // set custom options - case Ini.LyricsFont of - 0: - begin - LyricMain.FontStyle := 0; - 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;1aa5dc} - 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; - end; - 2: - begin - LyricMain.FontStyle := 3; - 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 - - case Ini.LyricsEffect of - 0: LyricMain.Style := 1; // 0 - one selected, 1 - selected all to the current - 1: LyricMain.Style := 2; - 2: LyricMain.Style := 3; - 3: LyricMain.Style := 4; - end; // case - - // fill texts - LyricMain.AddCzesc(0); - LyricMain.Selected := -1; - LyricSub.AddCzesc(1); - LyricSub.Selected := -1; - - UpdateLCD; - - //Deactivate Pause - Paused := False; - - //Kill all Stars not Killed yet - //GoldenStarsTwinkle Mod - GoldenRec.SentenceChange; - //GoldenStarsTwinkle Mod End - - //Set Position of Line Bonus - PhrasenBonus - 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 - PhrasenBonus End - //Set Num of Empty Sentences for Phrasen Bonus - NumEmptySentences := 0; - for P := low(Czesci[0].Czesc) to high(Czesci[0].Czesc) do - if Czesci[0].Czesc[P].TotalNotes = 0 then Inc(NumEmptySentences); - - Log.LogStatus('End', 'onShow'); -end; - -procedure TScreenSing.onShowFinish; -begin - // play movie (II) - - if AktSong.VideoLoaded then - begin - try - FFmpegGetFrame(Czas.Teraz); - FFmpegDrawGL(ScreenAct); -// PlaySmpeg; - except - //If an Error occurs Reading Video: prevent Video from being Drawn again and Close Video - AktSong.VideoLoaded := False; - Log.LogError('Error drawing Video, Video has been disabled for this Song/Session.'); - Log.LogError('Corrupted File: ' + AktSong.Video); - try -// CloseSmpeg; - FFmpegClose; - except - - end; - end; - end; - - // play music (II) - Music.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 | den wirren Scheiss hier brauch mer nimmer, wir haben colorized png's - no need for wirrness also - // set player colors - macht nichts weiter als die farben des statics zu wechseln, was zu unschönen effekten bei colorized png führt -{ 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 - - // stereo - -// weird stuff, maybe this is for "dual screen?", but where is player three then? | okay, i commented the stuff out the other day - nothing was missing on screen w/ 6 players - so do we even need this stuff? -// okay this stuff appears again some lines beneath this one, I commented it out for testing what it does - seems like it's doing nothing -// but I might be wrong, so what is this stuff here doing? O.o - Static[StaticP1].Texture.X := Static[StaticP1].Texture.X + 10*ScreenX; - Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X + 10*ScreenX; - - Text[TextP1].X := Text[TextP1].X + 10*ScreenX; - Text[TextP1Score].X := Text[TextP1Score].X + 10*ScreenX; - - - Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X + 10*ScreenX; - Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X + 10*ScreenX; - - Text[TextP2R].X := Text[TextP2R].X + 10*ScreenX; - Text[TextP2RScore].X := Text[TextP2RScore].X + 10*ScreenX; -// end of weird stuff - - for S := 1 to 1 do //wtf? - Static[S].Texture.X := Static[S].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(Czas.Teraz) div 60; - Sec := Round(Czas.Teraz) 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) - DrawBG; - //Draw Background - SingDrawBackground; - // update and draw movie - if ShowFinish and AktSong.VideoLoaded then begin - try -// UpdateSmpeg; // this only draws - // todo: find a way to determine, when a new frame is needed - // toto: same for the need to skip frames - FFmpegGetFrame(Czas.Teraz); - FFmpegDrawGL(ScreenAct); - except - //If an Error occurs drawing: prevent Video from being Drawn again and Close Video - AktSong.VideoLoaded := False; - log.LogError('Error drawing Video, Video has been disabled for this Song/Session.'); - Log.LogError('Corrupted File: ' + AktSong.Video); - try -// CloseSmpeg; - FFmpegClose; - except - - end; - end; - end; - - // draw static menu (FG) - DrawFG; - - // check for music finish -// Log.LogError('Check for music finish: ' + BoolToStr(Music.Finished) + ' ' + FloatToStr(Czas.Teraz*1000) + ' ' + IntToStr(AktSong.Finish)); - if ShowFinish then begin - if (not Music.Finished) and ((AktSong.Finish = 0) or (Czas.Teraz*1000 <= AktSong.Finish)) then begin - //Pause Mod: - if not Paused then - Sing(Self); // analyze song - end else begin -// Log.LogError('End'); - if not FadeOut then begin -// Log.LogError('End2'); - Finish; - FadeOut := true; - FadeTo(@ScreenScore); - end; - end; - end; - - // draw custom items - SingDraw; // always draw - -//GoldenNoteStarsTwinkle Mod - GoldenRec.SpawnRec; -//GoldenNoteStarsTwinkle Mod - - // back stereo - -// weird stuff, maybe this is for "dual screen?", but where is player three then? -// okay this stuff appears again some lines above this one, I commented it out for testing what it does - seems like it's doing nothing -// but I might be wrong, so what is this stuff here doing? O.o - Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10*ScreenX; - Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X - 10*ScreenX; - - Text[TextP1].X := Text[TextP1].X - 10*ScreenX; - Text[TextP1Score].X := Text[TextP1Score].X - 10*ScreenX; - - - Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X - 10*ScreenX; - Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X - 10*ScreenX; - - Text[TextP2R].X := Text[TextP2R].X - 10*ScreenX; - Text[TextP2RScore].X := Text[TextP2RScore].X - 10*ScreenX; -//weird end - - for S := 1 to 1 do // wtf? - Static[S].Texture.X := Static[S].Texture.X - 10*ScreenX; - - for T := 0 to 1 do - Text[T].X := Text[T].X - 10*ScreenX; - -end; - -procedure TScreenSing.Finish; -begin - Music.CaptureStop; - Music.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 AktSong.VideoLoaded then begin -// CloseSmpeg; - FFmpegClose; - AktSong.VideoLoaded := false; // to prevent drawing closed video - end; - - SetFontItalic (False); -end; - -procedure TScreenSing.UpdateLCD; -var - T: string; -begin - 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(S: Cardinal); -var -I: Integer; -A: Real; -B: integer; //Max Points for Notes -begin - - //Check for Empty Sentence - if (Czesci[0].Czesc[S].TotalNotes<=0) then - exit; - - //Set Max Note Points - if (Ini.LineBonus > 0) then - B := 9000 - else - B := 10000; - - for I := 0 to High(Player) do begin - A := Player[I].Score + Player[I].ScoreGolden - Player[I].ScoreLast + 2; - - //SingBar Mod - If ({(Ini.Oscilloscope = 2) and }(Czesci[0].Czesc[S].TotalNotes>0)) then - begin - Player[I].ScorePercentTarget := Player[I].ScorePercentTarget + floor(A / (B * Czesci[0].Czesc[S].TotalNotes / Czesci[0].Wartosc) * 40 - 26); - if Player[I].ScorePercentTarget < 0 then Player[I].ScorePercentTarget := 0; - if Player[I].ScorePercentTarget > 99 then Player[I].ScorePercentTarget := 99; - - //end Singbar Mod - end; - - //PhrasenBonus - Line Bonus Mod - - //Generate Steps 0 to 8 - A := Floor(A / (B * Czesci[0].Czesc[S].TotalNotes / Czesci[0].Wartosc) * 8); - - If (Ini.LineBonus > 0) then - begin - - //Generate Text - if A >= 8 then - Player[I].LineBonus_Text := Theme.Sing.LineBonusText[8] - else - Player[I].LineBonus_Text := Theme.Sing.LineBonusText[Floor(A)]; - - //PhrasenBonus give Points - Player[I].ScoreLine := Player[I].ScoreLine + (1000 / (Length(Czesci[0].Czesc) - NumEmptySentences) * A / 8); - Player[I].ScoreLineI := Round(Player[I].ScoreLine / 10) * 10; - //Update Total Score - Player[I].ScoreTotalI := Player[I].ScoreI + Player[I].ScoreGoldenI + Player[I].ScoreLineI; - - //Color - Case Floor(A) of - 0: begin - Player[I].LineBonus_Color.R := 1; - Player[I].LineBonus_Color.G := 0; - Player[I].LineBonus_Color.B := 0; - end; - 1..3: begin - Player[I].LineBonus_Color.R := 1; - Player[I].LineBonus_Color.G := (A * 0.25); - Player[I].LineBonus_Color.B := 0; - end; - 4: begin - Player[I].LineBonus_Color.R := 1; - Player[I].LineBonus_Color.G := 1; - Player[I].LineBonus_Color.B := 0; - end; - 5..7: begin - Player[I].LineBonus_Color.R := 1-((a-4)*0.25); - Player[I].LineBonus_Color.G := 1; - Player[I].LineBonus_Color.B := 0; - end; - 8: begin - Player[I].LineBonus_Color.R := 0; - Player[I].LineBonus_Color.G := 1; - Player[I].LineBonus_Color.B := 0; - end; - End; //Case - //Player[I].LineBonus_Color.B := 0; - //Player[I].LineBonus_Color.R := (8-A)/8; - //Player[I].LineBonus_Color.G := A/10; - - Player[I].LineBonus_PosX := Player[I].LineBonus_StartX; - Player[I].LineBonus_PosY := Player[I].LineBonus_StartY; - Player[I].LineBonus_Alpha := 0.92; - Player[I].LineBonus_Visible := True; - Player[I].LineBonus_Age := 1; - end; - //PhrasenBonus - Line Bonus Mod End// } - - //PerfectLineTwinkle Mod (effect) Pt.1 - If (Ini.EffectSing=1) then - begin - if A >= 8 then Player[I].LastSentencePerfect := True - else Player[I].LastSentencePerfect := False; - end; - //PerfectLineTwinkle Mod end - - //Refresh LastScore - Player[I].ScoreLast := Player[I].Score + Player[I].ScoreGolden; - - end; - - //PerfectLineTwinkle Mod (effect) Pt.2 - if Ini.EffectSing=1 then - GoldenRec.SpawnPerfectLineTwinkle; - //PerfectLineTwinkle Mod end -end; - -//Called on Sentence Change S= New Current Sentence -procedure TScreenSing.onSentenceChange(S: Cardinal); -begin - //GoldenStarsTwinkle Mod - GoldenRec.SentenceChange; - //GoldenStarsTwinkle Mod End -end; - -end. +unit UScreenSing; + +interface + +{$I switches.inc} + +{$IFDEF FPC} + {$MODE DELPHI} +{$ENDIF} + + +uses UMenu, + UMusic, + SDL, + SysUtils, + UFiles, + UTime, + USongs, + UIni, + ULog, + UTexture, + ULyrics, + TextGL, + OpenGL12, + {$IFDEF useBASS} + bass, + {$ENDIF} + UThemes, + ULCD, + UGraphicClasses, + UVideo; + +type + TScreenSing = class(TMenu) + protected + paused: boolean; //Pause Mod + PauseTime: Real; + NumEmptySentences: integer; + public + //TextTime: integer; + + //TimeBar mod + StaticTimeProgress: integer; + TextTimeText: integer; + //eoa TimeBar mod + + StaticP1: integer; + StaticP1ScoreBG: integer; + TextP1: 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; + StaticP1TwoPScoreBG: integer; + TextP1TwoP: integer; + TextP1TwoPScore: integer; + //shown when game is in 3/6 player modus + StaticP1ThreeP: integer; + StaticP1ThreePScoreBG: integer; + TextP1ThreeP: integer; + TextP1ThreePScore: integer; + //eoa + + StaticP2R: integer; + StaticP2RScoreBG: integer; + TextP2R: integer; + TextP2RScore: integer; + + StaticP2M: integer; + StaticP2MScoreBG: integer; + TextP2M: integer; + TextP2MScore: integer; + + StaticP3R: integer; + StaticP3RScoreBG: integer; + TextP3R: integer; + TextP3RScore: integer; + + Tex_Background: TTexture; + FadeOut: boolean; +// LyricMain: TLyric; +// LyricSub: TLyric; + Lyrics: TLyricEngine; + + constructor Create; override; + procedure onShow; override; + procedure onShowFinish; override; + function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override; + function Draw: boolean; override; + procedure Finish; virtual; + procedure UpdateLCD; + procedure Pause; //Pause Mod(Toggles Pause) + + //OnSentenceEnd for LineBonus + Singbar + procedure onSentenceEnd(S: Cardinal); + //OnSentenceChange (for Golden Notes) + procedure onSentenceChange(S: Cardinal); + end; + +implementation +uses UGraphic, UDraw, UMain, 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; ScanCode: byte; PressedDown: Boolean): Boolean; +begin + Result := true; + If (PressedDown) Then + begin // Key Down + case PressedKey of + SDLK_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; + end; + + SDLK_ESCAPE, + SDLK_BACKSPACE : + begin + //Record Sound Hack: + //Sound[0].BufferLong + + Finish; + Music.PlayBack; + FadeTo(@ScreenScore); + end; + + SDLK_P://Pause Mod + begin + Pause; + 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 //Pause einschalten + begin + // pause Time + PauseTime := Czas.Teraz; + Paused := true; + + // pause Music + Music.Pause; + + // pause Video + if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then + FFmpegTogglePause; + end + else //Pause ausschalten + begin + Czas.Teraz := PauseTime; //Position of Notes + + // Position of Music + Music.MoveTo (PauseTime); + // Play Music + Music.Play; + + // Video + if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then + FFmpegTogglePause; + //SkipSmpeg(PauseTime); + + Paused := false; + end; +end; +//Pause Mod End + +constructor TScreenSing.Create; +var + I: integer; + P: integer; +begin + inherited Create; + + LoadFromTheme(Theme.Sing); + + //TimeBar + StaticTimeProgress := AddStatic(Theme.Sing.StaticTimeProgress); + TextTimeText := AddText(Theme.Sing.TextTimeText); + +// 1 player | P1 + StaticP1 := AddStatic(Theme.Sing.StaticP1); + StaticP1ScoreBG := AddStatic(Theme.Sing.StaticP1ScoreBG); + TextP1 := AddText(Theme.Sing.TextP1); + TextP1Score := AddText(Theme.Sing.TextP1Score); + StaticP1SingBar := AddStatic(Theme.Sing.StaticP1SingBar); + +// 2 or 4 players | P1 + StaticP1TwoP := AddStatic(Theme.Sing.StaticP1TwoP); + StaticP1TwoPScoreBG := AddStatic(Theme.Sing.StaticP1TwoPScoreBG); + TextP1TwoP := AddText(Theme.Sing.TextP1TwoP); + TextP1TwoPScore := AddText(Theme.Sing.TextP1TwoPScore); + StaticP1TwoPSingBar := AddStatic(Theme.Sing.StaticP2RSingBar); + + // | P2 + StaticP2R := AddStatic(Theme.Sing.StaticP2R); + StaticP2RScoreBG := AddStatic(Theme.Sing.StaticP2RScoreBG); + TextP2R := AddText(Theme.Sing.TextP2R); + TextP2RScore := AddText(Theme.Sing.TextP2RScore); + StaticP2RSingBar := AddStatic(Theme.Sing.StaticP2RSingBar); + +// 3 or 6 players | P1 + StaticP1ThreeP := AddStatic(Theme.Sing.StaticP1ThreeP); + StaticP1ThreePScoreBG := AddStatic(Theme.Sing.StaticP1ThreePScoreBG); + TextP1ThreeP := AddText(Theme.Sing.TextP1ThreeP); + TextP1ThreePScore := AddText(Theme.Sing.TextP1ThreePScore); + StaticP1ThreePSingBar := AddStatic(Theme.Sing.StaticP1ThreePSingBar); + + // | P2 + StaticP2M := AddStatic(Theme.Sing.StaticP2M); + StaticP2MScoreBG := AddStatic(Theme.Sing.StaticP2MScoreBG); + TextP2M := AddText(Theme.Sing.TextP2M); + TextP2MScore := AddText(Theme.Sing.TextP2MScore); + StaticP2MSingBar := AddStatic(Theme.Sing.StaticP2MSingBar); + + // | P3 + StaticP3R := AddStatic(Theme.Sing.StaticP3R); + StaticP3RScoreBG := AddStatic(Theme.Sing.StaticP3RScoreBG); + TextP3R := AddText(Theme.Sing.TextP3R); + TextP3RScore := AddText(Theme.Sing.TextP3RScore); + StaticP3SingBar := AddStatic(Theme.Sing.StaticP3SingBar); + + if ScreenAct = 2 then begin + // katze und affe + + end; + + Lyrics := TLyricEngine.Create(80,Skin_LyricsT,640,12,80,Skin_LyricsT+36,640,12); + + UVideo.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 +begin + Log.LogStatus('Begin', 'onShow'); + FadeOut := false; // 0.5.0: early 0.5.0 problems were by this line commented + + // prepare players + SetLength(Player, PlayersPlay); +// Player[0].ScoreTotalI := 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; + Static[StaticP1ScoreBG].Visible := V1; + Text[TextP1].Visible := V1; + Text[TextP1Score].Visible := V1; + + + //This one is shown in 2/4P mode + Static[StaticP1TwoP].Visible := V1TwoP; + Static[StaticP1TwoPScoreBG].Visible := V1TwoP; + Text[TextP1TwoP].Visible := V1TwoP; + Text[TextP1TwoPScore].Visible := V1TwoP; + + Static[StaticP2R].Visible := V2R; + Static[StaticP2RScoreBG].Visible := V2R; + Text[TextP2R].Visible := V2R; + Text[TextP2RScore].Visible := V2R; + + + //This one is shown in 3/6P mode + Static[StaticP1ThreeP].Visible := V1ThreeP; + Static[StaticP1ThreePScoreBG].Visible := V1ThreeP; + Text[TextP1ThreeP].Visible := V1ThreeP; + Text[TextP1ThreePScore].Visible := V1ThreeP; + + Static[StaticP2M].Visible := V2M; + Static[StaticP2MScoreBG].Visible := V2M; + Text[TextP2M].Visible := V2M; + Text[TextP2MScore].Visible := V2M; + + Static[StaticP3R].Visible := V3R; + Static[StaticP3RScoreBG].Visible := V3R; + Text[TextP3R].Visible := V3R; + Text[TextP3RScore].Visible := V3R; + + // load notes + ResetSingTemp; +// Log.LogWarning(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName, '!!!'); + AktSong := CatSongs.Song[CatSongs.Selected]; + try + if not LoadSong(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName) 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 = 1 then + ScreenSong.SelectRandomSong; + ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG')); + Exit; + end; + except + //Error Loading Song -> Go back to Song Screen and Show some Error Message + FadeTo(@ScreenSong); + //Select New Song in Party Mode + if ScreenSong.Mode = 1 then + ScreenSong.SelectRandomSong; + ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG')); + Exit; + end; + AktSong.Path := CatSongs.Song[CatSongs.Selected].Path; +// AktSong.GAP := AktSong.GAP + 40 {4096 = 100ms for buffer} + 20 {microphone} + 60000 / AktSong.BPM[0].BPM / 2; // temporary until UMain will be fixed + + // set movie + if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then begin +(* OpenSmpeg(AktSong.Path + AktSong.Video); + SkipSmpeg(AktSong.VideoGAP + AktSong.Start);*) + + // todo: VideoGap and Start time verwursten + FFmpegOpenFile(pAnsiChar(AktSong.Path + AktSong.Video)); + FFmpegSkip(AktSong.VideoGAP + AktSong.Start); + AktSong.VideoLoaded := true; + end; + + // set background + if (AktSong.Background <> '') and (AktSong.VideoLoaded = false) then + try + Tex_Background := Texture.LoadTexture(AktSong.Path + AktSong.Background); + except + log.LogError('Background could not be loaded: ' + AktSong.Path + AktSong.Background); + Tex_Background.TexNum := -1; + end + else + Tex_Background.TexNum := -1; + + + + // play music (I) + Music.CaptureStart; + Music.MoveTo(AktSong.Start); +// Music.Play; + + // prepare timer (I) +// CountSkipTimeSet; + Czas.Teraz := AktSong.Start; + Czas.Razem := Music.Length; + if (AktSong.Finish > 0) then Czas.Razem := AktSong.Finish / 1000; + Czas.OldBeat := -1; + for P := 0 to High(Player) do + ClearScores(P); + + // main text + Lyrics.Clear (AktSong.BPM[0].BPM, AktSong.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_akt.R := 5/256; + Lyrics.LineColor_akt.G := 163/256; + Lyrics.LineColor_akt.B := 210/256; + Lyrics.LineColor_akt.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;1aa5dc}{ + 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_akt.R := 0.5; + Lyrics.LineColor_akt.G := 0.5; + Lyrics.LineColor_akt.B := 1; + Lyrics.LineColor_akt.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_akt.R := 0.5; + Lyrics.LineColor_akt.G := 0.5; + Lyrics.LineColor_akt.B := 1; + Lyrics.LineColor_akt.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 + + case Ini.LyricsEffect of + 0: Lyrics.HoverEffekt := 1; // 0 - one selected, 1 - selected all to the current + 1: Lyrics.HoverEffekt := 2; + 2: Lyrics.HoverEffekt := 3; + 3: Lyrics.HoverEffekt := 4; + end; // case + + // Add Lines to Lyrics + While (not Lyrics.LineinQueue) AND (Lyrics.LineCounter <= High(Czesci[0].Czesc)) do + Lyrics.AddLine(@Czesci[0].Czesc[Lyrics.LineCounter]); + + UpdateLCD; + + //Deactivate Pause + Paused := False; + + //Kill all Stars not Killed yet + //GoldenStarsTwinkle Mod + GoldenRec.SentenceChange; + //GoldenStarsTwinkle Mod End + + //Set Position of Line Bonus - PhrasenBonus + 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 - PhrasenBonus End + //Set Num of Empty Sentences for Phrasen Bonus + NumEmptySentences := 0; + for P := low(Czesci[0].Czesc) to high(Czesci[0].Czesc) do + if Czesci[0].Czesc[P].TotalNotes = 0 then Inc(NumEmptySentences); + + Log.LogStatus('End', 'onShow'); +end; + +procedure TScreenSing.onShowFinish; +begin + // play movie (II) + + if AktSong.VideoLoaded then + begin + try + FFmpegGetFrame(Czas.Teraz); + FFmpegDrawGL(ScreenAct); +// PlaySmpeg; + except + //If an Error occurs Reading Video: prevent Video from being Drawn again and Close Video + AktSong.VideoLoaded := False; + Log.LogError('Error drawing Video, Video has been disabled for this Song/Session.'); + Log.LogError('Corrupted File: ' + AktSong.Video); + try +// CloseSmpeg; + FFmpegClose; + except + + end; + end; + end; + + // play music (II) + Music.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 | den wirren Scheiss hier brauch mer nimmer, wir haben colorized png's - no need for wirrness also + // set player colors - macht nichts weiter als die farben des statics zu wechseln, was zu unschönen effekten bei colorized png führt +{ 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 + + // stereo + +// weird stuff, maybe this is for "dual screen?", but where is player three then? | okay, i commented the stuff out the other day - nothing was missing on screen w/ 6 players - so do we even need this stuff? +// okay this stuff appears again some lines beneath this one, I commented it out for testing what it does - seems like it's doing nothing +// but I might be wrong, so what is this stuff here doing? O.o + Static[StaticP1].Texture.X := Static[StaticP1].Texture.X + 10*ScreenX; + Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X + 10*ScreenX; + + Text[TextP1].X := Text[TextP1].X + 10*ScreenX; + Text[TextP1Score].X := Text[TextP1Score].X + 10*ScreenX; + + + Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X + 10*ScreenX; + Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X + 10*ScreenX; + + Text[TextP2R].X := Text[TextP2R].X + 10*ScreenX; + Text[TextP2RScore].X := Text[TextP2RScore].X + 10*ScreenX; +// end of weird stuff + + for S := 1 to 1 do //wtf? + Static[S].Texture.X := Static[S].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(Czas.Teraz) div 60; + Sec := Round(Czas.Teraz) 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) + DrawBG; + //Draw Background + SingDrawBackground; + // update and draw movie + if ShowFinish and AktSong.VideoLoaded then begin + try +// UpdateSmpeg; // this only draws + // todo: find a way to determine, when a new frame is needed + // toto: same for the need to skip frames + FFmpegGetFrame(Czas.Teraz); + FFmpegDrawGL(ScreenAct); + except + //If an Error occurs drawing: prevent Video from being Drawn again and Close Video + AktSong.VideoLoaded := False; + log.LogError('Error drawing Video, Video has been disabled for this Song/Session.'); + Log.LogError('Corrupted File: ' + AktSong.Video); + try +// CloseSmpeg; + FFmpegClose; + except + + end; + end; + end; + + // draw static menu (FG) + DrawFG; + + // check for music finish +// Log.LogError('Check for music finish: ' + BoolToStr(Music.Finished) + ' ' + FloatToStr(Czas.Teraz*1000) + ' ' + IntToStr(AktSong.Finish)); + if ShowFinish then begin + if (not Music.Finished) and ((AktSong.Finish = 0) or (Czas.Teraz*1000 <= AktSong.Finish)) then begin + //Pause Mod: + if not Paused then + Sing(Self); // analyze song + end else begin +// Log.LogError('End'); + if not FadeOut then begin +// Log.LogError('End2'); + Finish; + FadeOut := true; + FadeTo(@ScreenScore); + end; + end; + end; + + // draw custom items + SingDraw; // always draw + +//GoldenNoteStarsTwinkle Mod + GoldenRec.SpawnRec; +//GoldenNoteStarsTwinkle Mod + + // back stereo + +// weird stuff, maybe this is for "dual screen?", but where is player three then? +// okay this stuff appears again some lines above this one, I commented it out for testing what it does - seems like it's doing nothing +// but I might be wrong, so what is this stuff here doing? O.o + Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10*ScreenX; + Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X - 10*ScreenX; + + Text[TextP1].X := Text[TextP1].X - 10*ScreenX; + Text[TextP1Score].X := Text[TextP1Score].X - 10*ScreenX; + + + Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X - 10*ScreenX; + Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X - 10*ScreenX; + + Text[TextP2R].X := Text[TextP2R].X - 10*ScreenX; + Text[TextP2RScore].X := Text[TextP2RScore].X - 10*ScreenX; +//weird end + + for S := 1 to 1 do // wtf? + Static[S].Texture.X := Static[S].Texture.X - 10*ScreenX; + + for T := 0 to 1 do + Text[T].X := Text[T].X - 10*ScreenX; + +end; + +procedure TScreenSing.Finish; +begin + Music.CaptureStop; + Music.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 AktSong.VideoLoaded then begin +// CloseSmpeg; + FFmpegClose; + AktSong.VideoLoaded := false; // to prevent drawing closed video + end; + + SetFontItalic (False); +end; + +procedure TScreenSing.UpdateLCD; +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(S: Cardinal); +var +I: Integer; +A: Real; +B: integer; //Max Points for Notes +begin + + //Check for Empty Sentence + if (Czesci[0].Czesc[S].TotalNotes<=0) then + exit; + + //Set Max Note Points + if (Ini.LineBonus > 0) then + B := 9000 + else + B := 10000; + + for I := 0 to High(Player) do begin + A := Player[I].Score + Player[I].ScoreGolden - Player[I].ScoreLast + 2; + + //SingBar Mod + If ({(Ini.Oscilloscope = 2) and }(Czesci[0].Czesc[S].TotalNotes>0)) then + begin + Player[I].ScorePercentTarget := Player[I].ScorePercentTarget + floor(A / (B * Czesci[0].Czesc[S].TotalNotes / Czesci[0].Wartosc) * 40 - 26); + if Player[I].ScorePercentTarget < 0 then Player[I].ScorePercentTarget := 0; + if Player[I].ScorePercentTarget > 99 then Player[I].ScorePercentTarget := 99; + + //end Singbar Mod + end; + + //PhrasenBonus - Line Bonus Mod + + //Generate Steps 0 to 8 + A := Floor(A / (B * Czesci[0].Czesc[S].TotalNotes / Czesci[0].Wartosc) * 8); + + If (Ini.LineBonus > 0) then + begin + + //Generate Text + if A >= 8 then + Player[I].LineBonus_Text := Theme.Sing.LineBonusText[8] + else + Player[I].LineBonus_Text := Theme.Sing.LineBonusText[Floor(A)]; + + //PhrasenBonus give Points + Player[I].ScoreLine := Player[I].ScoreLine + (1000 / (Length(Czesci[0].Czesc) - NumEmptySentences) * A / 8); + Player[I].ScoreLineI := Round(Player[I].ScoreLine / 10) * 10; + //Update Total Score + Player[I].ScoreTotalI := Player[I].ScoreI + Player[I].ScoreGoldenI + Player[I].ScoreLineI; + + //Color + Case Floor(A) of + 0: begin + Player[I].LineBonus_Color.R := 1; + Player[I].LineBonus_Color.G := 0; + Player[I].LineBonus_Color.B := 0; + end; + 1..3: begin + Player[I].LineBonus_Color.R := 1; + Player[I].LineBonus_Color.G := (A * 0.25); + Player[I].LineBonus_Color.B := 0; + end; + 4: begin + Player[I].LineBonus_Color.R := 1; + Player[I].LineBonus_Color.G := 1; + Player[I].LineBonus_Color.B := 0; + end; + 5..7: begin + Player[I].LineBonus_Color.R := 1-((a-4)*0.25); + Player[I].LineBonus_Color.G := 1; + Player[I].LineBonus_Color.B := 0; + end; + 8: begin + Player[I].LineBonus_Color.R := 0; + Player[I].LineBonus_Color.G := 1; + Player[I].LineBonus_Color.B := 0; + end; + End; //Case + //Player[I].LineBonus_Color.B := 0; + //Player[I].LineBonus_Color.R := (8-A)/8; + //Player[I].LineBonus_Color.G := A/10; + + Player[I].LineBonus_PosX := Player[I].LineBonus_StartX; + Player[I].LineBonus_PosY := Player[I].LineBonus_StartY; + Player[I].LineBonus_Alpha := 0.92; + Player[I].LineBonus_Visible := True; + Player[I].LineBonus_Age := 1; + end; + //PhrasenBonus - Line Bonus Mod End// } + + //PerfectLineTwinkle Mod (effect) Pt.1 + If (Ini.EffectSing=1) then + begin + if A >= 8 then Player[I].LastSentencePerfect := True + else Player[I].LastSentencePerfect := False; + end; + //PerfectLineTwinkle Mod end + + //Refresh LastScore + Player[I].ScoreLast := Player[I].Score + Player[I].ScoreGolden; + + end; + + //PerfectLineTwinkle Mod (effect) Pt.2 + if Ini.EffectSing=1 then + GoldenRec.SpawnPerfectLineTwinkle; + //PerfectLineTwinkle Mod end +end; + +//Called on Sentence Change S= New Current Sentence +procedure TScreenSing.onSentenceChange(S: Cardinal); +begin + //GoldenStarsTwinkle Mod + GoldenRec.SentenceChange; + if (Lyrics.LineCounter <= High(Czesci[0].Czesc)) then + Lyrics.AddLine(@Czesci[0].Czesc[Lyrics.LineCounter]); + //GoldenStarsTwinkle Mod End +end; + +end. diff --git a/Game/Code/UltraStar.dpr b/Game/Code/UltraStar.dpr index 474bf173..65109055 100644 --- a/Game/Code/UltraStar.dpr +++ b/Game/Code/UltraStar.dpr @@ -6,46 +6,28 @@ program UltraStar; {$I switches.inc} uses - //------------------------------ - //Includes - 3rd Party Libraries - //------------------------------ - SDL in 'lib\JEDI-SDLv1.0\SDL\Pas\SDL.pas', - OpenGL12 in 'lib\JEDI-SDLv1.0\OpenGL\Pas\OpenGL12.pas', - - bass in 'lib\bass\delphi\bass.pas', - - PNGImage in 'lib\PNGImage\PNGImage.pas', - PNGzLib in 'lib\PNGImage\PNGzLib.pas', - pnglang in 'lib\PNGImage\pnglang.pas', - - midiout in 'lib\midi\midiout.pas', - midiin in 'lib\midi\midiin.pas', - Circbuf in 'lib\midi\CIRCBUF.PAS', - MidiType in 'lib\midi\MidiType.PAS', - MidiDefs in 'lib\midi\MidiDefs.PAS', - MidiCons in 'lib\midi\MidiCons.PAS', - MidiFile in 'lib\midi\MidiFile.PAS', - Delphmcb in 'lib\midi\Delphmcb.PAS', - - {$IFDEF UseSerialPort} - zlportio in 'lib\zlportio\zlportio.pas', - ddkint in 'lib\zlportio\ddkint.pas', - {$ENDIF} - - avcodec in 'lib\ffmpeg\avcodec.pas', - avformat in 'lib\ffmpeg\avformat.pas', - avutil in 'lib\ffmpeg\avutil.pas', - rational in 'lib\ffmpeg\rational.pas', - opt in 'lib\ffmpeg\opt.pas', - avio in 'lib\ffmpeg\avio.pas', - + SDL in 'lib\JEDI-SDLv1.0\SDL\Pas\SDL.pas', + OpenGL12 in 'lib\JEDI-SDLv1.0\OpenGL\Pas\OpenGL12.pas', + bass in 'lib\bass\delphi\bass.pas', + PNGImage in 'lib\PNGImage\PNGImage.pas', + PNGzLib in 'lib\PNGImage\PNGzLib.pas', + pnglang in 'lib\PNGImage\pnglang.pas', + midiout in 'lib\midi\midiout.pas', + midiin in 'lib\midi\midiin.pas', + CIRCBUF in 'lib\midi\CIRCBUF.PAS', + MidiType in 'lib\midi\MidiType.PAS', + MidiDefs in 'lib\midi\MidiDefs.PAS', + MidiCons in 'lib\midi\MidiCons.PAS', + MidiFile in 'lib\midi\MidiFile.PAS', + Delphmcb in 'lib\midi\Delphmcb.PAS', + avcodec in 'lib\ffmpeg\avcodec.pas', + avformat in 'lib\ffmpeg\avformat.pas', + avutil in 'lib\ffmpeg\avutil.pas', + rational in 'lib\ffmpeg\rational.pas', + opt in 'lib\ffmpeg\opt.pas', + avio in 'lib\ffmpeg\avio.pas', SQLiteTable3 in 'lib\SQLite\SQLiteTable3.pas', - SQLite3 in 'lib\SQLite\SQLite3.pas', - - - //------------------------------ - //Includes - Menu System - //------------------------------ + SQLite3 in 'lib\SQLite\SQLite3.pas', UDisplay in 'Menu\UDisplay.pas', UMenu in 'Menu\UMenu.pas', UMenuStatic in 'Menu\UMenuStatic.pas', @@ -56,11 +38,7 @@ uses UMenuSelectSlide in 'Menu\UMenuSelectSlide.pas', UDrawTexture in 'Menu\UDrawTexture.pas', UMenuButtonCollection in 'Menu\UMenuButtonCollection.pas', - - //------------------------------ - //Includes - Classes - //------------------------------ - UCommon in 'Classes\UCommon.pas', + UCommon in 'Classes\UCommon.pas', UGraphic in 'Classes\UGraphic.pas', UTexture in 'Classes\UTexture.pas', UMusic in 'Classes\UMusic.pas', @@ -87,16 +65,8 @@ uses UDLLManager in 'Classes\UDLLManager.pas', UParty in 'Classes\UParty.pas', UPlaylist in 'Classes\UPlaylist.pas', - UCommandLine in 'Classes\UCommandLine.pas', - - //------------------------------ - //Includes - Video Support - //------------------------------ + UCommandLine in 'Classes\UCommandLine.pas', UVideo in 'Classes\UVideo.pas', - - //------------------------------ - //Includes - Screens - //------------------------------ UScreenLoading in 'Screens\UScreenLoading.pas', UScreenWelcome in 'Screens\UScreenWelcome.pas', UScreenMain in 'Screens\UScreenMain.pas', @@ -125,27 +95,16 @@ uses UScreenStatDetail in 'Screens\UScreenStatDetail.pas', UScreenCredits in 'Screens\UScreenCredits.pas', UScreenPopup in 'Screens\UScreenPopup.pas', - - //------------------------------ - //Includes - Screens PartyMode - //------------------------------ UScreenSingModi in 'Screens\UScreenSingModi.pas', UScreenPartyNewRound in 'Screens\UScreenPartyNewRound.pas', UScreenPartyScore in 'Screens\UScreenPartyScore.pas', UScreenPartyPlayer in 'Screens\UScreenPartyPlayer.pas', UScreenPartyOptions in 'Screens\UScreenPartyOptions.pas', UScreenPartyWin in 'Screens\UScreenPartyWin.pas', - - //------------------------------ - //Includes - Modi SDK - //------------------------------ ModiSDK in '..\..\Modis\SDK\ModiSDK.pas', - - //------------------------------ - //Includes - Delphi - //------------------------------ Windows, - SysUtils; + SysUtils, + ULyrics.bak in 'Classes\ULyrics.bak.pas'; const Version = 'UltraStar Deluxe V 1.10 Alpha Build'; @@ -357,6 +316,7 @@ begin Log.BenchmarkEnd(0); Log.LogBenchmark('Loading Time', 0); + Lyric := TLyric.Create; //------------------------------ //Start- Mainloop -- cgit v1.2.3