From 9e20b144baa4591e9f384742cb90e40e79b315e6 Mon Sep 17 00:00:00 2001 From: brunzelchen Date: Fri, 4 Jun 2010 20:46:56 +0000 Subject: - switched SDL.dll back to v1.2.12, the 1.2.14 has too much bugs - added duet support. duet song format based on hawkears duet mod for the 1.1 alpha git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/1.0.1 Challenge MOD@2440 b956fd51-792f-4845-bead-9b4dfca2ff2c --- Game/Code/Classes/UDraw.pas | 880 +++++++++++++++++++++++----------------- Game/Code/Classes/UFiles.pas | 481 ++++++++++++++-------- Game/Code/Classes/UGraphic.pas | 3 +- Game/Code/Classes/ULyrics.pas | 27 +- Game/Code/Classes/UMain.pas | 555 ++++++++++++++++--------- Game/Code/Classes/UMusic.pas | 47 ++- Game/Code/Classes/UPlaylist.pas | 5 +- Game/Code/Classes/USongs.pas | 108 ++++- Game/Code/Classes/UThemes.pas | 10 + Game/Code/Classes/UVideo.pas | 1 + 10 files changed, 1345 insertions(+), 772 deletions(-) (limited to 'Game/Code/Classes') diff --git a/Game/Code/Classes/UDraw.pas b/Game/Code/Classes/UDraw.pas index 5a646cc0..fece85fc 100644 --- a/Game/Code/Classes/UDraw.pas +++ b/Game/Code/Classes/UDraw.pas @@ -3,14 +3,33 @@ unit UDraw; interface uses UThemes, ModiSDK, UGraphicClasses; +type + TRecR = record + Top: real; + Left: real; + Right: real; + Bottom: real; + + Width: real; + WMid: real; + Height: real; + HMid: real; + + Mid: real; + end; + procedure SingDraw; +procedure SingDrawLyricHelper(CP: integer; NR: TRecR); +procedure SingDrawNotes(NR: TRecR); +procedure SingDrawNotesDuet(NR: TRecR); 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 SingDrawPlayerCzesc(X, Y, W: real; CP, NrGracza: integer; Space: integer); procedure SingDrawPlayerBGCzesc(Left, Top, Right: real; NrCzesci, NrGracza: integer; Space: integer); // TimeBar mod @@ -33,22 +52,6 @@ procedure EditDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: intege //Draw Volume Bar procedure DrawVolumeBar(x, y, w, h: Real; Volume: 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; @@ -205,17 +208,42 @@ procedure SingDrawBeatDelimeters(Left, Top, Right: real; NrCzesci: integer); var Pet: integer; TempR: real; + CP: integer; + end_: integer; + st: integer; begin - TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote); + CP := NrCzesci; + if (Length(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta)=0) then + begin + CP := (CP+1) mod 2; + st := Czesci[CP].Czesc[Czesci[CP].Akt].StartNote; + end_ := Czesci[CP].Czesc[Czesci[CP].Akt].Koniec; + end else + begin + st := Czesci[CP].Czesc[Czesci[CP].Akt].StartNote; + end_ := Czesci[CP].Czesc[Czesci[CP].Akt].Koniec; + if AktSong.isDuet and (Length(Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].Nuta)>0)then + begin + if (Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].Koniec > end_) then + end_ := Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].Koniec; + + if (Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].StartNote < st) then + st := Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].StartNote; + end; + end; + + TempR := (Right-Left) / (end_ - st); + 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 + for Pet := st to end_ do + begin + if (Pet mod Czesci[CP].Resolution) = Czesci[CP].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); + glVertex2f(Left + TempR * (Pet - st), Top); + glVertex2f(Left + TempR * (Pet - st), Top + 135); end; glEnd; glDisable(GL_BLEND); @@ -229,18 +257,41 @@ var TempR: real; GoldenStarPos : real; + CP: integer; + end_: integer; + st: integer; begin + CP := NrCzesci; + if (Length(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta)=0) then + Exit + else + begin + st := Czesci[CP].Czesc[Czesci[CP].Akt].StartNote; + end_ := Czesci[CP].Czesc[Czesci[CP].Akt].Koniec; + if AktSong.isDuet and (Length(Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].Nuta)>0)then + begin + if (Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].Koniec > end_) then + end_ := Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].Koniec; + + if (Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].StartNote < st) then + st := Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].StartNote; + end; + end; + 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 - + TempR := (Right-Left) / (end_ - st); + 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 @@ -253,7 +304,7 @@ begin glColor4f(1, 1, 1, 0.85); // lewa czesc - left part - Rec.Left := (Start-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left + 0.5 + 10*ScreenX; + Rec.Left := (Start-st) * 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; @@ -266,33 +317,32 @@ begin glEnd; //We keep the postion of the top left corner b4 it's overwritten - GoldenStarPos := Rec.Left; + 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; + Rec.Left := Rec.Right; + Rec.Right := (Start+Dlugosc-st) * 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; + 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; + // 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; + 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; // Golden Star Patch if (Wartosc = 2) AND (Ini.EffectSing=1) then @@ -311,47 +361,57 @@ end; // draw sung notes -procedure SingDrawPlayerCzesc(X, Y, W: real; NrGracza: integer; Space: integer); +procedure SingDrawPlayerCzesc(X, Y, W: real; CP, NrGracza: integer; Space: integer); var TempR: real; Rec: TRecR; N: integer; NotesH2: real; + end_: integer; + st: integer; +begin + if (Length(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta)=0) then + Exit + else 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; + st := Czesci[CP].Czesc[Czesci[CP].Akt].StartNote; + end_ := Czesci[CP].Czesc[Czesci[CP].Akt].Koniec; + if AktSong.isDuet and (Length(Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].Nuta)>0)then + begin + if (Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].Koniec > end_) then + end_ := Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].Koniec; + if (Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].StartNote < st) then + st := Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].StartNote; + end; + end; 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 + if Player[NrGracza].IlNut > 0 then + begin + TempR := W / (end_ - st); + for N := 0 to Player[NrGracza].HighNut do + begin + with Player[NrGracza].Nuta[N] do + begin // lewa czesc - Rec.Left := X + (Start-Czesci[0].Czesc[Czesci[0].Akt].StartNote) * TempR + 0.5 + 10*ScreenX; + Rec.Left := X + (Start-st) * TempR + 0.5 + 10*ScreenX; Rec.Right := Rec.Left + NotesW; - - // Half size Notes Patch - if Hit then begin - NotesH2 := NotesH - end else begin - NotesH2 := int(NotesH * 0.65); - end; //if - - + // Half size Notes Patch + if Hit then + begin + NotesH2 := NotesH + end else + begin + NotesH2 := int(NotesH * 0.65); + end; //if // if True then - Rec.Top := Y - (Ton-Czesci[0].Czesc[Czesci[0].Akt].BaseNote)*Space/2 - NotesH2; + Rec.Top := Y - (Ton-Czesci[CP].Czesc[Czesci[0].Akt].BaseNote)*Space/2 - NotesH2; Rec.Bottom := Rec.Top + 2 *NotesH2; glColor3f(1, 1, 1); @@ -365,7 +425,7 @@ var // srodkowa czesc Rec.Left := Rec.Right; - Rec.Right := X + (Start+Dlugosc-Czesci[0].Czesc[Czesci[0].Akt].StartNote) * TempR - NotesW - 0.5 + 10*ScreenX; + Rec.Right := X + (Start+Dlugosc-st) * TempR - NotesW - 0.5 + 10*ScreenX; // (nowe) if (Start+Dlugosc-1 = Czas.AktBeatD) then Rec.Right := Rec.Right - (1-Frac(Czas.MidBeatD)) * TempR; @@ -411,38 +471,6 @@ var GoldenRec.SavePerfectNotePos(Rec.Left, Rec.Top); { SingDrawStar(Rec.Left+2, Rec.Top+4, A);} end; - - // detekt -{ Rec.Left := Round((Detekt-Czesci.Czesc[Czesci.Akt].Start) * TempR) + 130; - glColor3f(1, 0.2, 0.2); - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); - glBegin(GL_QUADS); - glVertex(Rec.Left, Rec.Top-5); - glVertex(Rec.Left, Rec.Bottom+5); - glVertex(Rec.Left+1, Rec.Bottom+5); - glVertex(Rec.Left+1, Rec.Top-5); - glEnd; - glColor3f(1, 1, 1); - glEnable(GL_BLEND); - glEnable(GL_TEXTURE_2D);} - - // detekt + FFT length -{ Rec.Right := (Detekt-Czesci.Czesc[Czesci.Akt].Start) * TempR + 130; - // TempR = dlugosc 1 kostki - // 60 * 4 / BPM = czas w sekundach na 1 kostke, np. 0,4s - // 4096 / 44100 = czas jednego sampla FFT, np. 0,1s - // ile to ma kostek? np. 0.25 - // (4096 / 44100) / (60 * 4 / BPM), np. 0,1s / 0,4s = 0.25 - // * TempR = dlugosc sampla FFT - Rec.Left := Rec.Right - (Sound.n / 44100) / (60 * 4 / Muzyka.BPM) * TempR; - - glColor3f(1, 0.2, 0.2); - glVertex(Rec.Left, Rec.Top-4); - glVertex(Rec.Left, Rec.Bottom+4); - glVertex(Rec.Right, Rec.Bottom+4); - glVertex(Rec.Right, Rec.Top-4);} - end; // with end; // for // eigentlich brauchen wir hier einen vergleich, um festzustellen, ob wir mit @@ -452,7 +480,7 @@ var // some kind of weird index into a colour-table if (Ini.EffectSing=1) then - GoldenRec.GoldenNoteTwinkle(Rec.Top,Rec.Bottom,Rec.Right, NrGracza); + GoldenRec.GoldenNoteTwinkle(Rec.Top,Rec.Bottom,Rec.Right, NrGracza); end; // if end; @@ -464,135 +492,151 @@ var TempR: real; X1, X2, X3, X4: real; W, H: real; + CP: integer; + end_: integer; + st: integer; 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; + if (Player[NrGracza].ScoreTotalI >= 0) then + begin + CP := NrCzesci; + if (Length(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta)=0) then + begin + CP := (CP+1) mod 2; + st := Czesci[CP].Czesc[Czesci[CP].Akt].StartNote; + end_ := Czesci[CP].Czesc[Czesci[CP].Akt].Koniec; + end else + begin + st := Czesci[CP].Czesc[Czesci[CP].Akt].StartNote; + end_ := Czesci[CP].Czesc[Czesci[CP].Akt].Koniec; + if AktSong.isDuet and (Length(Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].Nuta)>0)then + begin + if (Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].Koniec > end_) then + end_ := Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].Koniec; - // prawa czesc - Rec.Left := X3; - Rec.Right := X4; + if (Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].StartNote < st) then + st := Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].StartNote; + end; + end; - 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 + 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) / (end_ - st); + 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-st) * TempR + Left + 0.5 + 10*ScreenX + 4; // wciecie + X1 := X2-W; + + X3 := (Start+Dlugosc-st) * 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); + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); end; end; -{not used anymore tough we have UGraphicClasses -procedure SingDrawStar(X, Y, A: real); +procedure SingDrawLyricHelper(CP: integer; NR: TRecR); var - TempR: real; - W, H: real; - Starframe: real; - begin - W := 32; - H := 32; - -// Golden Star Patch -// case Z of -// 1: glColor4f(1, 1, 1, A); -// 2: glColor4f(1, 1, 0.3, A); -// end; // case - - glColor4f(1, 1, 1, A); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBindTexture(GL_TEXTURE_2D, Tex_Note_Star.TexNum); + BarFrom: integer; + BarWspol: real; + Rec: TRecR; - Starframe := 15 - ((GetTickCount div 33) mod 16); +begin + if (Length(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta)=0) then + Exit; + //TODO: apply duet special... ? + + BarFrom := Czesci[CP].Czesc[Czesci[CP].Akt].StartNote - Czesci[CP].Czesc[Czesci[CP].Akt].Start; + if BarFrom > 40 then + BarFrom := 40; + + if (Czesci[CP].Czesc[Czesci[CP].Akt].StartNote - Czesci[CP].Czesc[Czesci[CP].Akt].Start > 8) and //16->12 for more help bars and then 12->8 for even more + (Czesci[CP].Czesc[Czesci[CP].Akt].StartNote - Czas.MidBeat > 0) and + (Czesci[CP].Czesc[Czesci[CP].Akt].StartNote - Czas.MidBeat < 40) then + begin // ale nie za wczesnie + BarWspol := (Czas.MidBeat - (Czesci[CP].Czesc[Czesci[CP].Akt].StartNote - BarFrom)) / BarFrom; + Rec.Left := NR.Left + BarWspol*(ScreenSing.LyricMain[CP].ClientX - NR.Left - 50) + 10*ScreenX; + Rec.Right := Rec.Left + 50; + Rec.Top := Skin_LyricsT + 3; + if AktSong.isDuet and (CP=1) then + Rec.Top := Skin_LyricsT + 3 + else if AktSong.isDuet and (CP=0) then + Rec.Top := 5+3; - glBegin(GL_QUADS); - glTexCoord2f((1/16) * Starframe, 0); glVertex2f(X-W, Y-H); - glTexCoord2f((1/16) * Starframe + (1/16), 0); glVertex2f(X-W, Y+H); - glTexCoord2f((1/16) * Starframe + (1/16), 1); glVertex2f(X+W, Y+H); - glTexCoord2f((1/16) * Starframe, 1); glVertex2f(X+W, Y-H); - glEnd; -end; -} + Rec.Bottom := Rec.Top + 33; -{not used anymore tough we have UGraphicClasses -procedure SingGoldenStar(X, Y, A: real); -var - TempR: real; - W, H: real; - StarfrG2: real; - begin - W := 16; - H := 16; - glColor4f(1, 1, 0.3, A); - glEnable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBindTexture(GL_TEXTURE_2D, Tex_Note_Star.TexNum); - StarfrG2 := 15 - ((GetTickCount div 67) mod 16); - glBegin(GL_QUADS); - //x1 - glTexCoord2f((1/16) * StarfrG2, 0); glVertex2f(X-W, Y-H); - glTexCoord2f((1/16) * StarfrG2 + (1/16), 0); glVertex2f(X-W, Y+H); - glTexCoord2f((1/16) * StarfrG2 + (1/16), 1); glVertex2f(X+W, Y+H); - glTexCoord2f((1/16) * StarfrG2, 1); glVertex2f(X+W, Y-H); - glEnd; + 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; end; -} -procedure SingDraw; +procedure SingDraw(); var Pet: integer; Pet2: integer; @@ -601,24 +645,20 @@ var TexRec: TRecR; NR: TRecR; //FS: real; - BarFrom: integer; + BarAlpha: real; - BarWspol: real; + TempCol: real; Tekst: string; LyricTemp: string; PetCz: integer; - - //SingBar Mod A: Cardinal; E: Integer; I: Integer; //end Singbar Mod - - begin // positions if Ini.SingWindow = 0 then begin @@ -654,47 +694,17 @@ begin 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; + ScreenSing.LyricMain[0].Draw; + ScreenSing.LyricSub[0].Draw; - // gaszenie - if BarWspol > 0.95 then BarAlpha := 0.5 * (1 - (BarWspol - 0.95) * 20);} - - //Change fuer Crazy Joker + SingDrawLyricHelper(0, NR); - 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; + if (AktSong.isDuet) then + begin + ScreenSing.LyricMain[1].Draw; + ScreenSing.LyricSub[1].Draw; + SingDrawLyricHelper(1, NR); + end; // oscilloscope if Ini.Oscilloscope = 1 then begin @@ -804,20 +814,22 @@ begin //end Singbar Mod //PhrasenBonus - Line Bonus Mod - if Ini.LineBonus > 0 then begin + if Ini.LineBonus > 0 then + begin A := GetTickCount div 33; - if (A <> Tickold2) AND (Player[0].LineBonus_Visible) then begin + 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 + 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 @@ -829,40 +841,45 @@ begin 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; + end; end; end; //if - if PlayersPlay = 1 then begin + 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 + 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 + 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 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); + 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 + 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 + 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); @@ -871,9 +888,6 @@ begin end; //PhrasenBonus - Line Bonus Mod End - - // rysuje paski -// Log.LogStatus('Original notes', 'SingDraw'); case Ini.Difficulty of 0: begin @@ -892,24 +906,38 @@ begin end; end; - if PlayersPlay = 1 then begin + if AktSong.isDuet then + SingDrawNotesDuet(NR) + else + SingDrawNotes(NR); + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); +end; + +procedure SingDrawNotes(NR: TRecR); +begin + if PlayersPlay = 1 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); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 0, 15); end; - if (PlayersPlay = 2) then begin + 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, 0, 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); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 0, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 1, 15); end; - if PlayersPlay = 3 then begin + if PlayersPlay = 3 then + begin NotesW := NotesW * 0.8; NotesH := NotesH * 0.8; @@ -921,12 +949,13 @@ begin SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 0, 12); SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 0, 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); + SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 0, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 0, 1, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 0, 2, 12); end; - if PlayersPlay = 4 then begin + 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); @@ -940,12 +969,12 @@ begin 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); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 0, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 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); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 2, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 3, 15); end; end; @@ -969,19 +998,111 @@ begin 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); + SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 0, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 0, 1, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 0, 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); + SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 3, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 0, 4, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 0, 5, 12); end; end; +end; - glDisable(GL_BLEND); - glDisable(GL_TEXTURE_2D); +procedure SingDrawNotesDuet(NR: TRecR); +begin + if PlayersPlay = 1 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, 0, 15); + 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, 1, 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, 0, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 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, 1, 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, 0, 12); + + SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 0, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 1, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 0, 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, 1, 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, 1, 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, 1, 15); + + if ScreenAct = 1 then begin + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 0, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 1, 15); + end; + if ScreenAct = 2 then begin + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 2, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 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, 1, 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, 1, 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, 1, 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, 0, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 1, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 0, 2, 12); + end; + if ScreenAct = 2 then begin + SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 3, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 4, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 0, 5, 12); + end; + end; end; procedure SingModiDraw (PlayerInfo: TPlayerInfo); @@ -1049,8 +1170,8 @@ begin end; // rysuje tekst - new Lyric engine - ScreenSingModi.LyricMain.Draw; - ScreenSingModi.LyricSub.Draw; + ScreenSingModi.LyricMain[0].Draw; + ScreenSingModi.LyricSub[0].Draw; // rysuje pasek, podpowiadajacy poczatek spiwania w scenie //FS := 1.3; @@ -1062,7 +1183,7 @@ begin 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); - (ScreenSingModi.LyricMain.ClientX - NR.Left - 50) + 10*ScreenX; + (ScreenSingModi.LyricMain[0].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; @@ -1230,7 +1351,8 @@ begin //end Singbar Mod //PhrasenBonus - Line Bonus Mod - if ((Ini.LineBonus > 0) AND (DLLMan.Selected.EnLineBonus_O)) OR (DLLMan.Selected.EnLineBonus) then begin + 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; @@ -1238,14 +1360,11 @@ begin //Change Alpha Player[E].LineBonus_Alpha := Player[E].LineBonus_Alpha - 0.02; - if Player[E].LineBonus_Alpha <= 0 then - begin + begin Player[E].LineBonus_Age := 0; Player[E].LineBonus_Visible := False - - end - else + end else begin inc(Player[E].LineBonus_Age, 1); @@ -1343,7 +1462,7 @@ 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); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 0, 15); end; if (PlayersPlay = 2) then begin @@ -1351,13 +1470,13 @@ begin 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); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 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); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 1, 15); end; end; @@ -1370,21 +1489,21 @@ begin 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); + SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 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); + SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 0, 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); + SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 0, 2, 12); end; end; @@ -1402,12 +1521,12 @@ begin 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); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 0, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 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); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 2, 15); + SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 3, 15); end; end; @@ -1431,14 +1550,14 @@ begin 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); + SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 0, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 0, 1, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 0, 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); + SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 3, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 0, 4, 12); + SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 0, 5, 12); end; end; end; @@ -1533,25 +1652,33 @@ end; //PhrasenBonus - Line Bonus Mod procedure SingDrawLineBonus( const X, Y: Single; Color: TRGB; Alpha: Single; Text: string; Age: Integer); var -Length: Real; //Length of Text -Size: Integer; //Size of Popup -begin -if Alpha <> 0 then + Length: 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); + //Set Font Propertys + SetFontStyle(2); //Font: Outlined1 + if Age < 5 then + SetFontSize(Age + 1) + else + SetFontSize(6); -//Check Font Size -Length := glTextWidth ( PChar(Text)) + 3; //Little Space for a Better Look ^^ + SetFontItalic(False); -//Text -SetFontPos (X + 50 - (Length / 2), Y + 12); //Position + //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; + + if Age < 5 then + Size := Age * 10 + else + Size := 50; //Draw Background glColor4f(Color.R, Color.G, Color.B, Alpha); //Set Color @@ -1587,13 +1714,34 @@ var Rec: TRecR; Pet: integer; TempR: real; + CP: integer; + end_: integer; + st: integer; begin + CP := NrCzesci; + if (Length(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta)=0) then + Exit + else + begin + st := Czesci[CP].Czesc[Czesci[CP].Akt].StartNote; + end_ := Czesci[CP].Czesc[Czesci[CP].Akt].Koniec; + if AktSong.isDuet and (Length(Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].Nuta)>0)then + begin + if (Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].Koniec > end_) then + end_ := Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].Koniec; + + if (Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].StartNote < st) then + st := Czesci[(CP+1) mod 2].Czesc[Czesci[CP].Akt].StartNote; + end; + end; + 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 + TempR := (Right-Left) / (end_ - st); + with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt] do + begin for Pet := 0 to HighNut do begin with Nuta[Pet] do begin @@ -1617,7 +1765,7 @@ begin // lewa czesc - left part - Rec.Left := (Start-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left + 0.5 + 10*ScreenX; + Rec.Left := (Start-st) * 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; @@ -1631,7 +1779,7 @@ begin // 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; + Rec.Right := (Start+Dlugosc-st) * TempR + Left - NotesW - 0.5 + 10*ScreenX; glBindTexture(GL_TEXTURE_2D, Tex_Mid[Color].TexNum); glBegin(GL_QUADS); diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas index 419a9cb8..1896829f 100644 --- a/Game/Code/Classes/UFiles.pas +++ b/Game/Code/Classes/UFiles.pas @@ -22,7 +22,7 @@ procedure ParseNote(NrCzesci: integer; TypeP: char; StartP, DurationP, NoteP: in procedure NewSentence(NrCzesciP: integer; Param1, Param2: integer; LoadFullFile: boolean); function LoadSong(Name: string; LoadFullFile: boolean): boolean; function CheckSong: boolean; -function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; +function SaveSong(Song: TSong; Czesc: array of TCzesci; Name: string; Relative: boolean): boolean; procedure FindRefrainStart(var Song: TSong); procedure SetMedleyMode; @@ -132,6 +132,7 @@ begin Song.Start := 0; Song.Finish := 0; Song.Relative := false; + Song.isDuet := false; //Additional Information Song.Background := ''; @@ -554,7 +555,8 @@ begin end; end; // case - with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].High] do begin + with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].High] do + begin SetLength(Nuta, Length(Nuta) + 1); IlNut := IlNut + 1; HighNut := HighNut + 1; @@ -625,7 +627,8 @@ begin if not AktSong.Relative then Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Start := Param1; - if AktSong.Relative then begin + if AktSong.Relative then + begin Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Start := Param1; Rel[NrCzesciP] := Rel[NrCzesciP] + Param2; end; @@ -645,7 +648,6 @@ var begin Result := true; - bt := -32000; if(AktSong.Medley.Source = msTag) then begin @@ -655,11 +657,12 @@ begin end else medley := false; - for p := 0 to {Length(Czesci)}1 - 1 do //TODO: why doesn't it work? + for p := 0 to Length(Czesci) - 1 do begin + bt := low(integer); numLines := Length(Czesci[p].Czesc); - if(numLines=0) then + if(numLines=0) and not AktSong.isDuet then begin Log.LogError('Song ' + AktSong.Path + AktSong.Filename + ' has no lines?'); if (Ini.LoadFaultySongs=0) then @@ -670,7 +673,7 @@ begin begin numNotes := Length(Czesci[p].Czesc[line].Nuta); - if(numNotes=0) then + if(numNotes=0) and not AktSong.isDuet then begin Log.LogError('Sentence ' + IntToStr(line+1) + ' in song ' + AktSong.Path + AktSong.Filename + ' has no notes?'); if (Ini.LoadFaultySongs=0) then @@ -759,9 +762,8 @@ function LoadSong(Name: string; LoadFullFile: boolean): boolean; var TempC: char; Tekst: string; - CP: integer; // Current Player (0 or 1) + CP: integer; // Current Actor (0 or 1) Pet: integer; - Both: boolean; Param1: integer; Param2: integer; Param3: integer; @@ -777,171 +779,197 @@ begin end; try - MultBPM := 4; // 4 - mnoznik dla czasu nut - Mult := 1; // 4 - dokladnosc pomiaru nut - Base[0] := 100; // high number -// Base[1] := 100; // high number - Czesci[0].Wartosc := 0; -// Czesci[1].Wartosc := 0; // here was the error in 0.3.2 - if LoadFullFile then - AktSong.Relative := false; + MultBPM := 4; // 4 - mnoznik dla czasu nut + Mult := 1; // 4 - dokladnosc pomiaru nut + Base[0] := 100; // high number + Base[1] := 100; // high number + if LoadFullFile then + AktSong.Relative := false; - Rel[0] := 0; -// Rel[1] := 0; - CP := 0; - Both := false; - if Length(Player) = 2 then Both := true; + Rel[0] := 0; + Rel[1] := 0; + CP := 0; - FileMode := fmOpenRead; - AssignFile(SongFile, Name); + FileMode := fmOpenRead; + AssignFile(SongFile, Name); - if LoadFullFile then - begin - Reset(SongFile); + if LoadFullFile then + begin + Reset(SongFile); - //Clear old Song Header - ClearSong(AktSong); + //Clear old Song Header + ClearSong(AktSong); - if (AktSong.Path = '') then - AktSong.Path := ExtractFilePath(Name); + if (AktSong.Path = '') then + AktSong.Path := ExtractFilePath(Name); - if (AktSong.FileName = '') then - AktSong.Filename := ExtractFileName(Name); - //Read Header - Result := ReadTxTHeader(AktSong); - if not Result then - begin - CloseFile(SongFile); - FileMode := fmOpenReadWrite; - Log.LogError('Error Loading SongHeader, abort Song Loading. File: ' + Name); - Exit; + if (AktSong.FileName = '') then + AktSong.Filename := ExtractFileName(Name); + + //Read Header + Result := ReadTxTHeader(AktSong); + if not Result then + begin + CloseFile(SongFile); + FileMode := fmOpenReadWrite; + Log.LogError('Error Loading SongHeader, abort Song Loading. File: ' + Name); + Exit; + end; end; - end; - Result := False; + Result := False; - Reset(SongFile); - FileLineNo := 0; - //Search for Note Begining - repeat - ReadLn(SongFile, Tekst); - Inc(FileLineNo); + Reset(SongFile); + FileLineNo := 0; + //Search for Note Begining + repeat + ReadLn(SongFile, Tekst); + Inc(FileLineNo); - if (EoF(SongFile)) or (Length(Tekst)=0) then - begin //Song File Corrupted - No Notes - CloseFile(SongFile); - FileMode := fmOpenReadWrite; - Log.LogError('Could not load txt File, no Notes found: ' + Name); - Result := False; - Exit; - end; - - Read(SongFile, TempC); - until ((TempC = ':') or (TempC = 'F') or (TempC = '*')); - Inc(FileLineNo); - - SetLength(Czesci, 0); - SetLength(Czesci, 2); - for Pet := 0 to High(Czesci) do begin - SetLength(Czesci[Pet].Czesc, 1); - Czesci[Pet].High := 0; - Czesci[Pet].Ilosc := 1; - Czesci[Pet].Akt := 0; - Czesci[Pet].Resolution := AktSong.Resolution; - Czesci[Pet].NotesGAP := AktSong.NotesGAP; - Czesci[Pet].Czesc[0].IlNut := 0; - Czesci[Pet].Czesc[0].HighNut := -1; - end; - - isNewSentence := false; - while (TempC <> 'E') AND (not EOF(SongFile)) do begin - if (TempC = ':') or (TempC = '*') or (TempC = 'F') then begin - // wczytuje nute - Read(SongFile, Param1); - Read(SongFile, Param2); - Read(SongFile, Param3); - Read(SongFile, ParamS); - - // dodaje nute - if not Both then - // P1 - ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS) - else begin - // P1 + P2 - ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS); - ParseNote(1, TempC, (Param1+Rel[1]) * Mult, Param2 * Mult, Param3, ParamS); - end; - isNewSentence := false; - end; // if - if TempC = '-' then begin - if isNewSentence then - begin - Log.LogError('Double sentence break in file: "' + Name + '"; Line '+IntToStr(FileLineNo)+' (LoadSong)'); + if (EoF(SongFile)) or (Length(Tekst)=0) then + begin //Song File Corrupted - No Notes + CloseFile(SongFile); + FileMode := fmOpenReadWrite; + Log.LogError('Could not load txt/txd File, no Notes found: ' + Name); Result := False; Exit; end; - // reads sentence - Read(SongFile, Param1); - if AktSong.Relative then Read(SongFile, Param2); // read one more data for relative system - - // new sentence - if not Both then - // P1 - NewSentence(0, (Param1 + Rel[0]) * Mult, Param2, LoadFullFile) - else begin - // P1 + P2 - NewSentence(0, (Param1 + Rel[0]) * Mult, Param2, LoadFullFile); - NewSentence(1, (Param1 + Rel[1]) * Mult, Param2, LoadFullFile); - end; - isNewSentence := true; - end; // if - if TempC = 'B' then begin - SetLength(AktSong.BPM, Length(AktSong.BPM) + 1); - Read(SongFile, AktSong.BPM[High(AktSong.BPM)].StartBeat); - AktSong.BPM[High(AktSong.BPM)].StartBeat := AktSong.BPM[High(AktSong.BPM)].StartBeat + Rel[0]; + Read(SongFile, TempC); + until ((TempC = ':') or (TempC = 'F') or (TempC = '*') or (TempC = 'P')); + Inc(FileLineNo); - Read(SongFile, Tekst); - AktSong.BPM[High(AktSong.BPM)].BPM := StrToFloat(Tekst); - AktSong.BPM[High(AktSong.BPM)].BPM := AktSong.BPM[High(AktSong.BPM)].BPM * Mult * MultBPM; - end; + SetLength(Czesci, 0); + if (TempC = 'P') then + begin + AktSong.isDuet := true; + SetLength(Czesci, 2); + end else + SetLength(Czesci, 1); + for Pet := 0 to High(Czesci) do + begin + SetLength(Czesci[Pet].Czesc, 1); + Czesci[Pet].High := 0; + Czesci[Pet].Ilosc := 1; + Czesci[Pet].Akt := 0; + Czesci[Pet].Resolution := AktSong.Resolution; + Czesci[Pet].NotesGAP := AktSong.NotesGAP; + Czesci[Pet].Czesc[0].IlNut := 0; + Czesci[Pet].Czesc[0].HighNut := -1; + Czesci[Pet].Wartosc := 0; + end; - if not Both then begin - Czesci[CP].Czesc[Czesci[CP].High].BaseNote := Base[CP]; - if LoadFullFile then - Czesci[CP].Czesc[Czesci[CP].High].LyricWidth := glTextWidth(PChar(Czesci[CP].Czesc[Czesci[CP].High].Lyric)); - //Total Notes Patch - Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := 0; - for I := low(Czesci[CP].Czesc[Czesci[CP].High].Nuta) to high(Czesci[CP].Czesc[Czesci[CP].High].Nuta) do + isNewSentence := false; + while (TempC <> 'E') AND (not EOF(SongFile)) do + begin + if (TempC = 'P') then + begin + Read(SongFile, Param1); + if (Param1=1) then + CP := 0 + else if (Param1=2) then + CP := 1 + else if (Param1=3) then + CP := 2 + else + begin + Log.LogError('Wrong P-Number in file: "' + Name + '"; Line '+IntToStr(FileLineNo)+' (LoadSong)'); + Result := False; + Exit; + end; + end; + if (TempC = ':') or (TempC = '*') or (TempC = 'F') then begin - Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := Czesci[CP].Czesc[Czesci[CP].High].TotalNotes + Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Dlugosc * Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Wartosc; + // wczytuje nute + Read(SongFile, Param1); + Read(SongFile, Param2); + Read(SongFile, Param3); + Read(SongFile, ParamS); + + // dodaje nute + if (CP<>2) then + // one singer + ParseNote(CP, TempC, (Param1+Rel[CP]) * Mult, Param2 * Mult, Param3, ParamS) + else begin + // both singer + ParseNote(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS); + ParseNote(1, TempC, (Param1+Rel[1]) * Mult, Param2 * Mult, Param3, ParamS); + end; + isNewSentence := false; end; - //Total Notes Patch End - end else begin - for Pet := 0 to High(Czesci) do begin - Czesci[Pet].Czesc[Czesci[Pet].High].BaseNote := Base[Pet]; + + if TempC = '-' then begin + if isNewSentence then + begin + Log.LogError('Double sentence break in file: "' + Name + '"; Line '+IntToStr(FileLineNo)+' (LoadSong)'); + Result := False; + Exit; + end; + // reads sentence + Read(SongFile, Param1); + if AktSong.Relative then Read(SongFile, Param2); // read one more data for relative system + + // new sentence + if not AktSong.isDuet then + // one singer + NewSentence(CP, (Param1 + Rel[CP]) * Mult, Param2, LoadFullFile) + else + begin + // both singer + NewSentence(0, (Param1 + Rel[0]) * Mult, Param2, LoadFullFile); + NewSentence(1, (Param1 + Rel[1]) * Mult, Param2, LoadFullFile); + end; + isNewSentence := true; + end; // if + + if TempC = 'B' then begin + SetLength(AktSong.BPM, Length(AktSong.BPM) + 1); + Read(SongFile, AktSong.BPM[High(AktSong.BPM)].StartBeat); + AktSong.BPM[High(AktSong.BPM)].StartBeat := AktSong.BPM[High(AktSong.BPM)].StartBeat + Rel[0]; + + Read(SongFile, Tekst); + AktSong.BPM[High(AktSong.BPM)].BPM := StrToFloat(Tekst); + AktSong.BPM[High(AktSong.BPM)].BPM := AktSong.BPM[High(AktSong.BPM)].BPM * Mult * MultBPM; + end; + + + if not AktSong.isDuet then begin + Czesci[CP].Czesc[Czesci[CP].High].BaseNote := Base[CP]; if LoadFullFile then - Czesci[Pet].Czesc[Czesci[Pet].High].LyricWidth := glTextWidth(PChar(Czesci[Pet].Czesc[Czesci[Pet].High].Lyric)); + Czesci[CP].Czesc[Czesci[CP].High].LyricWidth := glTextWidth(PChar(Czesci[CP].Czesc[Czesci[CP].High].Lyric)); //Total Notes Patch - Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := 0; - for I := low(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) to high(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) do + Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := 0; + for I := low(Czesci[CP].Czesc[Czesci[CP].High].Nuta) to high(Czesci[CP].Czesc[Czesci[CP].High].Nuta) do begin - Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes + Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Dlugosc * Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Wartosc; + Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := Czesci[CP].Czesc[Czesci[CP].High].TotalNotes + Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Dlugosc * Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Wartosc; end; //Total Notes Patch End + end else + begin + for Pet := 0 to High(Czesci) do begin + Czesci[Pet].Czesc[Czesci[Pet].High].BaseNote := Base[Pet]; + if LoadFullFile then + Czesci[Pet].Czesc[Czesci[Pet].High].LyricWidth := glTextWidth(PChar(Czesci[Pet].Czesc[Czesci[Pet].High].Lyric)); + //Total Notes Patch + Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := 0; + for I := low(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) to high(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) do + begin + Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes + Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Dlugosc * Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Wartosc; + end; + //Total Notes Patch End + end; end; - end; - Repeat - Read(SongFile, TempC); - Until ((TempC <> #13) AND (TempC <> #10)) or (TempC = 'E') or (EOF(SongFile)); + Repeat + Read(SongFile, TempC); + Until ((TempC <> #13) AND (TempC <> #10)) or (TempC = 'E') or (EOF(SongFile)); - Inc(FileLineNo); - end; // while} + Inc(FileLineNo); + end; // while} - CloseFile(SongFile); - FileMode := fmOpenReadWrite; + CloseFile(SongFile); + FileMode := fmOpenReadWrite; except try CloseFile(SongFile); @@ -949,6 +977,7 @@ begin except end; + Result := false; Log.LogError('Error Loading File: "' + Name + '" in Line ' + inttostr(FileLineNo)); exit; @@ -960,7 +989,7 @@ end; //-------------------- // Saves a Song //-------------------- -function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean; +function SaveSong(Song: TSong; Czesc: array of TCzesci; Name: string; Relative: boolean): boolean; var C: integer; N: integer; @@ -968,11 +997,12 @@ var B: integer; RelativeSubTime: integer; NoteState: String; + CP: integer; procedure WriteCustomTags; //from 1.1 (modified) - var - I: integer; - Line: String; + var + I: integer; + Line: String; begin for I := 0 to High(Song.CustomTags) do begin @@ -982,7 +1012,60 @@ var WriteLn(SongFile, '#' + Line); end; + end; + + function isIdenticalLine(line: integer): boolean; + var + I: integer; + + begin + Result := false; + + if (Czesc[0].Czesc[line].HighNut <> Czesc[1].Czesc[line].HighNut) then + Exit; + + if (Czesc[0].Czesc[line].Start <> Czesc[1].Czesc[line].Start) then + Exit; + + for I := 0 to Length(Czesc[0].Czesc[line].Nuta) - 1 do + begin + if (Czesc[0].Czesc[line].Nuta[I].Wartosc <> Czesc[1].Czesc[line].Nuta[I].Wartosc) then + Exit; + + if (Czesc[0].Czesc[line].Nuta[I].Start <> Czesc[1].Czesc[line].Nuta[I].Start) then + Exit; + + if (Czesc[0].Czesc[line].Nuta[I].Dlugosc <> Czesc[1].Czesc[line].Nuta[I].Dlugosc) then + Exit; + + if (Czesc[0].Czesc[line].Nuta[I].Ton <> Czesc[1].Czesc[line].Nuta[I].Ton) then + Exit; + + if (Czesc[0].Czesc[line].Nuta[I].Tekst <> Czesc[1].Czesc[line].Nuta[I].Tekst) then + Exit; + end; + Result := true; + end; + procedure WriteLine(CP, line: integer); + var + note: integer; + begin + for note := 0 to Czesc[CP].Czesc[line].HighNut do + begin + with Czesc[CP].Czesc[line].Nuta[note] do + begin + //Golden + Freestyle Note Patch + case Czesc[CP].Czesc[line].Nuta[note].Wartosc of + 0: NoteState := 'F '; + 1: NoteState := ': '; + 2: NoteState := '* '; + end; // case + S := NoteState + IntToStr(Start-RelativeSubTime) + ' ' + IntToStr(Dlugosc) + + ' ' + IntToStr(Ton) + ' ' + Tekst; + WriteLn(SongFile, S); + end; // with + end; // N end; begin // Relative := true; // override (idea - use shift+S to save with relative) @@ -1028,38 +1111,82 @@ begin // write custom header tags (from 1.1) WriteCustomTags; - for C := 0 to Czesc.High do begin - for N := 0 to Czesc.Czesc[C].HighNut do begin - with Czesc.Czesc[C].Nuta[N] do begin - - - //Golden + Freestyle Note Patch - case Czesc.Czesc[C].Nuta[N].Wartosc of - 0: NoteState := 'F '; - 1: NoteState := ': '; - 2: NoteState := '* '; - end; // case - S := NoteState + IntToStr(Start-RelativeSubTime) + ' ' + IntToStr(Dlugosc) + ' ' + IntToStr(Ton) + ' ' + Tekst; - + if not Song.isDuet then + begin + for C := 0 to Czesc[0].High do + begin + WriteLine(0, C); + if C < Czesc[0].High then + begin // don't write end of last sentence + if not Relative then + S := '- ' + IntToStr(Czesc[0].Czesc[C+1].Start) + else + begin + S := '- ' + IntToStr(Czesc[0].Czesc[C+1].Start - RelativeSubTime) + + ' ' + IntToStr(Czesc[0].Czesc[C+1].Start - RelativeSubTime); + RelativeSubTime := Czesc[0].Czesc[C+1].Start; + end; WriteLn(SongFile, S); - end; // with - end; // N - - if C < Czesc.High then begin // don't write end of last sentence - if not Relative then - S := '- ' + IntToStr(Czesc.Czesc[C+1].Start) - else begin - S := '- ' + IntToStr(Czesc.Czesc[C+1].Start - RelativeSubTime) + - ' ' + IntToStr(Czesc.Czesc[C+1].Start - RelativeSubTime); - RelativeSubTime := Czesc.Czesc[C+1].Start; end; - WriteLn(SongFile, S); - end; - - end; // C + end; // C + end else + begin + CP := -1; + for C := 0 to Czesc[0].High do //go through all lines + begin + if isIdenticalLine(C) then + begin + //not end? + if (C < Czesc[0].High) and (CP <> 3) then + begin + //P1+P2 ==> P3 + S := 'P3'; + CP := 3; + WriteLn(SongFile, S); + end; + WriteLine(0, C); + end else + begin + //singer 1 P1 + if (Length(Czesc[0].Czesc[C].Nuta)>0) then + begin + if (C < Czesc[0].High) and (CP <> 1) then + begin + S := 'P1'; + CP := 1; + WriteLn(SongFile, S); + end; + WriteLine(0, C); + end; + //singer 2 P2 + if (Length(Czesc[1].Czesc[C].Nuta)>0) then + begin + if (C < Czesc[0].High) and (CP <> 2) then + begin + S := 'P2'; + CP := 2; + WriteLn(SongFile, S); + end; + WriteLine(1, C); + end; + end; + if C < Czesc[0].High then + begin // don't write end of last sentence + if not Relative then + S := '- ' + IntToStr(Czesc[0].Czesc[C+1].Start) + else + begin + S := '- ' + IntToStr(Czesc[0].Czesc[C+1].Start - RelativeSubTime) + + ' ' + IntToStr(Czesc[0].Czesc[C+1].Start - RelativeSubTime); + RelativeSubTime := Czesc[0].Czesc[C+1].Start; + end; + WriteLn(SongFile, S); + end; + end; // C + end; WriteLn(SongFile, 'E'); CloseFile(SongFile); end; diff --git a/Game/Code/Classes/UGraphic.pas b/Game/Code/Classes/UGraphic.pas index 7604e68e..4d5bf3c7 100644 --- a/Game/Code/Classes/UGraphic.pas +++ b/Game/Code/Classes/UGraphic.pas @@ -302,7 +302,7 @@ begin Log.LogBenchmark('--> Loading Textures', 2); Log.BenchmarkStart(2); - Lyric := TLyric.Create; + //Lyric := TLyric.Create; Log.BenchmarkEnd(2); Log.LogBenchmark('--> Loading Fonts', 2); @@ -468,7 +468,6 @@ begin 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); diff --git a/Game/Code/Classes/ULyrics.pas b/Game/Code/Classes/ULyrics.pas index 07ecccac..08563d66 100644 --- a/Game/Code/Classes/ULyrics.pas +++ b/Game/Code/Classes/ULyrics.pas @@ -69,7 +69,7 @@ type property Style: integer write SetStyle; property FontStyle: integer write SetFStyle; procedure AddWord(Text: string); - procedure AddCzesc(NrCzesci: integer); //AddLine? + procedure AddCzesc(CP, NrCzesci: integer); //AddLine? procedure ChangeCurText(Text: String); function SelectedLetter: integer; // LCD @@ -80,8 +80,8 @@ type end; -var - Lyric: TLyric; +{var + Lyric: TLyric;} implementation uses TextGL, UGraphic, UDrawTexture; @@ -220,15 +220,24 @@ begin Refresh; end; -procedure TLyric.AddCzesc(NrCzesci: integer); +procedure TLyric.AddCzesc(CP, 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; + if (Length(Czesci[CP].Czesc[NrCzesci].Nuta)>0) then + begin + for N := 0 to Czesci[CP].Czesc[NrCzesci].HighNut do + begin + Italic := Czesci[CP].Czesc[NrCzesci].Nuta[N].FreeStyle; + AddWord(Czesci[CP].Czesc[NrCzesci].Nuta[N].Tekst); + Text := Text + Czesci[CP].Czesc[NrCzesci].Nuta[N].Tekst; + end; + end else + begin + Italic := false; + AddWord(' '); + Text := ' '; end; Selected := -1; end; @@ -301,7 +310,7 @@ begin 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.Y := YR -12 - 10*sin(Word[W].Done * pi); Tex_Ball.W := 20; Tex_Ball.H := 20; DrawTexture(Tex_Ball); diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas index c56513d1..9a7caae7 100644 --- a/Game/Code/Classes/UMain.pas +++ b/Game/Code/Classes/UMain.pas @@ -101,12 +101,12 @@ var 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 NewSentence(CP: integer; Sender: TScreenSing); +procedure NewBeat(CP: integer; Sender: TScreenSing); // executed when on then new beat +procedure NewBeatC(CP: integer; Sender: TScreenSing); // executed when on then new beat for click +procedure NewBeatD(CP: integer; 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 +procedure NewNote(P: integer; Sender: TScreenSing); // detect note function GetMidBeat(Time: real): real; function GetTimeFromBeat(Beat: integer): real; procedure ClearScores(PlayerNum: integer); @@ -382,10 +382,14 @@ begin Czas.FracBeatD := Frac(Czas.MidBeatD); // sentences routines - for PetGr := 0 to 0 do begin;//High(Gracz) do begin - CP := PetGr; + PetGr := 0; + if AktSong.isDuet then + PetGr := 1; + + for CP := 0 to PetGr do + begin // ustawianie starej czesci - Czas.OldCzesc := Czesci[CP].Akt; + Czas.OldCzesc[CP] := Czesci[CP].Akt; // wybieranie aktualnej czesci for Pet := 0 to Czesci[CP].High do @@ -396,94 +400,108 @@ begin // czysczenie nut gracza, gdy to jest nowa plansza // (optymizacja raz na halfbeat jest zla) - if Czesci[CP].Akt <> Czas.OldCzesc then NewSentence(Sender); + if Czesci[CP].Akt <> Czas.OldCzesc[CP] then + NewSentence(CP, Sender); - end; // for PetGr + // wykonuje operacje raz na beat + if (Czas.AktBeat >= 0) and (Czas.OldBeat <> Czas.AktBeat) then + NewBeat(CP, Sender); - // 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(CP, 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(CP, 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; + // plynnie przesuwa text + Done := 1; + if (Length(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta)>0) then + begin + for N := 0 to Czesci[CP].Czesc[Czesci[CP].Akt].HighNut do + if (Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[N].Start <= Czas.MidBeat) + and (Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[N].Start + Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[N].Dlugosc >= Czas.MidBeat) then + Done := (Czas.MidBeat - Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[N].Start) / (Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[N].Dlugosc); + + N := Czesci[CP].Czesc[Czesci[CP].Akt].HighNut; + + // wylacza ostatnia nute po przejsciu + if (Ini.LyricsEffect = 1) and (Done = 1) and + (Czas.MidBeat > Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[N].Start + Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[N].Dlugosc) + then + begin + Sender.LyricMain[CP].Selected := -1 + end; - if Done > 1 then Done := 1; - Sender.LyricMain.Done := Done; + if Done > 1 then + Done := 1; - // 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; + Sender.LyricMain[CP].Done := Done; end; - end;} - - + end; end; -procedure NewSentence(Sender: TScreenSing); +procedure NewSentence(CP: integer; 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); + if AktSong.isDuet then + begin + for G := 0 to High(Player) do + begin + if (G mod 2 = CP) then + begin + Player[G].IlNut := 0; + Player[G].HighNut := -1; + SetLength(Player[G].Nuta, 0); + end; + end; + end else + begin + for G := 0 to High(Player) do + begin + Player[G].IlNut := 0; + Player[G].HighNut := -1; + SetLength(Player[G].Nuta, 0); + end; 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) + with Sender do + begin + LyricMain[CP].AddCzesc(CP, Czesci[CP].Akt); + if Czesci[CP].Akt < Czesci[CP].High then + LyricSub[CP].AddCzesc(CP, Czesci[CP].Akt+1) else - LyricSub.Clear; + LyricSub[CP].Clear; end; //On Sentence Change... - Sender.onSentenceChange(Czesci[0].Akt); + if(CP=0) then + Sender.onSentenceChange(Czesci[CP].Akt); end; -procedure NewBeat(Sender: TScreenSing); +procedure NewBeat(CP: integer; 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; + if (Length(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta)=0) then + Exit; + for Pet := 0 to Czesci[CP].Czesc[Czesci[CP].Akt].HighNut do + begin + if (Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[Pet].Start = Czas.AktBeat) then + begin + // operates on currently beated note + Sender.LyricMain[CP].Selected := Pet end; + end; end; -procedure NewBeatC; +procedure NewBeatC(CP: integer; Sender: TScreenSing); var Pet: integer; // LPT_1: integer; @@ -493,11 +511,12 @@ begin // LPT_2 := 1; // beat click - if (Ini.BeatClick = 1) and ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod Czesci[0].Resolution = 0) then + if (Ini.BeatClick = 1) and ((Czas.AktBeatC + Czesci[CP].Resolution + Czesci[CP].NotesGAP) mod Czesci[CP].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 + if ((Czas.AktBeatC + Czesci[CP].Resolution + Czesci[CP].NotesGAP) mod Czesci[CP].Resolution = 0) then + begin //LPT_1 := 0; // Light.LightOne(0, 150); @@ -508,8 +527,12 @@ begin 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 + if (Length(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta)=0) then + Exit; + + for Pet := 0 to Czesci[CP].Czesc[Czesci[CP].Akt].HighNut do + if (Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[Pet].Start = Czas.AktBeatC) then + begin // click assist if Ini.ClickAssist = 1 then Music.PlayClick; @@ -526,9 +549,9 @@ begin //PortWriteB($378, LPT_1 + LPT_2 * 2); // 0 zapala end; -procedure NewBeatD(Sender: TScreenSing); +procedure NewBeatD(CP: integer; Sender: TScreenSing); begin - NewNote(Sender); + NewNote(CP, Sender); end; //procedure NewHalf; @@ -536,7 +559,7 @@ end; // NewNote; //end; -procedure NewNote(Sender: TScreenSing); +procedure NewNote(P: integer; Sender: TScreenSing); var CP: integer; // current player S: integer; // sentence @@ -549,161 +572,301 @@ var 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; - 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 + + for CP := 0 to PlayersPlay-1 do + begin + if (not AktSong.isDuet) then + begin + // analyze buffer + Sound[CP].AnalizujBufor; + + // 0.5.0: count min and max sentence range for checking (detection is delayed to the notes we see on the screen) + SMin := Czesci[P].Akt-1; + if SMin < 0 then + SMin := 0; + SMax := Czesci[P].Akt; + + // check if we can add new note + Mozna := false; + for S := SMin to SMax do + begin + for Pet := 0 to Czesci[P].Czesc[S].HighNut do + begin + if ((Czesci[P].Czesc[S].Nuta[Pet].Start <= Czas.AktBeatD) + and (Czesci[P].Czesc[S].Nuta[Pet].Start + Czesci[P].Czesc[S].Nuta[Pet].Dlugosc - 1 >= Czas.AktBeatD)) + and (not Czesci[P].Czesc[S].Nuta[Pet].FreeStyle) // but don't allow when it's FreeStyle note + and (Czesci[P].Czesc[S].Nuta[Pet].Dlugosc > 0) // and make sure the note lenghts is at least 1 + then + begin SDet := S; Mozna := true; Break; end; + end; + end; - S := SDet; - - - + S := SDet; + if (Sound[CP].SzczytJest) and (Mozna) then + begin + // operowanie na ostatniej nucie + for Pet := 0 to Czesci[P].Czesc[S].HighNut do + begin + if (Czesci[P].Czesc[S].Nuta[Pet].Start <= Czas.OldBeatD+1) + and (Czesci[P].Czesc[S].Nuta[Pet].Start + + Czesci[P].Czesc[S].Nuta[Pet].Dlugosc > Czas.OldBeatD+1) then + begin + // przesuwanie tonu w odpowiednia game + while (Sound[CP].Ton - Czesci[P].Czesc[S].Nuta[Pet].Ton > 6) do + Sound[CP].Ton := Sound[CP].Ton - 12; + while (Sound[CP].Ton - Czesci[P].Czesc[S].Nuta[Pet].Ton < -6) do + Sound[CP].Ton := Sound[CP].Ton + 12; -// Czas.SzczytJest := true; -// Czas.Ton := 27; + // Half size Notes Patch + NoteHit := false; - // 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) + //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[P].Czesc[S].Nuta[Pet].Ton - Sound[CP].Ton) <= Range then + begin + Sound[CP].Ton := Czesci[P].Czesc[S].Nuta[Pet].Ton; - // 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 := true; - // Half size Notes Patch - NoteHit := false; + if (Ini.LineBonus = 0) then + begin + // add points without LineBonus + case Czesci[P].Czesc[S].Nuta[Pet].Wartosc of + 1: Player[CP].Score := Player[CP].Score + 10000 / Czesci[P].Wartosc * + Czesci[P].Czesc[S].Nuta[Pet].Wartosc; + 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 10000 / Czesci[P].Wartosc * + Czesci[P].Czesc[S].Nuta[Pet].Wartosc; + end; + end else + begin + // add points with Line Bonus + case Czesci[P].Czesc[S].Nuta[Pet].Wartosc of + 1: Player[CP].Score := Player[CP].Score + 9000 / Czesci[P].Wartosc * + Czesci[P].Czesc[S].Nuta[Pet].Wartosc; + 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 9000 / Czesci[P].Wartosc * + Czesci[P].Czesc[S].Nuta[Pet].Wartosc; + end; + end; - //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; + 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 + end; - // Half size Notes Patch - NoteHit := true; + // 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[P].Czesc[S].HighNut do + if (Czesci[P].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; + end else + begin + // przedluzenie nuty + Player[CP].Nuta[Player[CP].HighNut].Dlugosc := Player[CP].Nuta[Player[CP].HighNut].Dlugosc + 1; + end; - 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 + // check for perfect note and then lit the star (on Draw) + for Pet := 0 to Czesci[P].Czesc[S].HighNut do + begin + if (Czesci[P].Czesc[S].Nuta[Pet].Start = Player[CP].Nuta[Player[CP].HighNut].Start) + and (Czesci[P].Czesc[S].Nuta[Pet].Dlugosc = Player[CP].Nuta[Player[CP].HighNut].Dlugosc) + and (Czesci[P].Czesc[S].Nuta[Pet].Ton = Player[CP].Nuta[Player[CP].HighNut].Ton) then 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; + Player[CP].Nuta[Player[CP].HighNut].Perfect := true; 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;// else beep; // if S = SMax + end; //for + end; // if moze + end else + begin //############################ DUET ##################### + if (CP mod 2 = P) then + begin + // analyze buffer + Sound[CP].AnalizujBufor; + + // 0.5.0: count min and max sentence range for checking (detection is delayed to the notes we see on the screen) + SMin := Czesci[P].Akt-1; + if SMin < 0 then + SMin := 0; + SMax := Czesci[P].Akt; + + // check if we can add new note + Mozna := false; + for S := SMin to SMax do + begin + for Pet := 0 to Czesci[P].Czesc[S].HighNut do + begin + if ((Czesci[P].Czesc[S].Nuta[Pet].Start <= Czas.AktBeatD) + and (Czesci[P].Czesc[S].Nuta[Pet].Start + Czesci[P].Czesc[S].Nuta[Pet].Dlugosc - 1 >= Czas.AktBeatD)) + and (not Czesci[P].Czesc[S].Nuta[Pet].FreeStyle) // but don't allow when it's FreeStyle note + and (Czesci[P].Czesc[S].Nuta[Pet].Dlugosc > 0) // and make sure the note lenghts is at least 1 + then + begin + SDet := S; + Mozna := true; + Break; end; + end; + 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; + S := SDet; + if (Sound[CP].SzczytJest) and (Mozna) then + begin + // operowanie na ostatniej nucie + for Pet := 0 to Czesci[P].Czesc[S].HighNut do + begin + if (Czesci[P].Czesc[S].Nuta[Pet].Start <= Czas.OldBeatD+1) + and (Czesci[P].Czesc[S].Nuta[Pet].Start + + Czesci[P].Czesc[S].Nuta[Pet].Dlugosc > Czas.OldBeatD+1) then + begin + // przesuwanie tonu w odpowiednia game + while (Sound[CP].Ton - Czesci[P].Czesc[S].Nuta[Pet].Ton > 6) do + Sound[CP].Ton := Sound[CP].Ton - 12; + while (Sound[CP].Ton - Czesci[P].Czesc[S].Nuta[Pet].Ton < -6) do + Sound[CP].Ton := Sound[CP].Ton + 12; - // Half Note Patch - Player[CP].Nuta[Player[CP].HighNut].Hit := NoteHit; + // 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[P].Czesc[S].Nuta[Pet].Ton - Sound[CP].Ton) <= Range then + begin + Sound[CP].Ton := Czesci[P].Czesc[S].Nuta[Pet].Ton; - // Log.LogStatus('Nowa Nuta ' + IntToStr(Gracz.Nuta[Gracz.HighNut].Start), 'NewBeat'); + // Half size Notes Patch + NoteHit := true; - end else begin - // przedluzenie nuty - Player[CP].Nuta[Player[CP].HighNut].Dlugosc := Player[CP].Nuta[Player[CP].HighNut].Dlugosc + 1; - end; + if (Ini.LineBonus = 0) then + begin + // add points without LineBonus + case Czesci[P].Czesc[S].Nuta[Pet].Wartosc of + 1: Player[CP].Score := Player[CP].Score + 10000 / Czesci[P].Wartosc * + Czesci[P].Czesc[S].Nuta[Pet].Wartosc; + 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 10000 / Czesci[P].Wartosc * + Czesci[P].Czesc[S].Nuta[Pet].Wartosc; + end; + end else + begin + // add points with Line Bonus + case Czesci[P].Czesc[S].Nuta[Pet].Wartosc of + 1: Player[CP].Score := Player[CP].Score + 9000 / Czesci[P].Wartosc * + Czesci[P].Czesc[S].Nuta[Pet].Wartosc; + 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 9000 / Czesci[P].Wartosc * + Czesci[P].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; - // 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; + Player[CP].ScoreTotalI := Player[CP].ScoreI + Player[CP].ScoreGoldenI + Player[CP].ScoreLineI; + end; + end; // operowanie end; - end;// else beep; // if S = SMax + // 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[P].Czesc[S].HighNut do + if (Czesci[P].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; + end else + begin + // przedluzenie nuty + Player[CP].Nuta[Player[CP].HighNut].Dlugosc := Player[CP].Nuta[Player[CP].HighNut].Dlugosc + 1; + end; + - end; // if moze - end; // for CP -// Log.LogStatus('EndBeat', 'NewBeat'); + // check for perfect note and then lit the star (on Draw) + for Pet := 0 to Czesci[P].Czesc[S].HighNut do + begin + if (Czesci[P].Czesc[S].Nuta[Pet].Start = Player[CP].Nuta[Player[CP].HighNut].Start) + and (Czesci[P].Czesc[S].Nuta[Pet].Dlugosc = Player[CP].Nuta[Player[CP].HighNut].Dlugosc) + and (Czesci[P].Czesc[S].Nuta[Pet].Ton = Player[CP].Nuta[Player[CP].HighNut].Ton) then + begin + Player[CP].Nuta[Player[CP].HighNut].Perfect := true; + end; -//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;// else beep; // if S = SMax + end; //for + end; // if moze + end; //if mod 2 + end; + end; // for CP + //On Sentence End -> For LineBonus + SingBar + if (sDet >= low(Czesci[P].Czesc)) AND (sDet <= high(Czesci[P].Czesc)) then + begin + if (Length(Czesci[P].Czesc[SDet].Nuta)>0) then + begin + if ((Czesci[P].Czesc[SDet].Nuta[Czesci[P].Czesc[SDet].HighNut].Start + + Czesci[P].Czesc[SDet].Nuta[Czesci[P].Czesc[SDet].HighNut].Dlugosc - 1) = Czas.AktBeatD) then + Sender.onSentenceEnd(P, sDet); + end; + end; end; procedure ClearScores(PlayerNum: integer); diff --git a/Game/Code/Classes/UMusic.pas b/Game/Code/Classes/UMusic.pas index 1e608c68..7fae3017 100644 --- a/Game/Code/Classes/UMusic.pas +++ b/Game/Code/Classes/UMusic.pas @@ -8,6 +8,7 @@ procedure InitializeSound; type TPos = record + CP: integer; line: integer; note: integer; end; @@ -200,7 +201,7 @@ type FracBeatC: real; // fractional part of MidBeatC - OldCzesc: integer; // poprzednio wyswietlana czesc + OldCzesc: array [0..1] of integer; // poprzednio wyswietlana czesc // akt jest w czesci.akt Teraz: real; // aktualny czas w utworze @@ -261,8 +262,10 @@ var found: boolean; min: integer; diff: integer; + begin found := false; + for I := 0 to length(Czesci[0].Czesc) - 1 do begin for J := 0 to length(Czesci[0].Czesc[I].Nuta) - 1 do @@ -270,6 +273,7 @@ begin if (beat>=Czesci[0].Czesc[I].Nuta[J].Start) and (beat<=Czesci[0].Czesc[I].Nuta[J].Start + Czesci[0].Czesc[I].Nuta[J].Dlugosc) then begin + Result.CP := 0; Result.line := I; Result.note := J; found:=true; @@ -278,6 +282,28 @@ begin end; end; + if found then //found exactly + exit; + + if AktSong.isDuet then + begin + for I := 0 to length(Czesci[1].Czesc) - 1 do + begin + for J := 0 to length(Czesci[1].Czesc[I].Nuta) - 1 do + begin + if (beat>=Czesci[1].Czesc[I].Nuta[J].Start) and + (beat<=Czesci[1].Czesc[I].Nuta[J].Start + Czesci[1].Czesc[I].Nuta[J].Dlugosc) then + begin + Result.CP := 1; + Result.line := I; + Result.note := J; + found:=true; + break; + end; + end; + end; + end; + if found then //found exactly exit; @@ -290,12 +316,31 @@ begin diff := abs(Czesci[0].Czesc[I].Nuta[J].Start - beat); if diffsmNormal) and (not CatSongs.Song[S].isDuet)) or + (ScreenSong.Mode=smNormal) then + CatSongs.Song[S].Visible := true + else + CatSongs.Song[S].Visible := false; + end else CatSongs.Song[S].Visible := false; end; end; @@ -619,7 +630,8 @@ procedure TCatSongs.HideCategory(Index: integer); // hides all songs in category var S: integer; // song begin - for S := 0 to high(CatSongs.Song) do begin + for S := 0 to high(CatSongs.Song) do + begin if not CatSongs.Song[S].Main then CatSongs.Song[S].Visible := false // hides all at now end; @@ -631,25 +643,64 @@ var begin Num := CatSongs.Song[Index].OrderNum; if Num <> CatNumShow then - begin + begin ShowCategory(Num); - end - else begin + end else + begin ShowCategoryList; end; end; +function TCatSongs.NumCatSongs(Cat: integer): integer; +var + I: integer; +begin + Result := 0; + for I := 0 to Length(CatSongs.Song)-1 do + begin + if (CatSongs.Song[I].OrderNum = Cat) AND (Not CatSongs.Song[I].Main) then + begin + if ((ScreenSong.Mode<>smNormal) and (not CatSongs.Song[I].isDuet)) or + (ScreenSong.Mode=smNormal) then + inc(Result); + end; + end; +end; + +function TCatSongs.NumVisibleCats(): integer; +var + I: integer; +begin + Result := 0; + for I := 0 to Length(CatSongs.Song)-1 do + begin + if CatSongs.Song[I].Main and CatSongs.Song[I].Visible then + begin + inc(Result); + end; + end; +end; + //Hide Categorys when in Category Hack procedure TCatSongs.ShowCategoryList; var S: integer; + vis: boolean; begin //Hide All Songs Show All Cats - for S := 0 to high(CatSongs.Song) do begin + for S := 0 to high(CatSongs.Song) do + begin + vis := false; + if CatSongs.Song[S].Main then - CatSongs.Song[S].Visible := true - else - CatSongs.Song[S].Visible := false + begin + if (ScreenSong.Mode=smNormal) then + Vis := true + else if (NumCatSongs(CatSongs.Song[S].OrderNum)>0) then + Vis := true; + end; + + CatSongs.Song[S].Visible := vis; end; CatSongs.Selected := CatNumShow; //Show last shown Category CatNumShow := -1; @@ -700,9 +751,11 @@ var begin {fType: 0: All 1: Title - 2: Artist} + 2: Artist + 3: Duet} FilterStr := Trim(FilterStr); - if FilterStr<>'' then begin + if FilterStr<>'' then + begin Result := 0; //Create Search Array SetLength(SearchStr, 1); @@ -742,14 +795,31 @@ begin Song[i].Visible:=False; end; CatNumShow := -2; - end - else begin - for i:=0 to High(Song) do begin + end else if (fType<>3) then + begin + for i:=0 to High(Song) do + begin Song[i].Visible:=(Ini.Tabs=1)=Song[i].Main; + if (ScreenSong.Mode<>smNormal) and Song[i].isDuet then + Song[i].Visible := false; CatNumShow := -1; end; Result := 0; + end else + begin + Result := 0; + for i:=0 to High(Song) do + begin + Song[i].Visible := false; + if not Song[i].Main and Song[i].isDuet then + begin + Song[i].Visible:=true; + inc(Result); + end; + CatNumShow := -2; + end; end; + end; end. \ No newline at end of file diff --git a/Game/Code/Classes/UThemes.pas b/Game/Code/Classes/UThemes.pas index f43143a6..36ac18b4 100644 --- a/Game/Code/Classes/UThemes.pas +++ b/Game/Code/Classes/UThemes.pas @@ -265,6 +265,9 @@ type MedleyIcon: TThemeStatic; CalculatedMedleyIcon: TThemeStatic; + //Duet Icon + DuetIcon: TThemeStatic; + //Show Cat in TopLeft Mod TextCat: TThemeText; StaticCat: TThemeStatic; @@ -335,6 +338,8 @@ type StaticSongName : TThemeStatic; TextSongName : TThemeText; + StaticLyricDuetBar : TThemeStatic; + //TimeBar mod StaticTimeProgress: TThemeStatic; TextTimeText : TThemeText; @@ -1101,6 +1106,9 @@ begin ThemeLoadStatic(Song.MedleyIcon, 'SongMedleyIcon'); ThemeLoadStatic(Song.CalculatedMedleyIcon, 'SongCalculatedMedleyIcon'); + //Duet Icon + ThemeLoadStatic(Song.DuetIcon, 'SongDuetIcon'); + //Show Cat in TopLeft Mod ThemeLoadStatic(Song.StaticCat, 'SongStaticCat'); ThemeLoadText(Song.TextCat, 'SongTextCat'); @@ -1181,6 +1189,8 @@ begin ThemeLoadStatic(Sing.StaticSongName, 'SingSongNameStatic'); ThemeLoadText(Sing.TextSongName, 'SingSongNameText'); + ThemeLoadStatic(Sing.StaticLyricDuetBar, 'SingStaticLyricDuetBar'); + //TimeBar mod ThemeLoadStatic(Sing.StaticTimeProgress, 'SingTimeProgress'); ThemeLoadText(Sing.TextTimeText, 'SingTimeText'); diff --git a/Game/Code/Classes/UVideo.pas b/Game/Code/Classes/UVideo.pas index ee3d2bbd..e59e4179 100644 --- a/Game/Code/Classes/UVideo.pas +++ b/Game/Code/Classes/UVideo.pas @@ -135,6 +135,7 @@ end; procedure Init; begin + inst := nil; videodecoder := nil; VideoOpened:=False; -- cgit v1.2.3