aboutsummaryrefslogtreecommitdiffstats
path: root/Game
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Game/Code/Classes/UDraw.pas880
-rw-r--r--Game/Code/Classes/UFiles.pas481
-rw-r--r--Game/Code/Classes/UGraphic.pas3
-rw-r--r--Game/Code/Classes/ULyrics.pas27
-rw-r--r--Game/Code/Classes/UMain.pas555
-rw-r--r--Game/Code/Classes/UMusic.pas47
-rw-r--r--Game/Code/Classes/UPlaylist.pas5
-rw-r--r--Game/Code/Classes/USongs.pas108
-rw-r--r--Game/Code/Classes/UThemes.pas10
-rw-r--r--Game/Code/Classes/UVideo.pas1
-rw-r--r--Game/Code/Screens/UScreenEditSub.pas2048
-rw-r--r--Game/Code/Screens/UScreenMain.pas2
-rw-r--r--Game/Code/Screens/UScreenOptionsGame.pas28
-rw-r--r--Game/Code/Screens/UScreenPartyOptions.pas4
-rw-r--r--Game/Code/Screens/UScreenPartyOptionsM2.pas3
-rw-r--r--Game/Code/Screens/UScreenSing.pas295
-rw-r--r--Game/Code/Screens/UScreenSong.pas111
-rw-r--r--Game/Code/Screens/UScreenSongJumpto.pas44
-rw-r--r--Game/Code/UltraStar.bdsproj5
-rw-r--r--Game/Code/UltraStar.cfg2
-rw-r--r--Game/Code/UltraStar.dpr11
-rw-r--r--Game/Output/Languages/English.ini12
-rw-r--r--Game/Output/Languages/German.ini14
-rw-r--r--Game/Output/Languages/Italian.ini1020
-rw-r--r--Game/Output/SDL.dllbin324096 -> 320512 bytes
-rw-r--r--Game/Output/Skins/Blue Sensation/[icon]song_duet.jpgbin0 -> 1569 bytes
-rw-r--r--Game/Output/Skins/Blue Sensation/blue sensation170
-rw-r--r--Game/Output/Skins/Blue Sensation/blue sensation.ini1
-rw-r--r--Game/Output/Skins/Blue Sensation/blue simple.ini1
-rw-r--r--Game/Output/Skins/Blue Sensation/city.ini3
-rw-r--r--Game/Output/Skins/Blue Sensation/flower.ini3
-rw-r--r--Game/Output/Skins/Deluxe/Blue.ini1
-rw-r--r--Game/Output/Skins/Deluxe/Fall.ini1
-rw-r--r--Game/Output/Skins/Deluxe/Summer.ini1
-rw-r--r--Game/Output/Skins/Deluxe/Winter.ini1
-rw-r--r--Game/Output/Skins/Deluxe/[icon]song_duet.jpgbin0 -> 1569 bytes
-rw-r--r--Game/Output/Skins/iStar/Apple.ini1
-rw-r--r--Game/Output/Skins/iStar/[icon]song_duet.jpgbin0 -> 1569 bytes
-rw-r--r--Game/Output/Themes/Blue Sensation.ini20
-rw-r--r--Game/Output/Themes/Deluxe.ini20
-rw-r--r--Game/Output/Themes/iStar.ini20
41 files changed, 3134 insertions, 2825 deletions
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;
@@ -281,6 +285,28 @@ begin
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;
+
min := high(integer);
//second try (approximating)
for I := 0 to length(Czesci[0].Czesc) - 1 do
@@ -290,12 +316,31 @@ begin
diff := abs(Czesci[0].Czesc[I].Nuta[J].Start - beat);
if diff<min then
begin
+ Result.CP := 0;
Result.line := I;
Result.note := J;
min := diff;
end;
end;
end;
+
+ 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
+ diff := abs(Czesci[1].Czesc[I].Nuta[J].Start - beat);
+ if diff<min then
+ begin
+ Result.CP := 1;
+ Result.line := I;
+ Result.note := J;
+ min := diff;
+ end;
+ end;
+ end;
+ end;
end;
procedure InitializeSound;
diff --git a/Game/Code/Classes/UPlaylist.pas b/Game/Code/Classes/UPlaylist.pas
index 3c15e893..66bd8189 100644
--- a/Game/Code/Classes/UPlaylist.pas
+++ b/Game/Code/Classes/UPlaylist.pas
@@ -60,7 +60,7 @@ type
implementation
-uses USongs, ULog, UFiles, UGraphic, UThemes, SysUtils;
+uses USongs, ULog, UFiles, UGraphic, UThemes, SysUtils, UMusic;
//----------
//Create - Construct Class - Dummy for now
@@ -247,7 +247,8 @@ begin
//Show Songs in PL
For I := 0 to high(PlayLists[Index].Items) do
begin
- CatSongs.Song[PlayLists[Index].Items[I].SongID].Visible := True;
+ if (ScreenSong.Mode=smNormal) or not CatSongs.Song[PlayLists[Index].Items[I].SongID].isDuet then
+ CatSongs.Song[PlayLists[Index].Items[I].SongID].Visible := True;
end;
//Set CatSongsMode + Playlist Mode
diff --git a/Game/Code/Classes/USongs.pas b/Game/Code/Classes/USongs.pas
index 3c6e147a..cb49ec9d 100644
--- a/Game/Code/Classes/USongs.pas
+++ b/Game/Code/Classes/USongs.pas
@@ -43,6 +43,7 @@ type
Folder: string; // for sorting by folder
FileName: string;
+ isDuet: boolean;
Medley: TMedley;
PreviewStart: real; //in seconds
CustomTags: array of TCustomHeaderTag; // from 1.1
@@ -114,6 +115,8 @@ type
function VisibleIndex(Index: integer): integer; // returns visible song index (skips invisible)
function SetFilter(FilterStr: String; const fType: Byte): Cardinal;
+ function NumCatSongs(Cat: integer): integer;
+ function NumVisibleCats(): integer;
end;
var
@@ -138,7 +141,6 @@ begin
//Set Correct SongArray Length
SetLength(Song, BrowsePos);
-// if Ini.Debug = 1 then BrowseDir('D:\Extract\Songs\');
end;
procedure TSongs.BrowseDir(Dir: string);
@@ -156,8 +158,8 @@ begin
end; // if
FindClose(SR);
- if FindFirst(Dir + '*.txt', 0, SR) = 0 then
- begin
+ if FindFirst(Dir + '*.tx?', 0, SR) = 0 then
+ begin
repeat
//New Mod for better Memory Management
@@ -179,7 +181,11 @@ begin
if res then
begin
Song[SLen]:=AktSong;
- FindRefrainStart(Song[SLen]);
+ //Medley and Duet - is it possible? Perhaps later...
+ if not AktSong.isDuet then
+ FindRefrainStart(Song[SLen])
+ else
+ Song[SLen].Medley.Source := msNone;
// scanning complete, file is good
// if there is no cover then try to find it
@@ -609,8 +615,13 @@ begin
for S := 0 to high(CatSongs.Song) do
begin
if (CatSongs.Song[S].OrderNum = Index) AND (Not CatSongs.Song[S].Main) then
- CatSongs.Song[S].Visible := true
- else
+ begin
+ if ((ScreenSong.Mode<>smNormal) 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;
diff --git a/Game/Code/Screens/UScreenEditSub.pas b/Game/Code/Screens/UScreenEditSub.pas
index 1d8ab390..55748a0e 100644
--- a/Game/Code/Screens/UScreenEditSub.pas
+++ b/Game/Code/Screens/UScreenEditSub.pas
@@ -18,6 +18,11 @@ type
TScreenEditSub = class(TMenu)
private
+ cRB, cGB, cBB: GLfloat;
+ cRR, cGR, cBR: GLfloat;
+
+ offset: array[0..1] of integer;
+
AktBeat: integer;
//Variable is True if no SOng is loaded
Error: Boolean;
@@ -36,7 +41,10 @@ type
TextNTon: integer;
TextNText: integer;
TextVideoGap:integer;
- AktNuta: integer;
+ AktNuta: array[0..1] of integer;
+
+ CP: integer; //actual singer: 0 or 1 (for duet)
+ EditorLyric: array[0..1] of TLyric;
PlaySentence: boolean;
PlaySentenceMidi: boolean;
@@ -64,7 +72,8 @@ type
editText: string; //backup of current text in text-edit-mode
noteStart: integer; //Start note when playing sentence
lineStart: integer; //Start line when playing sentence
- LineChanged: boolean;
+ cpStart: integer; //Start singer when playing sentence
+ LineChanged: array[0..1] of boolean;
VidVis: TVidVis; //video visiability
PlayVideo: boolean;
@@ -84,6 +93,7 @@ type
procedure JoinSentence;
procedure DivideNote;
procedure DeleteNote;
+ procedure DeleteSentence;
procedure TransposeNote(Transpose: integer);
procedure ChangeWholeTone(Tone: integer);
procedure MoveAllToEnd(Move: integer);
@@ -95,8 +105,15 @@ type
//Note Name Mod
function GetNoteName(Note: Integer): String;
function GetMedleyLength: real; //returns if availible the length of the medley in seconds, else 0
- procedure DrawInfoBar(x, y, w, h: integer);
+ procedure DrawInfoBar(P, x, y, w, h: integer);
procedure DrawStatics;
+ procedure SelectNextNote;
+ procedure SelectPrevNote;
+ procedure MakeSingle;
+ procedure MakeDuet;
+ procedure DuetCopyLine;
+ procedure DuetMoveLine;
+ procedure Refresh;
public
Tex_Background: TTexture;
FadeOut: boolean;
@@ -165,9 +182,9 @@ begin
SDLK_BACKQUOTE:
begin
// Increase Note Length (same as Alt + Right)
- Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
- if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
- Inc(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+ Inc(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Dlugosc);
+ if AktNuta[CP] = Czesci[CP].Czesc[Czesci[CP].Akt].HighNut then
+ Inc(Czesci[CP].Czesc[Czesci[CP].Akt].Koniec);
end;
SDLK_EQUALS:
@@ -212,6 +229,7 @@ begin
SDLK_8:
begin
+ temp := 0;
// Increase VideoGAP
if SDL_ModState = 0 then
temp := 1; //10ms
@@ -229,6 +247,7 @@ begin
SDLK_7:
begin
+ temp := 0;
// Decrease VideoGAP
if SDL_ModState = 0 then
temp := -1; //10ms
@@ -264,23 +283,30 @@ begin
SDLK_SLASH:
begin
- if SDL_ModState = 0 then begin
+ if SDL_ModState = 0 then
+ begin
+ if AktSong.isDuet then
+ Exit;
// Insert start of sentece
- if AktNuta > 0 then
+ if AktNuta[CP] > 0 then
begin
DivideSentence;
FixTimings;
- Lyric.Selected := AktNuta;
+ EditorLyric[CP].Selected := AktNuta[CP];
end;
end;
- if SDL_ModState = KMOD_LSHIFT then begin
+ if SDL_ModState = KMOD_LSHIFT then
+ begin
+ if AktSong.isDuet then
+ Exit;
// Join next sentence with current
- if Czesci[0].Akt < Czesci[0].High then
+ if Czesci[CP].Akt < Czesci[CP].High then
JoinSentence;
end;
- if SDL_ModState = KMOD_LCTRL then begin
+ if SDL_ModState = KMOD_LCTRL then
+ begin
// divide note
DivideNote;
end;
@@ -291,7 +317,11 @@ begin
SDLK_S:
begin
//Medley MOD:
- if (MedleyNotes.isStart and MedleyNotes.isEnd) and
+ if AktSong.isDuet then
+ begin
+ AktSong.Medley.Source := msNone;
+ end
+ else if (MedleyNotes.isStart and MedleyNotes.isEnd) and
(MedleyNotes.start.line < MedleyNotes.end_.line) then
begin
AktSong.Medley.Source := msTag;
@@ -300,7 +330,8 @@ begin
Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].Dlugosc;
AktSong.Medley.FadeIn_time := DEFAULT_FADE_IN_TIME;
AktSong.Medley.FadeOut_time := DEFAULT_FADE_OUT_TIME;
- end else begin
+ end else
+ begin
AktSong.Medley.Source := msNone;
AktSong.Medley.StartBeat:=0;
AktSong.Medley.EndBeat:=0;
@@ -311,13 +342,19 @@ begin
begin
if (AktSong.Medley.Source = msTag) then
begin
- ScreenPopupError.ShowPopup(Language.Translate('Medley and Relative is not supported!'));
+ ScreenPopupError.ShowPopup('Medley with Relative is not supported!');
+ Exit;
+ end;
+
+ if (AktSong.isDuet) then
+ begin
+ ScreenPopupError.ShowPopup('Duet with Relative is not supported!');
Exit;
end;
- SResult := SaveSong(AktSong, Czesci[0], Path + FileName, true); //save with relative
+ SResult := SaveSong(AktSong, Czesci, Path + FileName, true); //save with relative
end else
- SResult := SaveSong(AktSong, Czesci[0], Path + FileName, false);
+ SResult := SaveSong(AktSong, Czesci, Path + FileName, false);
if SResult then
begin
@@ -336,7 +373,13 @@ begin
begin
if AktSong.Relative then
begin
- ScreenPopupError.ShowPopup(Language.Translate('Medley and Relative is not supported!'));
+ ScreenPopupError.ShowPopup('Medley with Relative is not supported!');
+ Exit;
+ end;
+
+ if AktSong.isDuet then
+ begin
+ ScreenPopupError.ShowPopup('Medley with Duet is not supported!');
Exit;
end;
@@ -344,45 +387,45 @@ begin
begin
if MedleyNotes.isEnd then
begin
- if (Czesci[0].Akt=MedleyNotes.end_.line) and (AktNuta=MedleyNotes.end_.note) then
+ if (Czesci[0].Akt=MedleyNotes.end_.line) and (AktNuta[0]=MedleyNotes.end_.note) then
begin
MedleyNotes.isEnd := false;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := false;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta[0]].IsMedley := false;
end else
begin
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := true;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta[0]].IsMedley := true;
Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].IsMedley := false;
MedleyNotes.end_.line := Czesci[0].Akt;
- MedleyNotes.end_.note := AktNuta;
+ MedleyNotes.end_.note := AktNuta[0];
end;
end else
begin
MedleyNotes.isEnd := true;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := true;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta[0]].IsMedley := true;
MedleyNotes.end_.line := Czesci[0].Akt;
- MedleyNotes.end_.note := AktNuta;
+ MedleyNotes.end_.note := AktNuta[0];
end;
end else
begin //Medley Start Note
if MedleyNotes.isStart then
begin
- if (Czesci[0].Akt=MedleyNotes.start.line) and (AktNuta=MedleyNotes.start.note) then
+ if (Czesci[0].Akt=MedleyNotes.start.line) and (AktNuta[0]=MedleyNotes.start.note) then
begin
MedleyNotes.isStart := false;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := false;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta[0]].IsMedley := false;
end else
begin
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := true;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta[0]].IsMedley := true;
Czesci[0].Czesc[MedleyNotes.start.line].Nuta[MedleyNotes.start.note].IsMedley := false;
MedleyNotes.start.line := Czesci[0].Akt;
- MedleyNotes.start.note := AktNuta;
+ MedleyNotes.start.note := AktNuta[0];
end;
end else
begin
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsMedley := true;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta[0]].IsMedley := true;
MedleyNotes.isStart := true;
MedleyNotes.start.line := Czesci[0].Akt;
- MedleyNotes.start.note := AktNuta;
+ MedleyNotes.start.note := AktNuta[0];
end;
end;
@@ -396,7 +439,13 @@ begin
begin
if AktSong.Relative then
begin
- ScreenPopupError.ShowPopup(Language.Translate('Medley and Relative is not supported!'));
+ ScreenPopupError.ShowPopup('Medley with Relative is not supported!');
+ Exit;
+ end;
+
+ if AktSong.isDuet then
+ begin
+ ScreenPopupError.ShowPopup('Medley with Duet is not supported!');
Exit;
end;
@@ -406,13 +455,13 @@ begin
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta[0]].Color := 0;
Czesci[0].Akt := MedleyNotes.end_.line;
- AktNuta := MedleyNotes.end_.note;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
+ AktNuta[0] := MedleyNotes.end_.note;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta[0]].Color := 2;
- Lyric.AddCzesc(Czesci[0].Akt);
- Lyric.Selected := AktNuta;
+ EditorLyric[0].AddCzesc(0, Czesci[0].Akt);
+ EditorLyric[0].Selected := AktNuta[0];
Music.Stop;
PlaySentence := false;
PlayOneNote := false;
@@ -422,13 +471,13 @@ begin
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta[0]].Color := 0;
Czesci[0].Akt := MedleyNotes.start.line;
- AktNuta := MedleyNotes.start.note;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
+ AktNuta[0] := MedleyNotes.start.note;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta[0]].Color := 2;
- Lyric.AddCzesc(Czesci[0].Akt);
- Lyric.Selected := AktNuta;
+ EditorLyric[0].AddCzesc(0, Czesci[0].Akt);
+ EditorLyric[0].Selected := AktNuta[0];
Music.Stop;
PlaySentence := false;
PlayOneNote := false;
@@ -439,13 +488,16 @@ begin
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Music.Stop;
- LineChanged:=false;
+ LineChanged[0]:=false;
+ LineChanged[1]:=false;
R := GetTimeFromBeat(Czesci[0].Czesc[MedleyNotes.start.line].Nuta[MedleyNotes.start.note].Start);
- if R <= Music.Length then begin
+ if R <= Music.Length then
+ begin
Music.MoveTo(R);
- noteStart := AktNuta;
+ noteStart := AktNuta[0];
lineStart := Czesci[0].Akt;
+ cpStart := 0;
PlayStopTime := GetTimeFromBeat(
Czesci[0].Czesc[MedleyNotes.end_.line].Nuta[MedleyNotes.end_.note].Start +
@@ -466,32 +518,44 @@ begin
begin
if (SDL_ModState = KMOD_LSHIFT) then //jump to...
begin
- MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ MidiOut.PutShort($81, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
- Czesci[0].Akt := MedleyNotes.Preview.line;
- AktNuta := MedleyNotes.Preview.note;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
+ Refresh;
- Lyric.AddCzesc(Czesci[0].Akt);
- Lyric.Selected := AktNuta;
+ CP := MedleyNotes.Preview.CP;
+ Czesci[CP].Akt := MedleyNotes.Preview.line;
+ Czesci[(CP+1) mod 2].Akt := Czesci[CP].Akt;
+
+ AktNuta[CP] := MedleyNotes.Preview.note;
+ AktNuta[(CP+1) mod 2] := 0;
+
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+
+ EditorLyric[CP].AddCzesc(CP, Czesci[CP].Akt);
+ EditorLyric[CP].Selected := AktNuta[CP];
+ EditorLyric[(CP+1) mod 2].AddCzesc((CP+1) mod 2, Czesci[(CP+1) mod 2].Akt);
+ EditorLyric[(CP+1) mod 2].Selected := -1;
Music.Stop;
PlaySentence := false;
PlayOneNote := false;
end else
begin
- if (Czesci[0].Akt = MedleyNotes.Preview.line) and (AktNuta = MedleyNotes.Preview.note) then //reset ?
+ if (CP = MedleyNotes.Preview.CP) and
+ (Czesci[CP].Akt = MedleyNotes.Preview.line) and
+ (AktNuta[CP] = MedleyNotes.Preview.note) then //reset ?
begin
end else //set
begin
- Czesci[0].Czesc[MedleyNotes.Preview.line].Nuta[MedleyNotes.Preview.note].IsStartPreview := false;
- MedleyNotes.Preview.line := Czesci[0].Akt;
- MedleyNotes.Preview.note := AktNuta;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsStartPreview := true;
- AktSong.PreviewStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].start);
+ if (Length(Czesci[MedleyNotes.Preview.CP].Czesc[MedleyNotes.Preview.line].Nuta)>MedleyNotes.Preview.note) then
+ Czesci[MedleyNotes.Preview.CP].Czesc[MedleyNotes.Preview.line].Nuta[MedleyNotes.Preview.note].IsStartPreview := false;
+ MedleyNotes.Preview.CP := CP;
+ MedleyNotes.Preview.line := Czesci[CP].Akt;
+ MedleyNotes.Preview.note := AktNuta[CP];
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].IsStartPreview := true;
+ AktSong.PreviewStart := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].start);
end;
end;
end;
@@ -502,6 +566,14 @@ begin
// Divide lengths by 2
if (SDL_ModState = KMOD_LSHIFT) then
CzesciDivide;
+
+ if (SDL_ModState = KMOD_LCTRL or KMOD_LSHIFT) then
+ begin
+ if AktSong.isDuet then
+ MakeSingle
+ else
+ MakeDuet;
+ end;
end;
SDLK_M:
@@ -518,13 +590,16 @@ begin
begin
LyricsCapitalize;
Text[TextDebug].Text := Language.Translate('EDITOR_CAPITALIZE_LETTER');
- Lyric.Selected := AktNuta;
+ EditorLyric[CP].Selected := AktNuta[CP];
end;
// Correct spaces
if SDL_ModState = KMOD_LSHIFT then
LyricsCorrectSpaces;
+ if AktSong.isDuet then
+ Exit;
+
// Copy sentence
if SDL_ModState = KMOD_LCTRL then
MarkSrc;
@@ -543,15 +618,15 @@ begin
SDLK_V:
begin
// Paste text
- if SDL_ModState = KMOD_LCTRL then begin
- if Czesci[0].Czesc[Czesci[0].Akt].IlNut >= Czesci[0].Czesc[CopySrc].IlNut then
+ if SDL_ModState = KMOD_LCTRL then begin //TODO !!!
+ if Czesci[CP].Czesc[Czesci[CP].Akt].IlNut >= Czesci[CP].Czesc[CopySrc].IlNut then
PasteText
else
beep;
end;
- if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
- CopySentence(CopySrc, Czesci[0].Akt);
+ if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin //TODO !!!
+ CopySentence(CopySrc, Czesci[CP].Akt);
end;
if SDL_ModState = 0 then
@@ -566,7 +641,11 @@ begin
SDLK_4:
begin
- if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
+ if AktSong.isDuet then //TODO !!!
+ Exit;
+
+ if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then
+ begin
CopySentence(CopySrc, Czesci[0].Akt);
CopySentence(CopySrc+1, Czesci[0].Akt+1);
CopySentence(CopySrc+2, Czesci[0].Akt+2);
@@ -579,7 +658,11 @@ begin
end;
SDLK_5:
begin
- if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
+ if AktSong.isDuet then //TODO !!!
+ Exit;
+
+ if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then
+ begin
CopySentence(CopySrc, Czesci[0].Akt);
CopySentence(CopySrc+1, Czesci[0].Akt+1);
CopySentence(CopySrc+2, Czesci[0].Akt+2);
@@ -587,7 +670,8 @@ begin
CopySentence(CopySrc+4, Czesci[0].Akt+4);
end;
- if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then begin
+ if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then
+ begin
CopySentences(CopySrc, Czesci[0].Akt, 5);
end;
end;
@@ -597,13 +681,13 @@ begin
// Fixes timings between sentences
FixTimings;
Text[TextDebug].Text := Language.Translate('EDITOR_FIX_TIMINGS');
- Lyric.Selected := AktNuta;
+ EditorLyric[CP].Selected := AktNuta[CP];
end;
SDLK_F4:
begin
// Enter Text Edit Mode
- editText := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
+ editText := Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Tekst;
TextEditMode := true;
end;
@@ -616,17 +700,19 @@ begin
SDLK_P:
begin
- if SDL_ModState = 0 then begin
+ if SDL_ModState = 0 then
+ begin
// Play Sentence
- MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ MidiOut.PutShort($81, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Click := true;
Music.Stop;
- R := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
- if R <= Music.Length then begin
+ R := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].StartNote);
+ if R <= Music.Length then
+ begin
Music.MoveTo(R);
- PlayStopTime := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+ PlayStopTime := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].Koniec);
PlaySentence := true;
PlayOneNote := false;
Music.Play;
@@ -634,47 +720,51 @@ begin
end;
end;
- if SDL_ModState = KMOD_LSHIFT then begin
+ if SDL_ModState = KMOD_LSHIFT then
+ begin
PlaySentenceMidi := true;
PlayOneNoteMidi := false;
MidiTime := USTime.GetTime;
Music.Stop;
PlaySentence := false;
PlayOneNote := false;
- MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
- MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+ MidiStart := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].StartNote);
+ MidiStop := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].Koniec);
LastClick := -100;
end;
- if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL then begin
+ if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL then
+ begin
PlaySentenceMidi := true;
PlayOneNoteMidi := false;
MidiTime := USTime.GetTime;
- MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
- MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+ MidiStart := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].StartNote);
+ MidiStop := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].Koniec);
LastClick := -100;
PlaySentence := true;
PlayOneNote := false;
Click := true;
Music.Stop;
- Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote)+0{-0.10});
- PlayStopTime := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec)+0;
+ Music.MoveTo(GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].StartNote)+0{-0.10});
+ PlayStopTime := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].Koniec)+0;
Music.Play;
LastClick := -100;
end;
//new: play hole file + LALT
- if SDL_ModState = KMOD_LALT then begin
+ if SDL_ModState = KMOD_LALT then
+ begin
// Play Sentence
- MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ MidiOut.PutShort($81, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Click := true;
Music.Stop;
- R := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
- if R <= Music.Length then begin
+ R := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].StartNote);
+ if R <= Music.Length then
+ begin
Music.MoveTo(R);
PlayStopTime := Music.Length;
PlaySentence := true;
@@ -684,24 +774,26 @@ begin
end;
end;
- if SDL_ModState = KMOD_LSHIFT or KMOD_LALT then begin
+ if SDL_ModState = KMOD_LSHIFT or KMOD_LALT then
+ begin
PlaySentenceMidi := true;
PlayOneNoteMidi := false;
Music.Stop;
PlaySentence := false;
PlayOneNote := false;
MidiTime := USTime.GetTime;
- MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
+ MidiStart := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].StartNote);
MidiStop := Music.Length;
LastClick := -100;
end;
- if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL or KMOD_LALT then begin
+ if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL or KMOD_LALT then
+ begin
PlaySentenceMidi := true;
PlayOneNoteMidi := false;
MidiTime := USTime.GetTime;
- MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
+ MidiStart := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].StartNote);
MidiStop := Music.Length;
LastClick := -100;
@@ -709,7 +801,7 @@ begin
PlayOneNote := false;
Click := true;
Music.Stop;
- Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote)+0{-0.10});
+ Music.MoveTo(GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].StartNote)+0{-0.10});
PlayStopTime := Music.Length;
Music.Play;
LastClick := -100;
@@ -717,13 +809,15 @@ begin
if PlaySentenceMidi or PlaySentence then
begin
- noteStart := AktNuta;
- lineStart := Czesci[0].Akt;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
- AktNuta := 0;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
- Lyric.Selected := AktNuta;
- LineChanged:=false;
+ noteStart := AktNuta[CP];
+ lineStart := Czesci[CP].Akt;
+ cpStart := CP;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 0;
+ AktNuta[CP] := 0;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+ EditorLyric[CP].Selected := AktNuta[CP];
+ LineChanged[0]:=false;
+ LineChanged[1]:=false;
PlayVideo := false;
end;
@@ -732,35 +826,37 @@ begin
SDLK_SPACE:
begin
//Thx to f1fth_freed0m for his One Note Midi Playback
- if SDL_ModState = KMOD_LSHIFT then begin //Play One Notes Midi [Shift + Space]
+ if SDL_ModState = KMOD_LSHIFT then
+ begin //Play One Notes Midi [Shift + Space]
PlaySentenceMidi := false;
PlayOneNoteMidi := true;
Music.Stop;
PlaySentence := false;
PlayOneNote := false;
MidiTime := USTime.GetTime;
- MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
- MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
+ MidiStart := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Start);
+ MidiStop := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Dlugosc);
LastClick := -100;
end
- else if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL then begin
+ else if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL then
+ begin
//Play One Notes Midi + MP3 [CTRL + Shift + Space]
PlaySentenceMidi := false;
PlayOneNoteMidi := true;
MidiTime := USTime.GetTime;
- MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
- MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
+ MidiStart := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Start);
+ MidiStop := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Dlugosc);
LastClick := -100;
PlaySentence := false;
PlayOneNote := true;
Click := true;
Music.Stop;
- Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start));
+ Music.MoveTo(GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Start));
PlayStopTime := (GetTimeFromBeat(
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start +
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc));
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Start +
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Dlugosc));
Music.Play;
LastClick := -100;
end
@@ -768,7 +864,7 @@ begin
Else
begin
// Play One Notes MP3 [Space]
- MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ MidiOut.PutShort($81, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false; // stop midi
PlayOneNoteMidi := false;
PlaySentence := false;
@@ -776,10 +872,10 @@ begin
Click := false;
Music.Stop;
- Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start));
+ Music.MoveTo(GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Start));
PlayStopTime := (GetTimeFromBeat(
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start +
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc));
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Start +
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Dlugosc));
Music.Play;
LastClick := -100;
end;
@@ -794,7 +890,9 @@ begin
SDLK_DELETE:
begin
- if SDL_ModState = KMOD_LCTRL then begin
+
+ if SDL_ModState = KMOD_LCTRL then
+ begin
// moves text to right in current sentence
DeleteNote;
end;
@@ -803,6 +901,8 @@ begin
SDLK_PERIOD:
begin
// moves text to right in current sentence
+ if AktSong.isDuet then
+ Exit;
MoveTextToRight;
end;
@@ -810,67 +910,81 @@ begin
begin
if PlaySentenceMidi or PlaySentence then
begin
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
- if (lineStart = Czesci[0].Akt) then
- AktNuta := noteStart;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 0;
- Dec(AktNuta);
- if AktNuta = -1 then AktNuta := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
- Lyric.Selected := AktNuta;
+ if (cpStart = CP) and (lineStart = Czesci[CP].Akt) then
+ AktNuta[CP] := noteStart;
+
+ Dec(AktNuta[CP]);
+ if AktNuta[CP] = -1 then AktNuta[CP] := Czesci[CP].Czesc[Czesci[CP].Akt].HighNut;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+ EditorLyric[CP].Selected := AktNuta[CP];
end;
- MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ MidiOut.PutShort($81, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Music.Stop;
- LineChanged:=false;
+ LineChanged[0]:=false;
+ LineChanged[1]:=false;
PlaySentence := false;
PlayOneNote := false;
// right
- if SDL_ModState = 0 then begin
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
- Inc(AktNuta);
- if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].IlNut then AktNuta := 0;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
- Lyric.Selected := AktNuta;
+ if SDL_ModState = 0 then
+ begin
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 0;
+ Inc(AktNuta[CP]);
+
+ if AktNuta[CP] = Czesci[CP].Czesc[Czesci[CP].Akt].IlNut then AktNuta[CP] := 0;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+ EditorLyric[CP].Selected := AktNuta[CP];
end;
// ctrl + right
- if SDL_ModState = KMOD_LCTRL then begin
- if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc > 1 then begin
- Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
- Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
- if AktNuta = 0 then begin
- Inc(Czesci[0].Czesc[Czesci[0].Akt].Start);
- Inc(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
+ if SDL_ModState = KMOD_LCTRL then
+ begin
+ if Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Dlugosc > 1 then
+ begin
+ Dec(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Dlugosc);
+ Inc(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Start);
+ if AktNuta[CP] = 0 then
+ begin
+ Inc(Czesci[CP].Czesc[Czesci[CP].Akt].Start);
+ Inc(Czesci[CP].Czesc[Czesci[CP].Akt].StartNote);
end;
FixTimings;
end;
end;
// shift + right
- if SDL_ModState = KMOD_LSHIFT then begin
- Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
- if AktNuta = 0 then begin
- Inc(Czesci[0].Czesc[Czesci[0].Akt].Start);
- Inc(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
+ if SDL_ModState = KMOD_LSHIFT then
+ begin
+ Inc(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Start);
+ if AktNuta[CP] = 0 then
+ begin
+ Inc(Czesci[CP].Czesc[Czesci[CP].Akt].Start);
+ Inc(Czesci[CP].Czesc[Czesci[CP].Akt].StartNote);
end;
- if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
- Inc(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+ if AktNuta[CP] = Czesci[CP].Czesc[Czesci[CP].Akt].HighNut then
+ Inc(Czesci[CP].Czesc[Czesci[CP].Akt].Koniec);
FixTimings;
end;
// alt + right
- if SDL_ModState = KMOD_LALT then begin
- Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
- if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
- Inc(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+ if SDL_ModState = KMOD_LALT then
+ begin
+ Inc(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Dlugosc);
+ if AktNuta[CP] = Czesci[CP].Czesc[Czesci[CP].Akt].HighNut then
+ Inc(Czesci[CP].Czesc[Czesci[CP].Akt].Koniec);
FixTimings;
end;
// alt + ctrl + shift + right = move all from cursor to right
- if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then begin
+ if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then
+ begin
+ if AktSong.isDuet then
+ Exit;
+
MoveAllToEnd(1);
FixTimings;
end;
@@ -880,70 +994,81 @@ begin
begin
if PlaySentenceMidi or PlaySentence then
begin
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
- if (lineStart = Czesci[0].Akt) then
- AktNuta := noteStart;
-
- Inc(AktNuta);
- if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].IlNut then AktNuta := 0;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
- Lyric.Selected := AktNuta;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 0;
+ if (cpStart = CP) and (lineStart = Czesci[CP].Akt) then
+ AktNuta[CP] := noteStart;
+
+ Inc(AktNuta[CP]);
+ if AktNuta[CP] = Czesci[CP].Czesc[Czesci[CP].Akt].IlNut then AktNuta[CP] := 0;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+ EditorLyric[CP].Selected := AktNuta[CP];
end;
- MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ MidiOut.PutShort($81, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Music.Stop;
- LineChanged:=false;
+ LineChanged[0]:=false;
+ LineChanged[1]:=false;
PlaySentence := false;
PlayOneNote := false;
// left
- if SDL_ModState = 0 then begin
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
- Dec(AktNuta);
- if AktNuta = -1 then AktNuta := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
- Lyric.Selected := AktNuta;
+ if SDL_ModState = 0 then
+ begin
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 0;
+ Dec(AktNuta[CP]);
+ if AktNuta[CP] = -1 then
+ AktNuta[CP] := Czesci[CP].Czesc[Czesci[CP].Akt].HighNut;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+ EditorLyric[CP].Selected := AktNuta[CP];
end;
// ctrl + left
- if SDL_ModState = KMOD_LCTRL then begin
- Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
- Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
- if AktNuta = 0 then begin
- Dec(Czesci[0].Czesc[Czesci[0].Akt].Start);
- Dec(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
+ if SDL_ModState = KMOD_LCTRL then
+ begin
+ Dec(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Start);
+ Inc(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Dlugosc);
+ if AktNuta[CP] = 0 then begin
+ Dec(Czesci[CP].Czesc[Czesci[CP].Akt].Start);
+ Dec(Czesci[CP].Czesc[Czesci[CP].Akt].StartNote);
end;
FixTimings;
end;
// shift + left
- if SDL_ModState = KMOD_LSHIFT then begin
- Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
+ if SDL_ModState = KMOD_LSHIFT then
+ begin
+ Dec(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Start);
// resizing sentences
- if AktNuta = 0 then begin
- Dec(Czesci[0].Czesc[Czesci[0].Akt].Start);
- Dec(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
+ if AktNuta[CP] = 0 then
+ begin
+ Dec(Czesci[CP].Czesc[Czesci[CP].Akt].Start);
+ Dec(Czesci[CP].Czesc[Czesci[CP].Akt].StartNote);
end;
- if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
- Dec(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+ if AktNuta[CP] = Czesci[CP].Czesc[Czesci[CP].Akt].HighNut then
+ Dec(Czesci[CP].Czesc[Czesci[CP].Akt].Koniec);
FixTimings;
end;
// alt + left
- if SDL_ModState = KMOD_LALT then begin
- if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc > 1 then begin
- Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
- if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
- Dec(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+ if SDL_ModState = KMOD_LALT then
+ begin
+ if Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Dlugosc > 1 then
+ begin
+ Dec(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Dlugosc);
+ if AktNuta[CP] = Czesci[CP].Czesc[Czesci[CP].Akt].HighNut then
+ Dec(Czesci[CP].Czesc[Czesci[CP].Akt].Koniec);
end;
FixTimings;
end;
// alt + ctrl + shift + right = move all from cursor to left
- if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then begin
+ if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then
+ begin
+ if AktSong.isDuet then
+ Exit;
MoveAllToEnd(-1);
FixTimings;
end;
@@ -951,88 +1076,122 @@ begin
SDLK_DOWN:
begin
- MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ MidiOut.PutShort($81, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Music.Stop;
- LineChanged:=false;
+ LineChanged[0]:=false;
+ LineChanged[1]:=false;
PlaySentence := false;
PlayOneNote := false;
// skip to next sentence
- if SDL_ModState = 0 then begin
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
- Inc(Czesci[0].Akt);
- AktNuta := 0;
- if Czesci[0].Akt > Czesci[0].High then
- Czesci[0].Akt := 0;
-
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
-
- Lyric.AddCzesc(Czesci[0].Akt);
- Lyric.Selected := 0;
+ if SDL_ModState = 0 then
+ begin
+ Refresh;
+ Inc(Czesci[CP].Akt);
+ AktNuta[0] := 0;
+ AktNuta[1] := 0;
+ if Czesci[CP].Akt > Czesci[CP].High then
+ Czesci[CP].Akt := 0;
+
+ SelectNextNote;
end;
// decrease tone
- if SDL_ModState = KMOD_LCTRL then begin
+ if SDL_ModState = KMOD_LCTRL then
+ begin
TransposeNote(-1);
end;
+ // select singer 2 notes if possible
+ if (SDL_ModState = KMOD_LSHIFT) and AktSong.isDuet then
+ begin
+ if (Length(Czesci[1].Czesc[Czesci[1].Akt].Nuta)>0) then
+ begin
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 0;
+ CP := 1;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+ end;
+ end;
+
+ if AktSong.isDuet and (SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL) and (CP=0) then
+ DuetCopyLine;
+
+ if AktSong.isDuet and (SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL or KMOD_LALT) and (CP=0) then
+ DuetMoveLine;
end;
SDLK_UP:
begin
- MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ MidiOut.PutShort($81, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Music.Stop;
- LineChanged:=false;
+ LineChanged[0]:=false;
+ LineChanged[1]:=false;
PlaySentence := false;
PlayOneNote := false;
// skip to previous sentence
- if SDL_ModState = 0 then begin
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
- Dec(Czesci[0].Akt);
- AktNuta := 0;
- if Czesci[0].Akt = -1 then
- Czesci[0].Akt := Czesci[0].High;
-
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
+ if SDL_ModState = 0 then
+ begin
+ Refresh;
+ Dec(Czesci[CP].Akt);
+ AktNuta[CP] := 0;
+ if Czesci[CP].Akt = -1 then
+ Czesci[CP].Akt := Czesci[CP].High;
- Lyric.AddCzesc(Czesci[0].Akt);
- Lyric.Selected := 0;
+ SelectPrevNote;
end;
// increase tone
- if SDL_ModState = KMOD_LCTRL then begin
+ if SDL_ModState = KMOD_LCTRL then
+ begin
TransposeNote(1);
end;
+
+ // select singer 1 notes if possible
+ if (SDL_ModState = KMOD_LSHIFT) and AktSong.isDuet then
+ begin
+ if (Length(Czesci[0].Czesc[Czesci[0].Akt].Nuta)>0) then
+ begin
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 0;
+ CP := 0;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+ end;
+ end;
+
+ if AktSong.isDuet and (SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL) and (CP=1) then
+ DuetCopyLine;
+
+ if AktSong.isDuet and (SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL or KMOD_LALT) and (CP=1) then
+ DuetMoveLine;
end;
// Golden Note Patch
SDLK_G:
begin
- case Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc of
- 0, 1: Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 2;
- 2: Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 1;
+ case Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Wartosc of
+ 0, 1: Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Wartosc := 2;
+ 2: Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Wartosc := 1;
end; // case
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Freestyle := False;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Freestyle := False;
end;
// Freestyle Note Patch
SDLK_F:
begin
- case Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc of
+ case Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Wartosc of
0:
begin;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 1;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Freestyle := False;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Wartosc := 1;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Freestyle := False;
end;
1,2:
begin;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 0;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Freestyle := True;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Wartosc := 0;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Freestyle := True;
end;
end; // case
@@ -1055,7 +1214,6 @@ begin
Music.SetMusicVolume(MP3Volume);
Text[TextDebug].Text := 'MP3 Volume: ' + IntToStr(MP3Volume) + '%';
end;
-
end;
end;
end; // if
@@ -1077,11 +1235,11 @@ begin
// check normal keys
if not (ScanCode in [0..31, 127..159]) then //=isPrintable
begin
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst :=
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst + chr(ScanCode);
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Tekst :=
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Tekst + chr(ScanCode);
- Lyric.ChangeCurText(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst);
- Lyric.AddCzesc(Czesci[0].Akt);
+ EditorLyric[CP].ChangeCurText(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Tekst);
+ EditorLyric[CP].AddCzesc(CP, Czesci[CP].Akt);
Exit;
end;
@@ -1090,8 +1248,8 @@ begin
case PressedKey of
SDLK_ESCAPE:
begin
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst := editText;
- Lyric.AddCzesc(Czesci[0].Akt);
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Tekst := editText;
+ EditorLyric[CP].AddCzesc(CP, Czesci[CP].Akt);
TextEditMode := false;
end;
SDLK_F4, SDLK_RETURN:
@@ -1099,37 +1257,41 @@ begin
// Exit Text Edit Mode
TextEditMode := false;
end;
-
+
SDLK_BACKSPACE:
begin
- Delete(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst,
- Length(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst), 1);
+ Delete(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Tekst,
+ Length(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Tekst), 1);
- Lyric.ChangeCurText(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst);
- Lyric.AddCzesc(Czesci[0].Akt);
+ EditorLyric[CP].ChangeCurText(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Tekst);
+ EditorLyric[CP].AddCzesc(CP, Czesci[CP].Akt);
end;
SDLK_RIGHT:
begin
// right
- if SDL_ModState = 0 then begin
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
- Inc(AktNuta);
- if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].IlNut then AktNuta := 0;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
- Lyric.Selected := AktNuta;
- editText := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
+ if SDL_ModState = 0 then
+ begin
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 0;
+ Inc(AktNuta[CP]);
+ if AktNuta[CP] = Czesci[CP].Czesc[Czesci[CP].Akt].IlNut then
+ AktNuta[CP] := 0;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+ EditorLyric[CP].Selected := AktNuta[CP];
+ editText := Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Tekst;
end;
end;
SDLK_LEFT:
begin
// left
- if SDL_ModState = 0 then begin
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
- Dec(AktNuta);
- if AktNuta = -1 then AktNuta := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
- Lyric.Selected := AktNuta;
- editText := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
+ if SDL_ModState = 0 then
+ begin
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 0;
+ Dec(AktNuta[CP]);
+ if AktNuta[CP] = -1 then
+ AktNuta[CP] := Czesci[CP].Czesc[Czesci[CP].Akt].HighNut;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+ EditorLyric[CP].Selected := AktNuta[CP];
+ editText := Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Tekst;
end;
end;
end;
@@ -1196,7 +1358,7 @@ var
begin
// Play Sentences with Video
- MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ MidiOut.PutShort($81, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Click := false;
@@ -1204,10 +1366,12 @@ begin
if PlayVideo then
begin
- Czesci[0].Akt := lineStart;
- AktNuta := noteStart;
+ CP := cpStart;
+ Czesci[CP].Akt := lineStart;
+ AktNuta[CP] := noteStart;
end;
- R := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
+
+ R := GetTimeFromBeat(Czesci[CP].Czesc[Czesci[CP].Akt].StartNote);
if R <= Music.Length then
begin
Music.MoveTo(R);
@@ -1218,13 +1382,15 @@ begin
LastClick := -100;
end;
- noteStart := AktNuta;
- lineStart := Czesci[0].Akt;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
- AktNuta := 0;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
- Lyric.Selected := AktNuta;
- LineChanged:=false;
+ noteStart := AktNuta[CP];
+ lineStart := Czesci[CP].Akt;
+ cpStart := CP;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 0;
+ AktNuta[CP] := 0;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+ EditorLyric[CP].Selected := AktNuta[CP];
+ LineChanged[0]:=false;
+ LineChanged[1]:=false;
PlayTime := 0;
PlayVideo := true;
StartVideoPreview;
@@ -1279,6 +1445,7 @@ end;
procedure TScreenEditSub.ChangeBPM(newBPM: real);
var
+ P: integer;
C: integer;
N: integer;
f: real;
@@ -1287,145 +1454,150 @@ begin
f := newBPM/AktSong.BPM[0].BPM; //z.B. neu/alt => 1/2 = 0.5 => *0.5
AktSong.BPM[0].BPM := newBPM;
- for C := 0 to Czesci[0].High do
+ for P := 0 to Length(Czesci) - 1 do
begin
- Czesci[0].Czesc[C].Start := ceil(Czesci[0].Czesc[C].Start *f);
- Czesci[0].Czesc[C].StartNote := ceil(Czesci[0].Czesc[C].StartNote *f);
- for N := 0 to Czesci[0].Czesc[C].HighNut do
+ for C := 0 to Czesci[P].High do
begin
- Czesci[0].Czesc[C].Nuta[N].Start := ceil(Czesci[0].Czesc[C].Nuta[N].Start *f);
- Czesci[0].Czesc[C].Nuta[N].Dlugosc := floor(Czesci[0].Czesc[C].Nuta[N].Dlugosc *f);
- if (Czesci[0].Czesc[C].Nuta[N].Dlugosc=0) then
- Czesci[0].Czesc[C].Nuta[N].Dlugosc := 1;
- end; // N (notes)
- Czesci[0].Czesc[C].Koniec := Czesci[0].Czesc[C].Nuta[Czesci[0].Czesc[C].HighNut].Start +
- Czesci[0].Czesc[C].Nuta[Czesci[0].Czesc[C].HighNut].Dlugosc;
- end; // C (lines)
+ Czesci[P].Czesc[C].Start := ceil(Czesci[P].Czesc[C].Start *f);
+ Czesci[P].Czesc[C].StartNote := ceil(Czesci[P].Czesc[C].StartNote *f);
+ if (Length(Czesci[P].Czesc[C].Nuta)>0) then
+ begin
+ for N := 0 to Czesci[P].Czesc[C].HighNut do
+ begin
+ Czesci[P].Czesc[C].Nuta[N].Start := ceil(Czesci[P].Czesc[C].Nuta[N].Start *f); //round up
+ Czesci[P].Czesc[C].Nuta[N].Dlugosc := floor(Czesci[P].Czesc[C].Nuta[N].Dlugosc *f); //round down
+ if (Czesci[P].Czesc[C].Nuta[N].Dlugosc=0) then
+ Czesci[P].Czesc[C].Nuta[N].Dlugosc := 1;
+ end; // N (notes)
+ Czesci[P].Czesc[C].Koniec := Czesci[P].Czesc[C].Nuta[Czesci[P].Czesc[C].HighNut].Start +
+ Czesci[P].Czesc[C].Nuta[Czesci[P].Czesc[C].HighNut].Dlugosc;
+ end else
+ Czesci[P].Czesc[C].Koniec := round(Czesci[P].Czesc[C].Koniec * f);
+ end; // C (lines)
+ end;
end;
procedure TScreenEditSub.CzesciDivide;
-var
- C: integer;
- N: integer;
-begin
- AktSong.BPM[0].BPM := AktSong.BPM[0].BPM / 2;
- for C := 0 to Czesci[0].High do begin
- Czesci[0].Czesc[C].Start := Czesci[0].Czesc[C].Start div 2;
- Czesci[0].Czesc[C].StartNote := Czesci[0].Czesc[C].StartNote div 2;
- Czesci[0].Czesc[C].Koniec := Czesci[0].Czesc[C].Koniec div 2;
- for N := 0 to Czesci[0].Czesc[C].HighNut do begin
- Czesci[0].Czesc[C].Nuta[N].Start := Czesci[0].Czesc[C].Nuta[N].Start div 2;
- Czesci[0].Czesc[C].Nuta[N].Dlugosc := Round(Czesci[0].Czesc[C].Nuta[N].Dlugosc / 2);
- end; // N
- end; // C
+begin
+ ChangeBPM(AktSong.BPM[0].BPM / 2);
end;
procedure TScreenEditSub.CzesciMultiply;
-var
- C: integer;
- N: integer;
begin
- AktSong.BPM[0].BPM := AktSong.BPM[0].BPM * 2;
- for C := 0 to Czesci[0].High do begin
- Czesci[0].Czesc[C].Start := Czesci[0].Czesc[C].Start * 2;
- Czesci[0].Czesc[C].StartNote := Czesci[0].Czesc[C].StartNote * 2;
- Czesci[0].Czesc[C].Koniec := Czesci[0].Czesc[C].Koniec * 2;
- for N := 0 to Czesci[0].Czesc[C].HighNut do begin
- Czesci[0].Czesc[C].Nuta[N].Start := Czesci[0].Czesc[C].Nuta[N].Start * 2;
- Czesci[0].Czesc[C].Nuta[N].Dlugosc := Czesci[0].Czesc[C].Nuta[N].Dlugosc * 2;
- end; // N
- end; // C
+ ChangeBPM(AktSong.BPM[0].BPM * 2);
end;
procedure TScreenEditSub.LyricsCapitalize;
var
+ P: integer;
C: integer;
- //N: integer; // temporary
S: string;
begin
- // temporary
-{ for C := 0 to Czesci[0].High do
- for N := 0 to Czesci[0].Czesc[C].HighNut do
- Czesci[0].Czesc[C].Nuta[N].Tekst := AnsiLowerCase(Czesci[0].Czesc[C].Nuta[N].Tekst);}
-
- for C := 0 to Czesci[0].High do begin
- S := AnsiUpperCase(Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 1, 1));
- S := S + Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 2, Length(Czesci[0].Czesc[C].Nuta[0].Tekst)-1);
- Czesci[0].Czesc[C].Nuta[0].Tekst := S;
- end; // C
- Lyric.AddCzesc(Czesci[0].Akt);
+ for P := 0 to Length(Czesci) - 1 do
+ begin
+ for C := 0 to Czesci[P].High do
+ begin
+ if (Length(Czesci[P].Czesc[C].Nuta)>0) then
+ begin
+ S := AnsiUpperCase(Copy(Czesci[P].Czesc[C].Nuta[0].Tekst, 1, 1));
+ S := S + Copy(Czesci[P].Czesc[C].Nuta[0].Tekst, 2, Length(Czesci[P].Czesc[C].Nuta[0].Tekst)-1);
+ Czesci[P].Czesc[C].Nuta[0].Tekst := S;
+ end;
+ end; // C
+ EditorLyric[P].AddCzesc(P, Czesci[P].Akt);
+ end;
end;
procedure TScreenEditSub.LyricsCorrectSpaces;
var
+ P: integer;
C: integer;
N: integer;
begin
- for C := 0 to Czesci[0].High do begin
- // correct starting spaces in the first word
- while Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 1, 1) = ' ' do
- Czesci[0].Czesc[C].Nuta[0].Tekst := Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 2, 100);
-
- // move spaces on the start to the end of the previous note
- for N := 1 to Czesci[0].Czesc[C].HighNut do begin
- while (Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, 1, 1) = ' ') do begin
- Czesci[0].Czesc[C].Nuta[N].Tekst := Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, 2, 100);
- Czesci[0].Czesc[C].Nuta[N-1].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst + ' ';
+ for P := 0 to Length(Czesci) - 1 do
+ begin
+ for C := 0 to Czesci[P].High do
+ begin
+ if(Length(Czesci[P].Czesc[C].Nuta)>0) then
+ begin
+ // correct starting spaces in the first word
+ while Copy(Czesci[P].Czesc[C].Nuta[0].Tekst, 1, 1) = ' ' do
+ Czesci[P].Czesc[C].Nuta[0].Tekst := Copy(Czesci[P].Czesc[C].Nuta[0].Tekst, 2, 100);
+
+ // move spaces on the start to the end of the previous note
+ for N := 1 to Czesci[P].Czesc[C].HighNut do
+ begin
+ while (Copy(Czesci[P].Czesc[C].Nuta[N].Tekst, 1, 1) = ' ') do
+ begin
+ Czesci[P].Czesc[C].Nuta[N].Tekst := Copy(Czesci[P].Czesc[C].Nuta[N].Tekst, 2, 100);
+ Czesci[P].Czesc[C].Nuta[N-1].Tekst := Czesci[P].Czesc[C].Nuta[N-1].Tekst + ' ';
+ end;
+ end; // N
+
+ // correct '-' to '- '
+ for N := 0 to Czesci[P].Czesc[C].HighNut do
+ begin
+ if Czesci[P].Czesc[C].Nuta[N].Tekst = '-' then
+ Czesci[P].Czesc[C].Nuta[N].Tekst := '- ';
+ end; // N
+
+ // add space to the previous note when the current word is '- '
+ for N := 1 to Czesci[P].Czesc[C].HighNut do
+ begin
+ if Czesci[P].Czesc[C].Nuta[N].Tekst = '- ' then
+ Czesci[P].Czesc[C].Nuta[N-1].Tekst := Czesci[P].Czesc[C].Nuta[N-1].Tekst + ' ';
+ end; // N
+
+ // correct too many spaces at the end of note
+ for N := 0 to Czesci[P].Czesc[C].HighNut do
+ begin
+ while Copy(Czesci[P].Czesc[C].Nuta[N].Tekst, Length(Czesci[P].Czesc[C].Nuta[N].Tekst)-1, 2) = ' ' do
+ Czesci[P].Czesc[C].Nuta[N].Tekst := Copy(Czesci[P].Czesc[C].Nuta[N].Tekst, 1, Length(Czesci[P].Czesc[C].Nuta[N].Tekst)-1);
+ end; // N
+
+ // and correct if there is no space at the end of sentence
+ N := Czesci[P].Czesc[C].HighNut;
+ if Copy(Czesci[P].Czesc[C].Nuta[N].Tekst, Length(Czesci[P].Czesc[C].Nuta[N].Tekst), 1) <> ' ' then
+ Czesci[P].Czesc[C].Nuta[N].Tekst := Czesci[P].Czesc[C].Nuta[N].Tekst + ' ';
end;
- end; // N
-
- // correct '-' to '- '
- for N := 0 to Czesci[0].Czesc[C].HighNut do begin
- if Czesci[0].Czesc[C].Nuta[N].Tekst = '-' then
- Czesci[0].Czesc[C].Nuta[N].Tekst := '- ';
- end; // N
-
- // add space to the previous note when the current word is '- '
- for N := 1 to Czesci[0].Czesc[C].HighNut do begin
- if Czesci[0].Czesc[C].Nuta[N].Tekst = '- ' then
- Czesci[0].Czesc[C].Nuta[N-1].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst + ' ';
- end; // N
-
- // correct too many spaces at the end of note
- for N := 0 to Czesci[0].Czesc[C].HighNut do begin
- while Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, Length(Czesci[0].Czesc[C].Nuta[N].Tekst)-1, 2) = ' ' do
- Czesci[0].Czesc[C].Nuta[N].Tekst := Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, 1, Length(Czesci[0].Czesc[C].Nuta[N].Tekst)-1);
- end; // N
-
- // and correct if there is no space at the end of sentence
- N := Czesci[0].Czesc[C].HighNut;
- if Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, Length(Czesci[0].Czesc[C].Nuta[N].Tekst), 1) <> ' ' then
- Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[C].Nuta[N].Tekst + ' ';
-
- end; // C
- Lyric.AddCzesc(Czesci[0].Akt);
+ end; // C
+ EditorLyric[P].AddCzesc(P, Czesci[P].Akt);
+ end;
end;
procedure TScreenEditSub.FixTimings;
var
+ P: integer;
C: integer;
S: integer;
Min: integer;
Max: integer;
begin
- for C := 1 to Czesci[0].High do begin
- with Czesci[0].Czesc[C-1] do begin
- Min := Nuta[HighNut].Start + Nuta[HighNut].Dlugosc;
- Max := Czesci[0].Czesc[C].StartNote;
- case (Max - Min) of
- 0: S := Max;
- 1: S := Max;
- 2: S := Max - 1;
- 3: S := Max - 2;
- else
- S := Min + 2;
-
- end; // case
-
- Czesci[0].Czesc[C].Start := S;
- end; // with
- end; // for
+ for P := 0 to Length(Czesci) - 1 do
+ begin
+ for C := 1 to Czesci[P].High do
+ begin
+ with Czesci[P].Czesc[C-1] do
+ begin
+ if (Length(Nuta)>0) then
+ begin
+ Min := Nuta[HighNut].Start + Nuta[HighNut].Dlugosc;
+ Max := Czesci[P].Czesc[C].StartNote;
+ case (Max - Min) of
+ 0: S := Max;
+ 1: S := Max;
+ 2: S := Max - 1;
+ 3: S := Max - 2;
+ else
+ S := Min + 2;
+ end; // case
+
+ Czesci[P].Czesc[C].Start := S;
+ end;
+ end; // with
+ end; // for
+ end;
end;
procedure TScreenEditSub.DivideSentence;
@@ -1452,7 +1624,7 @@ begin
// clear and set new sentence
CNew := CStart + 1;
- NStart := AktNuta;
+ NStart := AktNuta[CP];
Czesci[0].Czesc[CNew].Start := Czesci[0].Czesc[CStart].Nuta[NStart].Start;
Czesci[0].Czesc[CNew].StartNote := Czesci[0].Czesc[CStart].Nuta[NStart].Start;
Czesci[0].Czesc[CNew].Lyric := '';
@@ -1491,9 +1663,9 @@ begin
Czesci[0].Czesc[CNew].BaseNote := Czesci[0].Czesc[CNew].Nuta[N].Ton;
Czesci[0].Akt := Czesci[0].Akt + 1;
- AktNuta := 0;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
- Lyric.AddCzesc(Czesci[0].Akt);
+ AktNuta[0] := 0;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta[0]].Color := 2;
+ EditorLyric[0].AddCzesc(0, Czesci[0].Akt);
end;
procedure TScreenEditSub.JoinSentence;
@@ -1503,7 +1675,7 @@ var
NStart: integer;
NDst: integer;
begin
- C := Czesci[0].Akt;
+ C := Czesci[CP].Akt;
// set new sentence
NStart := Czesci[0].Czesc[C].IlNut;
@@ -1512,7 +1684,8 @@ begin
SetLength(Czesci[0].Czesc[C].Nuta, Czesci[0].Czesc[C].IlNut);
// move right notes to new sentences
- for N := 0 to Czesci[0].Czesc[C+1].HighNut do begin
+ for N := 0 to Czesci[0].Czesc[C+1].HighNut do
+ begin
NDst := NStart + N;
Czesci[0].Czesc[C].Nuta[NDst] := Czesci[0].Czesc[C+1].Nuta[N];
end;
@@ -1530,7 +1703,7 @@ begin
SetLength(Czesci[0].Czesc, Length(Czesci[0].Czesc) - 1);
Dec(Czesci[0].Ilosc);
Dec(Czesci[0].High);
- Lyric.AddCzesc(Czesci[0].Akt);
+ EditorLyric[0].AddCzesc(0, Czesci[0].Akt);
end;
procedure TScreenEditSub.DivideNote;
@@ -1539,37 +1712,38 @@ var
N: integer;
NLen: integer;
begin
- C := Czesci[0].Akt;
+ C := Czesci[CP].Akt;
- NLen := Czesci[0].Czesc[C].IlNut + 1;
- SetLength(Czesci[0].Czesc[C].Nuta, NLen);
- Inc(Czesci[0].Czesc[C].HighNut);
- Inc(Czesci[0].Czesc[C].IlNut);
+ NLen := Czesci[CP].Czesc[C].IlNut + 1;
+ SetLength(Czesci[CP].Czesc[C].Nuta, NLen);
+ Inc(Czesci[CP].Czesc[C].HighNut);
+ Inc(Czesci[CP].Czesc[C].IlNut);
// we copy all notes including selected one
- for N := Czesci[0].Czesc[C].HighNut downto AktNuta+1 do begin
- Czesci[0].Czesc[C].Nuta[N] := Czesci[0].Czesc[C].Nuta[N-1];
+ for N := Czesci[CP].Czesc[C].HighNut downto AktNuta[CP]+1 do
+ begin
+ Czesci[CP].Czesc[C].Nuta[N] := Czesci[CP].Czesc[C].Nuta[N-1];
end;
// me slightly modify new note
- Czesci[0].Czesc[C].Nuta[AktNuta].Dlugosc := ceil(Czesci[0].Czesc[C].Nuta[AktNuta+1].Dlugosc/2);
+ Czesci[CP].Czesc[C].Nuta[AktNuta[CP]].Dlugosc := ceil(Czesci[CP].Czesc[C].Nuta[AktNuta[CP]+1].Dlugosc/2);
- Czesci[0].Czesc[C].Nuta[AktNuta+1].Start := Czesci[0].Czesc[C].Nuta[AktNuta+1].Start +
- Czesci[0].Czesc[C].Nuta[AktNuta].Dlugosc;
+ Czesci[CP].Czesc[C].Nuta[AktNuta[CP]+1].Start := Czesci[CP].Czesc[C].Nuta[AktNuta[CP]+1].Start +
+ Czesci[CP].Czesc[C].Nuta[AktNuta[CP]].Dlugosc;
- Czesci[0].Czesc[C].Nuta[AktNuta+1].Dlugosc := Czesci[0].Czesc[C].Nuta[AktNuta+1].Dlugosc -
- Czesci[0].Czesc[C].Nuta[AktNuta].Dlugosc;
+ Czesci[CP].Czesc[C].Nuta[AktNuta[CP]+1].Dlugosc := Czesci[CP].Czesc[C].Nuta[AktNuta[CP]+1].Dlugosc -
+ Czesci[CP].Czesc[C].Nuta[AktNuta[CP]].Dlugosc;
- if (Czesci[0].Czesc[C].Nuta[AktNuta+1].Dlugosc>0) then
- Czesci[0].Czesc[C].Nuta[AktNuta+1].Tekst := '~'
+ if (Czesci[CP].Czesc[C].Nuta[AktNuta[CP]+1].Dlugosc>0) then
+ Czesci[CP].Czesc[C].Nuta[AktNuta[CP]+1].Tekst := '~'
else
- Czesci[0].Czesc[C].Nuta[AktNuta+1].Tekst := ' ';
+ Czesci[CP].Czesc[C].Nuta[AktNuta[CP]+1].Tekst := ' ';
- Czesci[0].Czesc[C].Nuta[AktNuta].Color := 0;
- Czesci[0].Czesc[C].Nuta[AktNuta+1].Color := 2;
+ Czesci[CP].Czesc[C].Nuta[AktNuta[CP]].Color := 0;
+ Czesci[CP].Czesc[C].Nuta[AktNuta[CP]+1].Color := 2;
- Inc(AktNuta);
- Lyric.AddCzesc(Czesci[0].Akt);
+ Inc(AktNuta[CP]);
+ EditorLyric[CP].AddCzesc(CP, Czesci[CP].Akt);
end;
procedure TScreenEditSub.DeleteNote;
@@ -1578,68 +1752,97 @@ var
N: integer;
NLen: integer;
begin
- C := Czesci[0].Akt;
+ C := Czesci[CP].Akt;
//Do Not delete Last Note
- if (Czesci[0].High > 0) OR (Czesci[0].Czesc[C].HighNut > 0) then
+ if (Czesci[CP].High > 0) OR (Czesci[CP].Czesc[C].HighNut > 0) then
begin
// we copy all notes from the next to the selected one
- for N := AktNuta+1 to Czesci[0].Czesc[C].HighNut do begin
- Czesci[0].Czesc[C].Nuta[N-1] := Czesci[0].Czesc[C].Nuta[N];
+ for N := AktNuta[CP]+1 to Czesci[CP].Czesc[C].HighNut do
+ begin
+ Czesci[CP].Czesc[C].Nuta[N-1] := Czesci[CP].Czesc[C].Nuta[N];
end;
- NLen := Czesci[0].Czesc[C].IlNut - 1;
+ NLen := Czesci[CP].Czesc[C].IlNut - 1;
if (NLen > 0) then
begin
- SetLength(Czesci[0].Czesc[C].Nuta, NLen);
- Dec(Czesci[0].Czesc[C].HighNut);
- Dec(Czesci[0].Czesc[C].IlNut);
+ SetLength(Czesci[CP].Czesc[C].Nuta, NLen);
+ Dec(Czesci[CP].Czesc[C].HighNut);
+ Dec(Czesci[CP].Czesc[C].IlNut);
// me slightly modify new note
- if AktNuta > Czesci[0].Czesc[C].HighNut then Dec(AktNuta);
- Czesci[0].Czesc[C].Nuta[AktNuta].Color := 2;
+ if AktNuta[CP] > Czesci[CP].Czesc[C].HighNut then
+ Dec(AktNuta[CP]);
+
+ Czesci[CP].Czesc[C].Nuta[AktNuta[CP]].Color := 2;
end
//Last Note of current Sentence Deleted - > Delete Sentence
else
begin
- //Move all Sentences after the current to the Left
- for N := C+1 to Czesci[0].High do
- Czesci[0].Czesc[N-1] := Czesci[0].Czesc[N];
-
- //Delete Last Sentence
- SetLength(Czesci[0].Czesc, Czesci[0].High);
- Czesci[0].High := High(Czesci[0].Czesc);
- Czesci[0].Ilosc := Length(Czesci[0].Czesc);
-
- AktNuta := 0;
- if (C > 0) then
- Czesci[0].Akt := C - 1
- else
- Czesci[0].Akt := 0;
-
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
+ DeleteSentence;
end;
end;
- Lyric.AddCzesc(Czesci[0].Akt);
+ EditorLyric[CP].AddCzesc(CP, Czesci[CP].Akt);
+ if AktSong.isDuet then
+ EditorLyric[(CP+1) mod 2].AddCzesc((CP+1) mod 2, Czesci[(CP+1) mod 2].Akt);
+end;
+
+procedure TScreenEditSub.DeleteSentence;
+var
+ P: integer;
+ C: integer;
+ N: integer;
+
+begin
+ for P := 0 to Length(Czesci) - 1 do
+ begin
+ C := Czesci[CP].Akt;
+ //Move all Sentences after the current to the Left
+ for N := C+1 to Czesci[P].High do
+ Czesci[P].Czesc[N-1] := Czesci[P].Czesc[N];
+
+ //Delete Last Sentence
+ SetLength(Czesci[P].Czesc, Czesci[P].High);
+ Czesci[P].High := High(Czesci[P].Czesc);
+ Czesci[P].Ilosc := Length(Czesci[P].Czesc);
+
+ AktNuta[P] := 0;
+ if (C > 0) then
+ Czesci[P].Akt := C - 1
+ else
+ Czesci[P].Akt := 0;
+ end;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
end;
procedure TScreenEditSub.TransposeNote(Transpose: integer);
begin
- Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton, Transpose);
+ if (Length(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta)>0) then
+ begin
+ Inc(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Ton, Transpose);
+ end;
end;
procedure TScreenEditSub.ChangeWholeTone(Tone: integer);
var
+ P: integer;
C: integer;
N: integer;
begin
- for C := 0 to Czesci[0].High do begin
- Czesci[0].Czesc[C].BaseNote := Czesci[0].Czesc[C].BaseNote + Tone;
- for N := 0 to Czesci[0].Czesc[C].HighNut do
- Czesci[0].Czesc[C].Nuta[N].Ton := Czesci[0].Czesc[C].Nuta[N].Ton + Tone;
+ for P := 0 to Length(Czesci) - 1 do
+ begin
+ for C := 0 to Czesci[P].High do
+ begin
+ if (Length(Czesci[P].Czesc[C].Nuta)>0) then
+ begin
+ Czesci[P].Czesc[C].BaseNote := Czesci[P].Czesc[C].BaseNote + Tone;
+ for N := 0 to Czesci[P].Czesc[C].HighNut do
+ Czesci[P].Czesc[C].Nuta[N].Ton := Czesci[P].Czesc[C].Nuta[N].Ton + Tone;
+ end;
+ end;
end;
end;
@@ -1649,13 +1852,16 @@ var
N: integer;
NStart: integer;
begin
- for C := Czesci[0].Akt to Czesci[0].High do begin
+ for C := Czesci[0].Akt to Czesci[0].High do
+ begin
NStart := 0;
- if C = Czesci[0].Akt then NStart := AktNuta;
- for N := NStart to Czesci[0].Czesc[C].HighNut do begin
+ if C = Czesci[0].Akt then NStart := AktNuta[0];
+ for N := NStart to Czesci[0].Czesc[C].HighNut do
+ begin
Inc(Czesci[0].Czesc[C].Nuta[N].Start, Move); // move note start
- if N = 0 then begin // fix beginning
+ if N = 0 then
+ begin // fix beginning
Inc(Czesci[0].Czesc[C].Start, Move);
Inc(Czesci[0].Czesc[C].StartNote, Move);
end;
@@ -1665,7 +1871,7 @@ begin
end; // for
end; // for
- Lyric.AddCzesc(Czesci[0].Akt);
+ EditorLyric[0].AddCzesc(0, Czesci[0].Akt);
end;
procedure TScreenEditSub.MoveTextToRight;
@@ -1674,14 +1880,6 @@ var
N: integer;
NHigh: integer;
begin
-{ C := Czesci[0].Akt;
-
- for N := Czesci[0].Czesc[C].HighNut downto 1 do begin
- Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst;
- end; // for
-
- Czesci[0].Czesc[C].Nuta[0].Tekst := '- ';}
-
C := Czesci[0].Akt;
NHigh := Czesci[0].Czesc[C].HighNut;
@@ -1689,11 +1887,12 @@ begin
Czesci[0].Czesc[C].Nuta[NHigh].Tekst := Czesci[0].Czesc[C].Nuta[NHigh-1].Tekst + Czesci[0].Czesc[C].Nuta[NHigh].Tekst;
// other words
- for N := NHigh - 1 downto AktNuta + 1 do begin
+ for N := NHigh - 1 downto AktNuta[0] + 1 do
+ begin
Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst;
end; // for
- Czesci[0].Czesc[C].Nuta[AktNuta].Tekst := '- ';
- Lyric.AddCzesc(Czesci[0].Akt);
+ Czesci[0].Czesc[C].Nuta[AktNuta[0]].Tekst := '- ';
+ EditorLyric[0].AddCzesc(0, Czesci[0].Akt);
end;
procedure TScreenEditSub.MarkSrc;
@@ -1710,7 +1909,7 @@ begin
for N := 0 to Czesci[0].Czesc[CopySrc].HighNut do
Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[CopySrc].Nuta[N].Tekst;
- Lyric.AddCzesc(Czesci[0].Akt);
+ EditorLyric[0].AddCzesc(0, Czesci[0].Akt);
end;
procedure TScreenEditSub.CopySentence(Src, Dst: integer);
@@ -1776,69 +1975,281 @@ begin
inherited Create;
SetLength(Player, 1);
- //Theme:
- //bg
+ //light blue:
+ cRB := 0.9; cGB := 0.95; cBB := 1;
- //AddStatic(0, 0, 800, 600, 0.3, 0.5, 0.6, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
+ //light red:
+ cRR := 1; cGR := 0.8; cBR := 0.8;
// Line
- //AddStatic(20, 5, 200, 40, 0.95, 0.95, 0.95, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
- AddText(40, 14, 1, 8, 0, 0, 0, 'Line:');
- TextSentence := AddText(110, 14, 1, 8, 0, 0, 0, '0 / 0');
+ AddText(500, 573, 1, 7, 0, 0, 0, 'Line:');
+ TextSentence := AddText(545, 573, 1, 7, 0, 0, 0, '0 / 0');
// Note
- //AddStatic(260, 5, 200, 40, 0.95, 0.95, 0.95, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
- AddText(282, 14, 1, 8, 0, 0, 0, 'Note:');
- TextNote := AddText(360, 14, 1, 8, 0, 0, 0, '0 / 0');
-
- // some borders
- {
- AddStatic(18, 53, 764, 240, 0, 0, 0, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
- AddStatic(20, 55, 760, 236, 0.95, 0.95, 0.95, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
-
- AddStatic(18, 303, 764, 139, 0, 0, 0, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
- AddStatic(20, 305, 760, 135, 0.95, 0.95, 0.95, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
-
- AddStatic(18, 498, 764, 44, 0, 0, 0, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
- AddStatic(20, 500, 760, 40, 0.95, 0.95, 0.95, Skin.GetTextureFileName('ButtonFade'), 'JPG', 'Font Black');
- }
-
- AddText(30, 65, 0, 8, 0, 0, 0, 'Title:');
- AddText(30, 90, 0, 8, 0, 0, 0, 'Artist:');
- AddText(30, 115, 0, 8, 0, 0, 0, 'Mp3:');
- AddText(30, 140, 0, 8, 0, 0, 0, 'BPM:');
- AddText(30, 165, 0, 8, 0, 0, 0, 'GAP:');
-
- TextTitle := AddText(180, 65, 0, 8, 0, 0, 0, 'a');
- TextArtist := AddText(180, 90, 0, 8, 0, 0, 0, 'b');
- TextMp3 := AddText(180, 115, 0, 8, 0, 0, 0, 'c');
- TextBPM := AddText(180, 140, 0, 8, 0, 0, 0, 'd');
- TextGAP := AddText(180, 165, 0, 8, 0, 0, 0, 'e');
-
-{ AddInteraction(2, TextTitle);
- AddInteraction(2, TextArtist);
- AddInteraction(2, TextMp3);
- AddInteraction(2, TextBPM);
- AddInteraction(2, TextGAP);}
+ AddText(655, 573, 1, 7, 0, 0, 0, 'Note:');
+ TextNote := AddText(710, 573, 1, 7, 0, 0, 0, '0 / 0');
+
+ AddText(10, 10, 0, 8, 0, 0, 0, 'Title:');
+ AddText(10, 30, 0, 8, 0, 0, 0, 'Artist:');
+ //AddText(10, 50, 0, 8, 0, 0, 0, 'Mp3:');
+ AddText(10, 50, 0, 8, 0, 0, 0, 'BPM:');
+ AddText(10, 70, 0, 8, 0, 0, 0, 'GAP:');
+
+ TextTitle := AddText(80, 10, 0, 8, 0, 0, 0, 'a');
+ TextArtist := AddText(80, 30, 0, 8, 0, 0, 0, 'b');
+ //TextMp3 := AddText(80, 50, 0, 8, 0, 0, 0, 'c');
+ TextBPM := AddText(80, 50, 0, 8, 0, 0, 0, 'd');
+ TextGAP := AddText(80, 70, 0, 8, 0, 0, 0, 'e');
// note info
- AddText(30, 190, 0, 8, 0, 0, 0, 'Start:');
- AddText(30, 215, 0, 8, 0, 0, 0, 'Duration:');
- AddText(30, 240, 0, 8, 0, 0, 0, 'Tone:');
- AddText(30, 265, 0, 8, 0, 0, 0, 'Text:'); AddText(500, 265, 0, 8, 0, 0, 0, 'VideoGap:');
+ AddText(10, 90, 0, 8, 0, 0, 0, 'Start:');
+ AddText(300, 90, 0, 8, 0, 0, 0, 'Duration:');
- TextNStart := AddText(180, 190, 0, 8, 0, 0, 0, 'a');
- TextNDlugosc := AddText(180, 215, 0, 8, 0, 0, 0, 'b');
- TextNTon := AddText(180, 240, 0, 8, 0, 0, 0, 'c');
- TextNText := AddText(180, 265, 0, 8, 0, 0, 0, 'd');
+ AddText(10, 110, 0, 8, 0, 0, 0, 'Tone:');
+ AddText(10, 130, 0, 8, 0, 0, 0, 'Text:');
+ AddText(300, 130, 0, 8, 0, 0, 0, 'VideoGap:');
- TextVideoGap := AddText(600, 265, 0, 8, 0, 0, 0, 'e');
+ TextNStart := AddText(80, 90, 0, 8, 0, 0, 0, 'a');
+ TextNDlugosc := AddText(400, 90, 0, 8, 0, 0, 0, 'b');
+ TextNTon := AddText(80, 110, 0, 8, 0, 0, 0, 'c');
+ TextNText := AddText(80, 130, 0, 8, 0, 0, 0, 'd');
+ TextVideoGap := AddText(400, 130, 0, 8, 0, 0, 0, 'e');
// debug
- TextDebug := AddText(30, 550, 0, 9, 0, 0, 0, '');
+ TextDebug := AddText(30, 575, 0, 9, 0, 0, 0, '');
+
+ EditorLyric[0] := TLyric.Create;
+ EditorLyric[1] := TLyric.Create;
+
+ offset[0] := 155;
+ offset[1] := 525;
+end;
+
+procedure TScreenEditSub.SelectNextNote();
+begin
+ if AktSong.isDuet then
+ begin
+ Czesci[(CP+1) mod 2].Akt := Czesci[CP].Akt;
+ while (Length(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta)=0) do
+ begin
+ Czesci[(CP+1) mod 2].Akt := Czesci[CP].Akt;
+ if (Length(Czesci[(CP+1) mod 2].Czesc[Czesci[(CP+1) mod 2].Akt].Nuta)=0) then
+ inc(Czesci[CP].Akt)
+ else
+ CP := (CP+1) mod 2;
+
+ if Czesci[CP].Akt > Czesci[CP].High then
+ Czesci[CP].Akt := 0;
+ end;
+
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+
+ EditorLyric[0].AddCzesc(0, Czesci[0].Akt);
+ EditorLyric[1].AddCzesc(1, Czesci[1].Akt);
+ EditorLyric[0].Selected := 0;
+ EditorLyric[1].Selected := 0;
+ end else
+ begin
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta[0]].Color := 2;
+
+ EditorLyric[0].AddCzesc(0, Czesci[0].Akt);
+ EditorLyric[0].Selected := 0;
+ end;
+end;
+
+procedure TScreenEditSub.SelectPrevNote();
+begin
+ if AktSong.isDuet then
+ begin
+ Czesci[(CP+1) mod 2].Akt := Czesci[CP].Akt;
+ while (Length(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta)=0) do
+ begin
+ Czesci[(CP+1) mod 2].Akt := Czesci[CP].Akt;
+ if (Length(Czesci[(CP+1) mod 2].Czesc[Czesci[(CP+1) mod 2].Akt].Nuta)=0) then
+ dec(Czesci[CP].Akt)
+ else
+ CP := (CP+1) mod 2;
+
+ if Czesci[CP].Akt < 0 then
+ Czesci[CP].Akt := Czesci[CP].High;
+ end;
+
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+
+ EditorLyric[0].AddCzesc(0, Czesci[0].Akt);
+ EditorLyric[1].AddCzesc(1, Czesci[1].Akt);
+ EditorLyric[0].Selected := 0;
+ EditorLyric[1].Selected := 0;
+ end else
+ begin
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta[0]].Color := 2;
+
+ EditorLyric[0].AddCzesc(0, Czesci[0].Akt);
+ EditorLyric[0].Selected := 0;
+ end;
+end;
+
+procedure TScreenEditSub.MakeSingle;
+var
+ C: integer;
+
+begin
+ for C := 0 to Length(Czesci[0].Czesc) - 1 do
+ begin
+ if (Length(Czesci[0].Czesc[C].Nuta)=0) then
+ Czesci[0].Czesc[C] := Czesci[1].Czesc[C];
+ end;
+ SetLength(Czesci, 1);
+ AktSong.isDuet := false;
+ CP := 0;
+ Refresh;
+ AktNuta[CP] := 0;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+
+ EditorLyric[0].Y := offset[0]+300;
+ EditorLyric[CP].AddCzesc(CP, Czesci[CP].Akt);
+end;
+
+procedure TScreenEditSub.MakeDuet;
+var
+ L: integer;
+
+begin
+ SetLength(Czesci, 2);
+
+ Czesci[1].Akt := Czesci[0].Akt;
+ Czesci[1].High := Czesci[0].High;
+ Czesci[1].Ilosc := Czesci[0].Ilosc;
+ Czesci[1].Resolution := Czesci[0].Resolution;
+ Czesci[1].NotesGAP := Czesci[0].NotesGAP;
+ Czesci[1].Wartosc := 0;
+ SetLength(Czesci[1].Czesc, Length(Czesci[0].Czesc));
+
+ for L := 0 to Length(Czesci[0].Czesc) - 1 do
+ begin
+ Czesci[1].Czesc[L].Start := Czesci[0].Czesc[L].Start;
+ Czesci[1].Czesc[L].StartNote := Czesci[0].Czesc[L].StartNote;
+ Czesci[1].Czesc[L].Lyric := '';
+ Czesci[1].Czesc[L].LyricWidth := 0;
+ Czesci[1].Czesc[L].Koniec := Czesci[0].Czesc[L].Koniec;
+ Czesci[1].Czesc[L].BaseNote := Czesci[0].Czesc[L].BaseNote;
+ Czesci[1].Czesc[L].HighNut := -1;
+ Czesci[1].Czesc[L].IlNut := 0;
+ Czesci[1].Czesc[L].TotalNotes := 0;
+ SetLength(Czesci[1].Czesc[L].Nuta, 0);
+ end;
+
+ AktSong.isDuet := true;
+
+ EditorLyric[0].Y := offset[0];
+ EditorLyric[1].Y := offset[1];
+
+ EditorLyric[(CP+1) mod 2].AddCzesc((CP+1) mod 2, Czesci[CP].Akt);
+ EditorLyric[(CP+1) mod 2].Selected := 0;
+ EditorLyric[CP].AddCzesc(CP, Czesci[CP].Akt);
+ AktNuta[(CP+1) mod 2] := 0;
+
+ //delete medley
+ MedleyNotes.isStart := false;
+ MedleyNotes.isEnd := false;
+ AktSong.Medley.Source := msNone;
+end;
+
+procedure TScreenEditSub.DuetCopyLine;
+var
+ L: integer;
+ Src, Dst: integer;
+ N: integer;
+
+begin
+ L := Czesci[CP].Akt;
+ Src := CP;
+ Dst := (CP+1) mod 2;
+
+ SetLength(Czesci[Dst].Czesc[L].Nuta, Czesci[Src].Czesc[L].IlNut);
+ Czesci[Dst].Czesc[L].IlNut := Czesci[Src].Czesc[L].IlNut;
+ Czesci[Dst].Czesc[L].HighNut := Czesci[Src].Czesc[L].HighNut;
+ Czesci[Dst].Czesc[L].Koniec := Czesci[Src].Czesc[L].Koniec;
+ Czesci[Dst].Czesc[L].Start := Czesci[Src].Czesc[L].Start;
+ Czesci[Dst].Czesc[L].BaseNote := Czesci[Src].Czesc[L].BaseNote;
+ Czesci[Dst].Czesc[L].StartNote := Czesci[Src].Czesc[L].StartNote;
+
+ for N := 0 to Czesci[Src].Czesc[L].HighNut do
+ begin
+ Czesci[Dst].Czesc[L].Nuta[N].Tekst := Czesci[Src].Czesc[L].Nuta[N].Tekst;
+ Czesci[Dst].Czesc[L].Nuta[N].Dlugosc := Czesci[Src].Czesc[L].Nuta[N].Dlugosc;
+ Czesci[Dst].Czesc[L].Nuta[N].Ton := Czesci[Src].Czesc[L].Nuta[N].Ton;
+ Czesci[Dst].Czesc[L].Nuta[N].Start := Czesci[Src].Czesc[L].Nuta[N].Start;
+ Czesci[Dst].Czesc[L].Nuta[N].TonGamy := Czesci[Src].Czesc[L].Nuta[N].TonGamy;
+ Czesci[Dst].Czesc[L].Nuta[N].FreeStyle := Czesci[Src].Czesc[L].Nuta[N].FreeStyle;
+ Czesci[Dst].Czesc[L].Nuta[N].Wartosc := Czesci[Src].Czesc[L].Nuta[N].Wartosc;
+ end;
+
+ Refresh;
+ EditorLyric[Dst].AddCzesc(Dst, Czesci[Src].Akt);
+ EditorLyric[Dst].Selected := 0;
+ AktNuta[Dst] := 0;
+ Czesci[Src].Czesc[L].Nuta[AktNuta[Src]].Color := 2;
+end;
+
+procedure TScreenEditSub.DuetMoveLine;
+begin
+ DuetCopyLine;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Lyric := '';
+ Czesci[CP].Czesc[Czesci[CP].Akt].LyricWidth := 0;
+ Czesci[CP].Czesc[Czesci[CP].Akt].HighNut := -1;
+ Czesci[CP].Czesc[Czesci[CP].Akt].IlNut := 0;
+ Czesci[CP].Czesc[Czesci[CP].Akt].TotalNotes := 0;
+ SetLength(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta, 0);
+
+ EditorLyric[CP].AddCzesc(CP, Czesci[CP].Akt);
+ EditorLyric[CP].Selected := -1;
+
+ CP := (CP+1) mod 2;
+ Refresh;
+end;
+
+procedure TScreenEditSub.Refresh;
+var
+ P: integer;
+ L: integer;
+ N: integer;
+
+begin
+ FixTimings;
+ for P := 0 to Length(Czesci) - 1 do
+ begin
+ Czesci[P].Ilosc := Length(Czesci[P].Czesc);
+ Czesci[P].High := Czesci[P].Ilosc-1;
+ Czesci[P].Wartosc := 0;
+
+ for L := 0 to Czesci[P].High - 1 do
+ begin
+ with Czesci[P].Czesc[L] do
+ begin
+ IlNut := Length(Nuta);
+ HighNut := IlNut-1;
+ TotalNotes := 0;
+
+ if (Length(Nuta)>0) then
+ begin
+ StartNote := Nuta[0].Start;
+ for N := 0 to Length(Czesci[P].Czesc[L].Nuta) - 1 do
+ begin
+ Nuta[N].Color := 0;
+ Czesci[P].Wartosc := Czesci[P].Wartosc + Nuta[N].Dlugosc * Nuta[N].Wartosc;
+ TotalNotes := TotalNotes + Nuta[N].Dlugosc * Nuta[N].Wartosc;
+ end;
+ end;
+ end;
+ end;
+ end;
end;
procedure TScreenEditSub.onShow;
+var
+ I: integer;
+
begin
Log.LogStatus('Initializing', 'TEditScreen.onShow');
@@ -1846,7 +2257,7 @@ begin
ResetSingTemp;
AktSong := CatSongs.Song[SongIndex];
Error := not LoadSong(Path + FileName, SONG_LOAD_COMPLETE);
- if not Error then
+ if not Error and not AktSong.isDuet then
FindRefrainStart(AktSong);
except
Error := True;
@@ -1859,7 +2270,8 @@ begin
ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG'));
Exit;
end
- else begin
+ else
+ begin
MidiOut := TMidiOutput.Create(nil);
MidiOut.Open;
@@ -1867,18 +2279,28 @@ begin
MP3Volume := 50;
Music.SetVolume(MP3Volume);
+ CP := 0;
+
if not Help.SetHelpID(ID) then
Log.LogError('No Entry for Help-ID ' + ID + ' (ScreenEditSub)');
Text[TextTitle].Text := AktSong.Title;
Text[TextArtist].Text := AktSong.Artist;
- Text[TextMp3].Text := AktSong.Mp3;
+ //Text[TextMp3].Text := AktSong.Mp3;
Czesci[0].Akt := 0;
- AktNuta := 0;
+ AktNuta[0] := 0;
+ AktNuta[1] := 0;
noteStart := 0; //when playing sentence
lineStart := 0;
- Czesci[0].Czesc[0].Nuta[0].Color := 2;
+ cpStart := 0;
+
+ if AktSong.isDuet then
+ begin
+ Czesci[1].Akt := 0;
+ SelectNextNote;
+ end else
+ Czesci[0].Czesc[0].Nuta[0].Color := 2;
if AktSong.Medley.Source <> msNone then
begin
@@ -1892,27 +2314,35 @@ begin
//set Preview Start
MedleyNotes.Preview := FindNote(round(GetMidBeat(AktSong.PreviewStart-AktSong.Gap/1000)));
- Czesci[0].Czesc[MedleyNotes.Preview.line].Nuta[MedleyNotes.Preview.note].IsStartPreview := true;
- AktSong.PreviewStart := GetTimeFromBeat(Czesci[0].Czesc[MedleyNotes.Preview.line].Nuta[MedleyNotes.Preview.note].start);
+ Czesci[MedleyNotes.Preview.CP].Czesc[MedleyNotes.Preview.line].Nuta[MedleyNotes.Preview.note].IsStartPreview := true;
+ AktSong.PreviewStart :=
+ GetTimeFromBeat(Czesci[MedleyNotes.Preview.CP].Czesc[MedleyNotes.Preview.line].Nuta[MedleyNotes.Preview.note].start);
Music.Open(Path + AktSong.Mp3);
//Set Down Music Volume for Better hearability of Midi Sounds
//Music.SetVolume(40);
-
- Lyric.Clear;
- Lyric.X := 400;
- Lyric.Y := 500;
- Lyric.Align := 1;
- Lyric.Size := 14;
- Lyric.ColR := 0;
- Lyric.ColG := 0;
- Lyric.ColB := 0;
- Lyric.ColSR := Skin_FontHighlightR;
- Lyric.ColSG := Skin_FontHighlightG;
- Lyric.ColSB := Skin_FontHighlightB;
- Lyric.Style := 0;
- Lyric.AddCzesc(0);
- Lyric.Selected := 0;
+
+ for I := 0 to Length(Czesci)-1 do
+ begin
+ EditorLyric[I].Clear;
+ EditorLyric[I].X := 400;
+ if not AktSong.isDuet and (I=0) then
+ EditorLyric[I].Y := offset[I]+300
+ else
+ EditorLyric[I].Y := offset[I];
+
+ EditorLyric[I].Align := 1;
+ EditorLyric[I].Size := 13;
+ EditorLyric[I].ColR := 0;
+ EditorLyric[I].ColG := 0;
+ EditorLyric[I].ColB := 0;
+ EditorLyric[I].ColSR := Skin_FontHighlightR;
+ EditorLyric[I].ColSG := Skin_FontHighlightG;
+ EditorLyric[I].ColSB := Skin_FontHighlightB;
+ EditorLyric[I].Style := 0;
+ EditorLyric[I].AddCzesc(I, Czesci[I].Akt);
+ EditorLyric[I].Selected := 0;
+ end;
NotesH := 7;
NotesW := 4;
@@ -1923,11 +2353,13 @@ begin
TextEditMode := false;
BPMEditMode := false;
- MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ //MidiOut.PutShort($81, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ MidiLastNote := 0;
PlaySentenceMidi := false;
PlayOneNoteMidi := false;
Music.Stop;
- LineChanged:=false;
+ LineChanged[0]:=false;
+ LineChanged[1]:=false;
PlaySentence := false;
PlayOneNote := false;
@@ -1977,53 +2409,73 @@ begin
if AktBeat <> LastClick then
begin
- for line := 0 to Length(Czesci[0].Czesc) - 1 do
+ for line := 0 to Length(Czesci[CP].Czesc) - 1 do
begin
- for note := 0 to Length(Czesci[0].Czesc[line].Nuta) - 1 do
+ for note := 0 to Length(Czesci[CP].Czesc[line].Nuta) - 1 do
begin
//line change
- if (Czesci[0].Czesc[line].Start = AktBeat) and (line <> Czesci[0].Akt) and not end_ then
- begin
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
- AktNuta := 0;
- Czesci[0].Akt := line;
- //Inc(Czesci[0].Akt);
- //if Czesci[0].Akt > Length(Czesci[0].Czesc)-1 then //useful?
- // Czesci[0].Akt := 0;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
- Lyric.AddCzesc(Czesci[0].Akt);
- Lyric.Selected := AktNuta;
- LineChanged := true;
+ if (Czesci[CP].Czesc[line].Start = AktBeat) and (line <> Czesci[CP].Akt) and not end_ then
+ begin
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 0;
+ AktNuta[CP] := 0;
+ Czesci[CP].Akt := line;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 1;
+ EditorLyric[CP].AddCzesc(CP, Czesci[CP].Akt);
+ EditorLyric[CP].Selected := AktNuta[CP];
+ LineChanged[CP] := true;
end;
- if (Czesci[0].Czesc[line].Nuta[note].Start = AktBeat) then
+ if (Czesci[CP].Czesc[line].Nuta[note].Start = AktBeat) then
begin
LastClick := AktBeat;
PlayClick := true;
end;
end;
end;
+
+ if AktSong.isDuet then
+ begin
+ for line := 0 to Length(Czesci[(CP+1) mod 2].Czesc) - 1 do
+ begin
+ for note := 0 to Length(Czesci[(CP+1) mod 2].Czesc[line].Nuta) - 1 do
+ begin
+ //line change
+ if (Czesci[(CP+1) mod 2].Czesc[line].Start = AktBeat) and (line <> Czesci[(CP+1) mod 2].Akt) and not end_ then
+ begin
+ if(Length(Czesci[(CP+1) mod 2].Czesc[Czesci[(CP+1) mod 2].Akt].Nuta)>0) then
+ Czesci[(CP+1) mod 2].Czesc[Czesci[(CP+1) mod 2].Akt].Nuta[AktNuta[(CP+1) mod 2]].Color := 0;
+ AktNuta[(CP+1) mod 2] := 0;
+ Czesci[(CP+1) mod 2].Akt := line;
+ Czesci[(CP+1) mod 2].Czesc[Czesci[(CP+1) mod 2].Akt].Nuta[AktNuta[(CP+1) mod 2]].Color := 1;
+ EditorLyric[(CP+1) mod 2].AddCzesc((CP+1) mod 2, Czesci[(CP+1) mod 2].Akt);
+ EditorLyric[(CP+1) mod 2].Selected := AktNuta[(CP+1) mod 2];
+ LineChanged[(CP+1) mod 2] := true;
+ end;
+ end;
+ end;
+ end;
end;
end else
begin
- LineChanged := false;
+ LineChanged[0]:=false;
+ LineChanged[1]:=false;
PlayVideo := false;
end;
// midi music
- if PlaySentenceMidi then begin
-
+ if PlaySentenceMidi then
+ begin
// stop the music
if end_ then
begin
- MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ MidiOut.PutShort($81, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlaySentenceMidi := false;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
- if (Czesci[0].Akt = lineStart) then
- AktNuta := noteStart;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 0;
+ if (Czesci[CP].Akt = lineStart) then
+ AktNuta[CP] := noteStart;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
- Lyric.Selected := AktNuta;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+ EditorLyric[CP].Selected := AktNuta[CP];
end;
// click
@@ -2031,12 +2483,12 @@ begin
if PlayClick then
begin
- for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
- if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then
+ for Pet := 0 to Czesci[CP].Czesc[Czesci[CP].Akt].HighNut do
+ if (Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[Pet].Start = AktBeat) then
begin
if Pet > 0 then
- MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet-1].Ton + 60, 127);
- MidiOut.PutShort($91, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Ton + 60, 127);
+ MidiOut.PutShort($81, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[Pet-1].Ton + 60, 127);
+ MidiOut.PutShort($91, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[Pet].Ton + 60, 127);
MidiLastNote := Pet;
end;
end;
@@ -2046,15 +2498,16 @@ begin
if PlaySentence then
begin
// stop the music
- if end_ then begin
+ if end_ then
+ begin
Music.Stop;
PlaySentence := false;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
- if (Czesci[0].Akt = lineStart) then
- AktNuta := noteStart;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 0;
+ if (Czesci[CP].Akt = lineStart) then
+ AktNuta[CP] := noteStart;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
- Lyric.Selected := AktNuta;
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+ EditorLyric[CP].Selected := AktNuta[CP];
end;
if (Click) and (PlaySentence) then
@@ -2068,31 +2521,56 @@ begin
// move "cursor"
if (PlaySentence or PlaySentenceMidi) then
begin
- for line := 0 to Length(Czesci[0].Czesc) - 1 do
+ for line := 0 to Length(Czesci[CP].Czesc) - 1 do
begin
- for note := 0 to Length(Czesci[0].Czesc[line].Nuta) - 1 do
+ for note := 0 to Length(Czesci[CP].Czesc[line].Nuta) - 1 do
begin
//note change
- if (Czesci[0].Czesc[line].Nuta[note].Start = AktBeat) and
- ((note <> AktNuta) or LineChanged) then
+ if (Czesci[CP].Czesc[line].Nuta[note].Start = AktBeat) and
+ ((note <> AktNuta[CP]) or LineChanged[CP]) then
begin
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
- if not LineChanged then
- begin
- AktNuta := note;
- Czesci[0].Akt := line;
- //Inc(AktNuta);
- //if AktNuta > Length(Czesci[0].Czesc[Czesci[0].Akt].Nuta)-1 then
- // Dec(AktNuta);
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 0;
+ if not LineChanged[CP] then
+ begin
+ AktNuta[CP] := note;
+ Czesci[CP].Akt := line;
end else
- LineChanged := false;
+ LineChanged[CP] := false;
+
+ Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Color := 2;
+ EditorLyric[CP].AddCzesc(CP, Czesci[CP].Akt);
+ EditorLyric[CP].Selected := AktNuta[CP];
+ end;
+ end;
+ end;
+
+ if AktSong.isDuet then
+ begin
+ for line := 0 to Length(Czesci[(CP+1) mod 2].Czesc) - 1 do
+ begin
+ for note := 0 to Length(Czesci[(CP+1) mod 2].Czesc[line].Nuta) - 1 do
+ begin
+ //note change
+ if (Czesci[(CP+1) mod 2].Czesc[line].Nuta[note].Start = AktBeat) and
+ ((note <> AktNuta[(CP+1) mod 2]) or LineChanged[(CP+1) mod 2]) then
+ begin
+ if(Length(Czesci[(CP+1) mod 2].Czesc[Czesci[(CP+1) mod 2].Akt].Nuta)>0) then
+ Czesci[(CP+1) mod 2].Czesc[Czesci[(CP+1) mod 2].Akt].Nuta[AktNuta[(CP+1) mod 2]].Color := 0;
+ if not LineChanged[(CP+1) mod 2] then
+ begin
+ AktNuta[(CP+1) mod 2] := note;
+ Czesci[(CP+1) mod 2].Akt := line;
+ end else
+ LineChanged[(CP+1) mod 2] := false;
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 2;
- Lyric.AddCzesc(Czesci[0].Akt);
- Lyric.Selected := AktNuta;
+ Czesci[(CP+1) mod 2].Czesc[Czesci[(CP+1) mod 2].Akt].Nuta[AktNuta[(CP+1) mod 2]].Color := 2;
+ EditorLyric[(CP+1) mod 2].AddCzesc((CP+1) mod 2, Czesci[(CP+1) mod 2].Akt);
+ EditorLyric[(CP+1) mod 2].Selected := AktNuta[(CP+1) mod 2];
+ end;
end;
end;
end;
+
end;
// midi music
@@ -2102,7 +2580,7 @@ begin
// stop the music
if (MidiPos > MidiStop) then
begin
- MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ MidiOut.PutShort($81, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[MidiLastNote].Ton + 60, 127);
PlayOneNoteMidi := false;
end;
@@ -2112,14 +2590,14 @@ begin
if AktBeat <> LastClick then
begin
- for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
+ for Pet := 0 to Czesci[CP].Czesc[Czesci[CP].Akt].HighNut do
begin
- if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then
+ if (Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[Pet].Start = AktBeat) then
begin
LastClick := AktBeat;
if Pet > 0 then
- MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet-1].Ton + 60, 127);
- MidiOut.PutShort($91, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Ton + 60, 127);
+ MidiOut.PutShort($81, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[Pet-1].Ton + 60, 127);
+ MidiOut.PutShort($91, Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[Pet].Ton + 60, 127);
MidiLastNote := Pet;
end;
end;
@@ -2143,9 +2621,9 @@ begin
Text[TextDebug].Text := IntToStr(AktBeat);
if AktBeat <> LastClick then
begin
- for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
+ for Pet := 0 to Czesci[CP].Czesc[Czesci[CP].Akt].HighNut do
begin
- if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then
+ if (Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[Pet].Start = AktBeat) then
begin
Music.PlayClick;
LastClick := AktBeat;
@@ -2155,8 +2633,8 @@ begin
end; // click
end; // if PlayOneNote
- Text[TextSentence].Text := IntToStr(Czesci[0].Akt + 1) + ' / ' + IntToStr(Czesci[0].Ilosc);
- Text[TextNote].Text := IntToStr(AktNuta + 1) + ' / ' + IntToStr(Czesci[0].Czesc[Czesci[0].Akt].IlNut);
+ Text[TextSentence].Text := IntToStr(Czesci[CP].Akt + 1) + ' / ' + IntToStr(Czesci[CP].Ilosc);
+ Text[TextNote].Text := IntToStr(AktNuta[CP] + 1) + ' / ' + IntToStr(Czesci[CP].Czesc[Czesci[CP].Akt].IlNut);
// Song info
if not BPMEditMode then
@@ -2166,29 +2644,30 @@ begin
Text[TextVideoGap].Text := FloatToStr(AktSong.VideoGap);
//Error reading Variables when no Song is loaded
- if not Error then
+ if not Error and (Length(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta)>AktNuta[CP]) then
begin
// Note info
- Text[TextNStart].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
- Text[TextNDlugosc].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
- Text[TextNTon].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton) + ' ( ' + GetNoteName(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton) + ' )';
- Text[TextNText].Text := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
+ Text[TextNStart].Text := IntToStr(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Start);
+ Text[TextNDlugosc].Text := IntToStr(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Dlugosc);
+ Text[TextNTon].Text := IntToStr(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Ton) +
+ ' ( ' + GetNoteName(Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Ton) + ' )';
+ Text[TextNText].Text := Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Tekst;
//F and G and Medley Mod:
- if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].FreeStyle then
+ if Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].FreeStyle then
Text[TextNTon].Text := Text[TextNTon].Text + ' *F*'
- else if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc = 2 then
+ else if Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].Wartosc = 2 then
Text[TextNTon].Text := Text[TextNTon].Text + ' *G*';
- if MedleyNotes.isStart and (Czesci[0].Akt = MedleyNotes.start.line)
- and (AktNuta = MedleyNotes.start.note) then
+ if MedleyNotes.isStart and (Czesci[CP].Akt = MedleyNotes.start.line)
+ and (AktNuta[0] = MedleyNotes.start.note) then
Text[TextNTon].Text := Text[TextNTon].Text + ' MedleyStart';
- if MedleyNotes.isEnd and (Czesci[0].Akt = MedleyNotes.end_.line) and
- (AktNuta = MedleyNotes.end_.note) then
+ if MedleyNotes.isEnd and (Czesci[CP].Akt = MedleyNotes.end_.line) and
+ (AktNuta[0] = MedleyNotes.end_.note) then
Text[TextNTon].Text := Text[TextNTon].Text + ' MedleyEnd';
//preview mod
- if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].IsStartPreview then
+ if Czesci[CP].Czesc[Czesci[CP].Akt].Nuta[AktNuta[CP]].IsStartPreview then
Text[TextNTon].Text := Text[TextNTon].Text + ' [PreviewStart]';
end;
@@ -2200,19 +2679,84 @@ begin
inherited Draw;
// draw notes
- SingDrawNoteLines(20, 305, 780, 15);
+ if not AktSong.isDuet then
+ SingDrawNoteLines(5, offset[0]+90, 795, 15)
+ else
+ begin
+ SingDrawNoteLines(5, offset[0]+45, 795, 15);
+ SingDrawNoteLines(5, offset[1]-140, 795, 15);
+ end;
+
//Error Drawing when no Song is loaded
if not Error then
begin
- SingDrawBeatDelimeters(40, 305, 760, 0);
- EditDrawCzesc(40, 410, 760, 0, 15);
+ if not AktSong.isDuet then
+ begin
+ SingDrawBeatDelimeters(5, offset[0]+90, 795, 0);
+ EditDrawCzesc(5, offset[0]+195, 795, 0, 15);
+ end else
+ begin
+ SingDrawBeatDelimeters(5, offset[0]+45, 795, 0);
+ EditDrawCzesc(5, offset[0]+150, 795, 0, 15);
+ SingDrawBeatDelimeters(5, offset[1]-140, 795, 1);
+ EditDrawCzesc(5, offset[1]-35, 795, 1, 15);
+ end;
end;
// draw text
- Lyric.Draw;
+ if not AktSong.isDuet then
+ begin
+ EditorLyric[0].Draw;
+ DrawInfoBar(0, 5, offset[0]+250, 790, 15);
+ end else
+ begin
+ EditorLyric[0].Draw;
+ DrawInfoBar(0, 5, offset[0]+185, 790, 15);
- DrawInfoBar(20, 460, 760, 20);
- glLineWidth(1); //bad fix...
+ EditorLyric[1].Draw;
+ DrawInfoBar(1, 5, offset[1]-160, 790, 15);
+ end;
+
+ if (CP=1) then
+ begin
+ glEnable(GL_BLEND);
+ glColor4f(0, 0, 0, 0.3);
+ //notes
+ glbegin(gl_quads);
+ glVertex2f(5, offset[0]+45);
+ glVertex2f(5, offset[0]+180);
+ glVertex2f(795, offset[0]+180);
+ glVertex2f(795, offset[0]+45);
+ glEnd;
+ //lyric
+ glbegin(gl_quads);
+ glVertex2f(5, offset[0]+5);
+ glVertex2f(5, offset[0]+35);
+ glVertex2f(795, offset[0]+35);
+ glVertex2f(795, offset[0]+5);
+ glEnd;
+ glDisable(GL_BLEND);
+ end else if AktSong.isDuet then
+ begin
+ glEnable(GL_BLEND);
+ glColor4f(0, 0, 0, 0.3);
+ //notes
+ glbegin(gl_quads);
+ glVertex2f(5, offset[1]-140);
+ glVertex2f(5, offset[1]-5);
+ glVertex2f(795, offset[1]-5);
+ glVertex2f(795, offset[1]-140);
+ glEnd;
+ //lyric
+ glbegin(gl_quads);
+ glVertex2f(5, offset[1]+35);
+ glVertex2f(5, offset[1]+5);
+ glVertex2f(795, offset[1]+5);
+ glVertex2f(795, offset[1]+35);
+ glEnd;
+ glDisable(GL_BLEND);
+ end;
+
if UVideo.VideoOpened and PlayVideo then
begin
@@ -2222,10 +2766,10 @@ begin
if VidVis=windowed then
begin
- Window.Left := 500;
- Window.Right := 770;
- Window.Upper := 65;
- Window.Lower := 250;
+ Window.Left := 570;
+ Window.Right := 790;
+ Window.Upper := 10;
+ Window.Lower := 145;
Window.Reflection := false;
Window.TargetAspect := acoCrop;
Window.windowed := true;
@@ -2266,11 +2810,22 @@ end;
procedure TScreenEditSub.DrawStatics;
var
x, y, w, h: Integer;
+
+ procedure DrawBorder(x, y, w, h: real);
+ begin
+ glColor4f(0, 0, 0, 1);
+ glLineWidth(2);
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(x-1, y-1);
+ glVertex2f(x+w+1, y-1);
+ glVertex2f(x+w+1, y+h+1);
+ glVertex2f(x-1, y+h+1);
+ glEnd;
+ end;
begin
- //Theme:
- //bg
glDisable(GL_BLEND);
+ //bg
x := 0;
y := 0;
w := 800;
@@ -2283,37 +2838,52 @@ begin
glVertex2f(x+w, y);
glEnd;
- // Line
- glColor4f(0.95, 0.95, 0.95, 1);
- x := 20;
- y := 5;
- w := 200;
- h := 40;
+ // line bg
+ if (CP=0) then
+ glColor4f(cRB, cGB, cBB, 1)
+ else
+ glColor4f(cRR, cGR, cBR, 1);
+ x := 650;
+ y := 570;
+ w := 145;
+ h := 25;
glbegin(gl_quads);
glVertex2f(x, y);
glVertex2f(x, y+h);
glVertex2f(x+w, y+h);
glVertex2f(x+w, y);
glEnd;
+ DrawBorder(x, y, w, h);
- // Note
- x := 260;
- y := 5;
- w := 200;
- h := 40;
+
+ // note bg
+ if (CP=0) then
+ glColor4f(cRB, cGB, cBB, 1)
+ else
+ glColor4f(cRR, cGR, cBR, 1);
+ x := 495;
+ y := 570;
+ w := 145;
+ h := 25;
glbegin(gl_quads);
glVertex2f(x, y);
glVertex2f(x, y+h);
glVertex2f(x+w, y+h);
glVertex2f(x+w, y);
glEnd;
+ DrawBorder(x, y, w, h);
+ // some borders:
- // some borders
- x := 20;
- y := 55;
- w := 760;
- h := 236;
+ //info box
+ x := 5;
+ y := 5;
+ w := 790;
+ if AktSong.isDuet then
+ h := 145
+ else
+ h := 150;
+
glColor4f(0.95, 0.95, 0.95, 1);
glbegin(gl_quads);
glVertex2f(x, y);
@@ -2321,62 +2891,82 @@ begin
glVertex2f(x+w, y+h);
glVertex2f(x+w, y);
glEnd;
-
- glColor4f(0, 0, 0, 1);
- glLineWidth(2);
- glBegin(GL_LINE_LOOP);
- glVertex2f(x-1, y-1);
- glVertex2f(x+w+1, y-1);
- glVertex2f(x+w+1, y+h+1);
- glVertex2f(x-1, y+h+1);
- glEnd;
-
- x := 20;
- y := 305;
- w := 760;
+ DrawBorder(x, y, w, h);
+
+ //notes singer 1
+ x := 5;
+ if AktSong.isDuet then
+ y := 200
+ else
+ y := 245;
+
+ w := 790;
h := 135;
- glColor4f(0.95, 0.95, 0.95, 1);
+ glColor4f(cRB, cGB, cBB, 1);
glbegin(gl_quads);
glVertex2f(x, y);
glVertex2f(x, y+h);
glVertex2f(x+w, y+h);
glVertex2f(x+w, y);
glEnd;
+ DrawBorder(x, y, w, h);
- glColor4f(0, 0, 0, 1);
- glLineWidth(2);
- glBegin(GL_LINE_LOOP);
- glVertex2f(x-1, y-1);
- glVertex2f(x+w+1, y-1);
- glVertex2f(x+w+1, y+h+1);
- glVertex2f(x-1, y+h+1);
- glEnd;
+ //notes singer 2
+ if AktSong.isDuet then
+ begin
+ x := 5;
+ y := 385;
+ w := 790;
+ h := 135;
+ glColor4f(cRR, cGR, cBR, 1);
+ glbegin(gl_quads);
+ glVertex2f(x, y);
+ glVertex2f(x, y+h);
+ glVertex2f(x+w, y+h);
+ glVertex2f(x+w, y);
+ glEnd;
+ DrawBorder(x, y, w, h);
+ end;
- x := 20;
- y := 500;
- w := 760;
- h := 40;
- glColor4f(0.95, 0.95, 0.95, 1);
+ //lyric singer 1
+ x := 5;
+ if AktSong.isDuet then
+ y := 160
+ else
+ y := 460;
+
+ w := 790;
+ h := 30;
+ glColor4f(cRB, cGB, cBB, 1);
glbegin(gl_quads);
glVertex2f(x, y);
glVertex2f(x, y+h);
glVertex2f(x+w, y+h);
glVertex2f(x+w, y);
glEnd;
+ DrawBorder(x, y, w, h);
- glColor4f(0, 0, 0, 1);
- glLineWidth(2);
- glBegin(GL_LINE_LOOP);
- glVertex2f(x-1, y-1);
- glVertex2f(x+w+1, y-1);
- glVertex2f(x+w+1, y+h+1);
- glVertex2f(x-1, y+h+1);
- glEnd;
+ //lyric singer 2
+ if AktSong.isDuet then
+ begin
+ x := 5;
+ y := 530;
+ w := 790;
+ h := 30;
+ glColor4f(cRR, cGR, cBR, 1);
+ glbegin(gl_quads);
+ glVertex2f(x, y);
+ glVertex2f(x, y+h);
+ glVertex2f(x+w, y+h);
+ glVertex2f(x+w, y);
+ glEnd;
+ DrawBorder(x, y, w, h);
+ end;
glLineWidth(1);
end;
-procedure TScreenEditSub.DrawInfoBar(x, y, w, h: integer);
+procedure TScreenEditSub.DrawInfoBar(P, x, y, w, h: integer);
var
start, end_: integer;
ww: integer;
@@ -2387,14 +2977,82 @@ var
line: integer;
numLines: integer;
+ function FindStart(): integer;
+ var
+ I: integer;
+ start: integer;
+ begin
+ start := High(integer);
+
+ for I := 0 to Length(Czesci[0].Czesc) - 1 do
+ begin
+ if (Length(Czesci[0].Czesc[I].Nuta)>0) then
+ begin
+ if(start > Czesci[0].Czesc[I].Nuta[0].Start) then
+ start := Czesci[0].Czesc[I].Nuta[0].Start;
+ end;
+ end;
+
+ Result := start;
+
+ if not AktSong.isDuet then
+ Exit;
+
+ for I := 0 to Length(Czesci[1].Czesc) - 1 do
+ begin
+ if (Length(Czesci[1].Czesc[I].Nuta)>0) then
+ begin
+ if(start > Czesci[1].Czesc[I].Nuta[0].Start) then
+ start := Czesci[1].Czesc[I].Nuta[0].Start;
+ end;
+ end;
+
+ Result := start;
+ end;
+
+ function FindEnd(): integer;
+ var
+ I: integer;
+ end_: integer;
+ h: integer;
+ begin
+ end_ := Low(integer);
+
+ for I := 0 to Length(Czesci[0].Czesc) - 1 do
+ begin
+ if (Length(Czesci[0].Czesc[I].Nuta)>0) then
+ begin
+ h := Length(Czesci[0].Czesc[I].Nuta)-1;
+ if(end_ < Czesci[0].Czesc[I].Nuta[h].Start + Czesci[0].Czesc[I].Nuta[h].Dlugosc) then
+ end_ := Czesci[0].Czesc[I].Nuta[h].Start + Czesci[0].Czesc[I].Nuta[h].Dlugosc;
+ end;
+ end;
+
+ Result := end_;
+
+ if not AktSong.isDuet then
+ Exit;
+
+ for I := 0 to Length(Czesci[1].Czesc) - 1 do
+ begin
+ if (Length(Czesci[1].Czesc[I].Nuta)>0) then
+ begin
+ h := Length(Czesci[1].Czesc[I].Nuta)-1;
+ if(end_ < Czesci[1].Czesc[I].Nuta[h].Start + Czesci[1].Czesc[I].Nuta[h].Dlugosc) then
+ end_ := Czesci[1].Czesc[I].Nuta[h].Start + Czesci[1].Czesc[I].Nuta[h].Dlugosc;
+ end;
+ end;
+
+ Result := end_;
+ end;
begin
- numLines := Length(Czesci[0].Czesc);
+ numLines := Length(Czesci[P].Czesc);
if(numLines=0) then
Exit;
- start := Czesci[0].Czesc[0].Start;
- end_ := Czesci[0].Czesc[numLines-1].Koniec;
+ start := FindStart;
+ end_ := FindEnd;
ww := end_ - start;
glColor4f(0, 0, 0, 1);
@@ -2407,7 +3065,10 @@ begin
glVertex2f(x-1, y+h+1);
glEnd;
- glColor4f(0.9, 0.9, 0.9, 1);
+ if (P=0) then
+ glColor4f(cRB, cGB, cBB, 1)
+ else
+ glColor4f(cRR, cGR, cBR, 1);
glbegin(gl_quads);
glVertex2f(x, y);
glVertex2f(x, y+h);
@@ -2418,32 +3079,27 @@ begin
for line := 0 to numLines - 1 do
begin
- if (line = Czesci[0].Akt) and not (PlaySentence or PlaySentenceMidi) then
+ if (line = Czesci[P].Akt) and not (PlaySentence or PlaySentenceMidi) then
glColor4f(0.4, 0.4, 0, 1)
else
glColor4f(1, 0.6, 0, 1);
-
- start := Czesci[0].Czesc[line].Nuta[0].Start;
- end_ := Czesci[0].Czesc[line].Nuta[Czesci[0].Czesc[line].HighNut].Start+
- Czesci[0].Czesc[line].Nuta[Czesci[0].Czesc[line].HighNut].Dlugosc;
-
- pos := start/ww*w;
- br := (end_-start)/ww*w;
-
- glbegin(gl_quads);
- glVertex2f(x+pos, y);
- glVertex2f(x+pos, y+h);
- glVertex2f(x+pos+br, y+h);
- glVertex2f(x+pos+br, y);
- glEnd;
- {
- numNotes := Length(Czesci[0].Czesc[line].Nuta);
-
- for note := 0 to numNotes - 1 do
+ if (Length(Czesci[P].Czesc[line].Nuta)>0) then
begin
-
- end; }
+ start := Czesci[P].Czesc[line].Nuta[0].Start;
+ end_ := Czesci[P].Czesc[line].Nuta[Czesci[P].Czesc[line].HighNut].Start+
+ Czesci[P].Czesc[line].Nuta[Czesci[P].Czesc[line].HighNut].Dlugosc;
+
+ pos := start/ww*w;
+ br := (end_-start)/ww*w;
+
+ glbegin(gl_quads);
+ glVertex2f(x+pos, y);
+ glVertex2f(x+pos, y+h);
+ glVertex2f(x+pos+br, y+h);
+ glVertex2f(x+pos+br, y);
+ glEnd;
+ end;
end;
@@ -2460,37 +3116,43 @@ begin
glVertex2f(x+pos+br, y);
glEnd;
- start := Czesci[0].Czesc[Czesci[0].Akt].Nuta[0].Start;
- end_ := Czesci[0].Czesc[Czesci[0].Akt].Nuta[Czesci[0].Czesc[Czesci[0].Akt].HighNut].Start+
- Czesci[0].Czesc[Czesci[0].Akt].Nuta[Czesci[0].Czesc[Czesci[0].Akt].HighNut].Dlugosc;
-
- pos := start/ww*w;
- br := (end_-start)/ww*w;
-
- glColor4f(0, 0, 0, 0.5);
-
- glEnable(GL_BLEND);
- glbegin(gl_quads);
- glVertex2f(x+pos, y);
- glVertex2f(x+pos, y+h);
- glVertex2f(x+pos+br, y+h);
- glVertex2f(x+pos+br, y);
- glEnd;
- glDisable(GL_BLEND);
+ if (Length(Czesci[P].Czesc[Czesci[P].Akt].Nuta)>0) then
+ begin
+ start := Czesci[P].Czesc[Czesci[P].Akt].Nuta[0].Start;
+ end_ := Czesci[P].Czesc[Czesci[P].Akt].Nuta[Czesci[P].Czesc[Czesci[P].Akt].HighNut].Start+
+ Czesci[P].Czesc[Czesci[P].Akt].Nuta[Czesci[P].Czesc[Czesci[P].Akt].HighNut].Dlugosc;
+
+ pos := start/ww*w;
+ br := (end_-start)/ww*w;
+
+ glColor4f(0, 0, 0, 0.5);
+
+ glEnable(GL_BLEND);
+ glbegin(gl_quads);
+ glVertex2f(x+pos, y);
+ glVertex2f(x+pos, y+h);
+ glVertex2f(x+pos+br, y+h);
+ glVertex2f(x+pos+br, y);
+ glEnd;
+ glDisable(GL_BLEND);
+ end;
end else
begin
glColor4f(1, 0, 0, 1);
- pos := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start/ww*w;
- br := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc/ww*w;
- if (br<1) then
- br := 1;
-
- glbegin(gl_quads);
- glVertex2f(x+pos, y);
- glVertex2f(x+pos, y+h);
- glVertex2f(x+pos+br, y+h);
- glVertex2f(x+pos+br, y);
- glEnd;
+ if (Length(Czesci[P].Czesc[Czesci[P].Akt].Nuta)>0) then
+ begin
+ pos := Czesci[P].Czesc[Czesci[P].Akt].Nuta[AktNuta[P]].Start/ww*w;
+ br := Czesci[P].Czesc[Czesci[P].Akt].Nuta[AktNuta[P]].Dlugosc/ww*w;
+ if (br<1) then
+ br := 1;
+
+ glbegin(gl_quads);
+ glVertex2f(x+pos, y);
+ glVertex2f(x+pos, y+h);
+ glVertex2f(x+pos+br, y+h);
+ glVertex2f(x+pos+br, y);
+ glEnd;
+ end;
end;
end;
diff --git a/Game/Code/Screens/UScreenMain.pas b/Game/Code/Screens/UScreenMain.pas
index b21a4778..156901e2 100644
--- a/Game/Code/Screens/UScreenMain.pas
+++ b/Game/Code/Screens/UScreenMain.pas
@@ -265,6 +265,8 @@ begin
end;
procedure TScreenMain.onShow;
+var
+ J: integer;
begin
ScreenSong.Mode := smNormal;
ScreenSong.SongIndex := -1;
diff --git a/Game/Code/Screens/UScreenOptionsGame.pas b/Game/Code/Screens/UScreenOptionsGame.pas
index c373b2d9..c698b046 100644
--- a/Game/Code/Screens/UScreenOptionsGame.pas
+++ b/Game/Code/Screens/UScreenOptionsGame.pas
@@ -7,12 +7,16 @@ uses
type
TScreenOptionsGame = class(TMenu)
- public
+ private
old_Tabs, old_Sorting: integer;
+
+ procedure Leave;
+ procedure RefreshSongs;
+
+ public
constructor Create; override;
function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
procedure onShow; override;
- procedure RefreshSongs;
end;
const
@@ -40,16 +44,13 @@ begin
SDLK_ESCAPE,
SDLK_BACKSPACE :
begin
- Music.PlayBack;
- RefreshSongs;
- FadeTo(@ScreenOptions);
+ Leave;
end;
SDLK_RETURN:
begin
- if SelInteraction = 7 then begin
- Music.PlayBack;
- RefreshSongs;
- FadeTo(@ScreenOptions);
+ if SelInteraction = 7 then
+ begin
+ Leave;
end;
end;
SDLK_DOWN:
@@ -116,4 +117,13 @@ begin
old_Tabs := Ini.Tabs;
end;
+procedure TScreenOptionsGame.Leave;
+begin
+
+
+ Music.PlayBack;
+ RefreshSongs;
+ FadeTo(@ScreenOptions);
+end;
+
end. \ No newline at end of file
diff --git a/Game/Code/Screens/UScreenPartyOptions.pas b/Game/Code/Screens/UScreenPartyOptions.pas
index 8576b596..deeb8c96 100644
--- a/Game/Code/Screens/UScreenPartyOptions.pas
+++ b/Game/Code/Screens/UScreenPartyOptions.pas
@@ -235,6 +235,7 @@ begin
PartySession.StartNewParty(Rounds + 2);
Music.PlayStart;
+
//Go to Player Screen
FadeTo(@ScreenPartyPlayer);
end;
@@ -491,7 +492,7 @@ begin
SetLength(IPlaylist2, 0);
For I := 0 to high(CatSongs.Song) do
begin
- If (CatSongs.Song[I].Main) then
+ If CatSongs.Song[I].Main and (CatSongs.NumCatSongs(CatSongs.Song[I].OrderNum)>0) then
begin
SetLength(IPlaylist2, Length(IPlaylist2) + 1);
IPlaylist2[high(IPlaylist2)] := CatSongs.Song[I].Artist;
@@ -636,6 +637,7 @@ begin
end;
SelectedPlugin := 0;
+ ScreenSong.Mode := smParty;
end;
procedure TScreenPartyOptions.SetAnimationProgress(Progress: real);
diff --git a/Game/Code/Screens/UScreenPartyOptionsM2.pas b/Game/Code/Screens/UScreenPartyOptionsM2.pas
index 17c6560e..057881f9 100644
--- a/Game/Code/Screens/UScreenPartyOptionsM2.pas
+++ b/Game/Code/Screens/UScreenPartyOptionsM2.pas
@@ -649,7 +649,7 @@ begin
SetLength(IPlaylist2, 0);
for I := 0 to high(CatSongs.Song) do
begin
- if (CatSongs.Song[I].Main) then
+ if CatSongs.Song[I].Main and (CatSongs.NumCatSongs(CatSongs.Song[I].OrderNum)>0) then
begin
SetLength(IPlaylist2, Length(IPlaylist2) + 1);
IPlaylist2[high(IPlaylist2)] := CatSongs.Song[I].Artist;
@@ -797,6 +797,7 @@ begin
end;
SelectedPlugin := 0;
+ ScreenSong.Mode := smChallenge;
end;
function TScreenPartyOptionsM2.Draw: boolean;
diff --git a/Game/Code/Screens/UScreenSing.pas b/Game/Code/Screens/UScreenSing.pas
index e06da0e7..9fba0ba0 100644
--- a/Game/Code/Screens/UScreenSing.pas
+++ b/Game/Code/Screens/UScreenSing.pas
@@ -15,12 +15,15 @@ type
protected
paused: boolean; //Pause Mod
PauseTime: Real;
- NumEmptySentences: integer;
+ NumEmptySentences: array [0..1] of integer;
public
//TextTime: integer;
MP3Volume: integer;
MP3VolumeHandler: THandler;
+ //Lyric bar for Duet mode
+ StaticLyricDuetBar: integer;
+
//TimeBar mod
StaticTimeProgress: integer;
TextTimeText: integer;
@@ -70,8 +73,8 @@ type
Tex_Background: TTexture;
FadeOut: boolean;
- LyricMain: TLyric;
- LyricSub: TLyric;
+ LyricMain: array [0..1] of TLyric;
+ LyricSub: array [0..1] of TLyric;
//VideoAspect
VideoAspectText: integer;
@@ -95,7 +98,7 @@ type
procedure Pause; //Pause Mod(Toggles Pause)
//OnSentenceEnd for LineBonus + Singbar
- procedure onSentenceEnd(S: Cardinal);
+ procedure onSentenceEnd(CP: integer; S: Cardinal);
//OnSentenceChange (for Golden Notes)
procedure onSentenceChange(S: Cardinal);
@@ -103,6 +106,9 @@ type
procedure LoadNextSong;
procedure UpdateMedleyStats(medley_end: boolean);
procedure DrawMedleyCountdown();
+
+ procedure SetLyricFontMain(Lyric: TLyric);
+ procedure SetLyricFontSub(Lyric: TLyric);
end;
const
@@ -252,6 +258,8 @@ begin
LoadFromTheme(Theme.Sing);
+ StaticLyricDuetBar := AddStatic(Theme.Sing.StaticLyricDuetBar);
+
//TimeBar mod
StaticTimeProgress := AddStatic(Theme.Sing.StaticTimeProgress);
TextTimeText := AddText(Theme.Sing.TextTimeText);
@@ -306,8 +314,10 @@ begin
VideoAspectStatic:= AddStatic(Theme.Sing.VideoAspectStatic);
VideoAspectText:= AddText(Theme.Sing.VideoAspectText);
- LyricMain := TLyric.Create;
- LyricSub := TLyric.Create;
+ LyricMain[0] := TLyric.Create;
+ LyricSub[0] := TLyric.Create;
+ LyricMain[1] := TLyric.Create;
+ LyricSub[1] := TLyric.Create;
UVideo.Init;
MP3Volume := 100;
@@ -676,82 +686,6 @@ begin
end;
//Set Position of Line Bonus - PhrasenBonus End
- // main text
- LyricMain.Clear;
- LyricMain.X := 400;
- LyricMain.Y := Skin_LyricsT;
- LyricMain.Scale := 1.4; //1.4
- LyricMain.Align := 1;
-
- // sub text
- LyricSub.Clear;
- LyricSub.X := 400;
- LyricSub.Y := Skin_LyricsT + 35; //42 //40
- LyricSub.Align := 1;
-
- // set custom options
- case Ini.LyricsFont of
- 0:
- begin
- LyricMain.FontStyle := 0;
- LyricSub.FontStyle := 0;
- LyricMain.Size := 14; // 13
- LyricSub.Size := 14; // 13
- LyricMain.ColR := Skin_FontR;
- LyricMain.ColG := Skin_FontG;
- LyricMain.ColB := Skin_FontB; //Change für Crazy Joker
- {LyricMain.ColSR := Skin_FontHighlightR;
- LyricMain.ColSG := Skin_FontHighlightG;
- LyricMain.ColSB := Skin_FontHighlightB;1aa5dc}
- LyricMain.ColSR := 5/255; //26
- LyricMain.ColSG := 163/255; //165
- LyricMain.ColSB := 210/255; //220
-
- LyricSub.ColR := 0.4; //0.6
- LyricSub.ColG := 0.4; //0.6
- LyricSub.ColB := 0.4; //0.6
- end;
- 1:
- begin
- LyricMain.FontStyle := 2;
- LyricSub.FontStyle := 2;
- LyricMain.Size := 14;
- LyricSub.Size := 14;
- LyricMain.ColR := 0.75;
- LyricMain.ColG := 0.75;
- LyricMain.ColB := 1;
- LyricMain.ColSR := 0.5;
- LyricMain.ColSG := 0.5;
- LyricMain.ColSB := 1;
- LyricSub.ColR := 0.8;
- LyricSub.ColG := 0.8;
- LyricSub.ColB := 0.8;
- end;
- 2:
- begin
- LyricMain.FontStyle := 3;
- LyricSub.FontStyle := 3;
- LyricMain.Size := 12;
- LyricSub.Size := 12;
- LyricMain.ColR := 0.75;
- LyricMain.ColG := 0.75;
- LyricMain.ColB := 1;
- LyricMain.ColSR := 0.5;
- LyricMain.ColSG := 0.5;
- LyricMain.ColSB := 1;
- LyricSub.ColR := 0.8;
- LyricSub.ColG := 0.8;
- LyricSub.ColB := 0.8;
- end;
- end; // case
-
- case Ini.LyricsEffect of
- 0: LyricMain.Style := 1; // 0 - one selected, 1 - selected all to the current
- 1: LyricMain.Style := 2;
- 2: LyricMain.Style := 3;
- 3: LyricMain.Style := 4;
- end; // case
-
LoadNextSong;
Log.LogStatus('End', 'onShow');
@@ -810,6 +744,87 @@ begin
end;
end;
+procedure TScreenSing.SetLyricFontMain(Lyric: TLyric);
+begin
+ // set custom options
+ case Ini.LyricsFont of
+ 0:
+ begin
+ Lyric.FontStyle := 0;
+ Lyric.Size := 14; // 13
+ Lyric.ColR := Skin_FontR;
+ Lyric.ColG := Skin_FontG;
+ Lyric.ColB := Skin_FontB; //Change für Crazy Joker
+ {Lyric.ColSR := Skin_FontHighlightR;
+ Lyric.ColSG := Skin_FontHighlightG;
+ Lyric.ColSB := Skin_FontHighlightB;1aa5dc}
+ Lyric.ColSR := 5/255; //26
+ Lyric.ColSG := 163/255; //165
+ Lyric.ColSB := 210/255; //220
+ end;
+ 1:
+ begin
+ Lyric.FontStyle := 2;
+ Lyric.Size := 14;
+ Lyric.ColR := 0.75;
+ Lyric.ColG := 0.75;
+ Lyric.ColB := 1;
+ Lyric.ColSR := 0.5;
+ Lyric.ColSG := 0.5;
+ Lyric.ColSB := 1;
+ end;
+ 2:
+ begin
+ Lyric.FontStyle := 3;
+ Lyric.Size := 12;
+ Lyric.ColR := 0.75;
+ Lyric.ColG := 0.75;
+ Lyric.ColB := 1;
+ Lyric.ColSR := 0.5;
+ Lyric.ColSG := 0.5;
+ Lyric.ColSB := 1;
+ end;
+ end; // case
+
+ case Ini.LyricsEffect of
+ 0: Lyric.Style := 1; // 0 - one selected, 1 - selected all to the current
+ 1: Lyric.Style := 2;
+ 2: Lyric.Style := 3;
+ 3: Lyric.Style := 4;
+ end; // case
+end;
+
+procedure TScreenSing.SetLyricFontSub(Lyric: TLyric);
+begin
+ // set custom options
+ case Ini.LyricsFont of
+ 0:
+ begin
+ Lyric.FontStyle := 0;
+ Lyric.Size := 14; // 13
+ Lyric.ColR := 0.4; //0.6
+ Lyric.ColG := 0.4; //0.6
+ Lyric.ColB := 0.4; //0.6
+ end;
+ 1:
+ begin
+ Lyric.FontStyle := 2;
+ Lyric.Size := 14;
+ Lyric.ColR := 0.8;
+ Lyric.ColG := 0.8;
+ Lyric.ColB := 0.8;
+ end;
+ 2:
+ begin
+ Lyric.FontStyle := 3;
+ Lyric.Size := 12;
+ Lyric.ColR := 0.8;
+ Lyric.ColG := 0.8;
+ Lyric.ColB := 0.8;
+ end;
+ end; // case
+end;
+
procedure TScreenSing.LoadNextSong;
var
P, I: integer;
@@ -906,6 +921,46 @@ begin
Czas.Razem := AktSong.Finish / 1000;
end;
+ // main text
+ LyricMain[0].Clear;
+ LyricMain[0].X := 400;
+ LyricMain[0].Y := Skin_LyricsT;
+ LyricMain[0].Scale := 1.4; //1.4
+ LyricMain[0].Align := 1;
+
+ // sub text
+ LyricSub[0].Clear;
+ LyricSub[0].X := 400;
+ LyricSub[0].Y := Skin_LyricsT + 35; //42 //40
+ LyricSub[0].Align := 1;
+
+ SetLyricFontMain(LyricMain[0]);
+ SetLyricFontSub(LyricSub[0]);
+
+ if AktSong.isDuet then
+ begin
+ // main text
+ LyricMain[1].Clear;
+ LyricMain[1].X := 400;
+ LyricMain[1].Y := Skin_LyricsT;
+ LyricMain[0].Y := 5{Skin_LyricsT};
+ LyricMain[1].Scale := 1.4;
+ LyricMain[1].Align := 1;
+
+ // sub text
+ LyricSub[1].Clear;
+ LyricSub[1].X := 400;
+ LyricSub[0].Y := 5{Skin_LyricsT} + 35;
+ LyricSub[1].Y := Skin_LyricsT + 35;
+ LyricSub[1].Align := 1;
+
+ SetLyricFontMain(LyricMain[1]);
+ SetLyricFontSub(LyricSub[1]);
+
+ Static[StaticLyricDuetBar].Visible := true;
+ end else
+ Static[StaticLyricDuetBar].Visible := false;
+
Czas.OldBeat := -1;
@@ -913,10 +968,19 @@ begin
ClearScores(P);
// fill texts
- LyricMain.AddCzesc(0);
- LyricMain.Selected := -1;
- LyricSub.AddCzesc(1);
- LyricSub.Selected := -1;
+ LyricMain[0].AddCzesc(0, 0);
+ LyricMain[0].Selected := -1;
+ LyricSub[0].AddCzesc(0, 1);
+ LyricSub[0].Selected := -1;
+
+ if AktSong.isDuet then
+ begin
+ // fill texts
+ LyricMain[1].AddCzesc(1, 0);
+ LyricMain[1].Selected := -1;
+ LyricSub[1].AddCzesc(1, 1);
+ LyricSub[1].Selected := -1;
+ end;
//Deactivate Pause
Paused := False;
@@ -927,9 +991,14 @@ begin
//GoldenStarsTwinkle Mod End
//Set Num of Empty Sentences for Phrasen Bonus
- NumEmptySentences := 0;
- for P := low(Czesci[0].Czesc) to high(Czesci[0].Czesc) do
- if Czesci[0].Czesc[P].TotalNotes = 0 then Inc(NumEmptySentences);
+ NumEmptySentences[0] := 0;
+ NumEmptySentences[1] := 0;
+
+ for I := 0 to Length(Czesci) - 1 do
+ begin
+ for P := low(Czesci[I].Czesc) to high(Czesci[I].Czesc) do
+ if Czesci[I].Czesc[P].TotalNotes = 0 then Inc(NumEmptySentences[I]);
+ end;
if (ScreenSong.Mode = smMedley) or ScreenSong.PartyMedley then
begin
@@ -1142,9 +1211,13 @@ begin
lastLine := Length(Czesci[0].Czesc)-1;
lastWord := Length(Czesci[0].Czesc[lastLine].Nuta)-1;
- if (Czas.AktBeat>(Czesci[0].Czesc[lastLine].Nuta[lastWord].Start+
- Czesci[0].Czesc[lastLine].Nuta[lastWord].Dlugosc)) then
- ScreenSong.SungToEnd := true;
+
+ if (lastLine>=0) and (lastWord>=0) then
+ begin
+ if (Czas.AktBeat>(Czesci[0].Czesc[lastLine].Nuta[lastWord].Start+
+ Czesci[0].Czesc[lastLine].Nuta[lastWord].Dlugosc)) then
+ ScreenSong.SungToEnd := true;
+ end;
// for medley-mode:
CurTime := Czas.Teraz;
@@ -1569,15 +1642,15 @@ begin
end;
end;
-procedure TScreenSing.onSentenceEnd(S: Cardinal);
+procedure TScreenSing.onSentenceEnd(CP: integer; S: Cardinal);
var
-I: Integer;
-A: Real;
-B: integer; //Max Points for Notes
-begin
+ I: Integer;
+ A: Real;
+ B: integer; //Max Points for Notes
+begin
//Check for Empty Sentence
- if (Czesci[0].Czesc[S].TotalNotes<=0) then
+ if (Czesci[CP].Czesc[S].TotalNotes<=0) then
exit;
//Set Max Note Points
@@ -1586,27 +1659,30 @@ begin
else
B := 10000;
- for I := 0 to High(Player) do begin
+ for I := 0 to High(Player) do
+ begin
+ if not AktSong.isDuet or (I mod 2 = CP) then
+ begin
+
A := Player[I].Score + Player[I].ScoreGolden - Player[I].ScoreLast + 2;
//SingBar Mod
- If ({(Ini.Oscilloscope = 2) and }(Czesci[0].Czesc[S].TotalNotes>0)) then
+ If (Czesci[CP].Czesc[S].TotalNotes>0) then
begin
- Player[I].ScorePercentTarget := Player[I].ScorePercentTarget + floor(A / (B * Czesci[0].Czesc[S].TotalNotes / Czesci[0].Wartosc) * 40 - 26);
+ Player[I].ScorePercentTarget := Player[I].ScorePercentTarget +
+ floor(A / (B * Czesci[0].Czesc[S].TotalNotes / Czesci[CP].Wartosc) * 40 - 26);
if Player[I].ScorePercentTarget < 0 then Player[I].ScorePercentTarget := 0;
if Player[I].ScorePercentTarget > 99 then Player[I].ScorePercentTarget := 99;
-
//end Singbar Mod
end;
//PhrasenBonus - Line Bonus Mod
//Generate Steps 0 to 8
- A := Floor(A / (B * Czesci[0].Czesc[S].TotalNotes / Czesci[0].Wartosc) * 8);
+ A := Floor(A / (B * Czesci[CP].Czesc[S].TotalNotes / Czesci[CP].Wartosc) * 8);
If (Ini.LineBonus > 0) then
begin
-
//Generate Text
if A >= 8 then
Player[I].LineBonus_Text := Theme.Sing.LineBonusText[8]
@@ -1614,7 +1690,8 @@ begin
Player[I].LineBonus_Text := Theme.Sing.LineBonusText[Floor(A)];
//PhrasenBonus give Points
- Player[I].ScoreLine := Player[I].ScoreLine + (1000 / (Length(Czesci[0].Czesc) - NumEmptySentences) * A / 8);
+ Player[I].ScoreLine := Player[I].ScoreLine +
+ (1000 / (Length(Czesci[CP].Czesc) - NumEmptySentences[I mod 2]) * A / 8);
Player[I].ScoreLineI := Round(Player[I].ScoreLine / 10) * 10;
//Update Total Score
Player[I].ScoreTotalI := Player[I].ScoreI + Player[I].ScoreGoldenI + Player[I].ScoreLineI;
@@ -1657,6 +1734,7 @@ begin
Player[I].LineBonus_Visible := True;
Player[I].LineBonus_Age := 1;
end;
+
//PhrasenBonus - Line Bonus Mod End// }
//PerfectLineTwinkle Mod (effect) Pt.1
@@ -1667,9 +1745,10 @@ begin
end;
//PerfectLineTwinkle Mod end
- //Refresh LastScore
- Player[I].ScoreLast := Player[I].Score + Player[I].ScoreGolden;
-
+ //Refresh LastScore
+ Player[I].ScoreLast := Player[I].Score + Player[I].ScoreGolden;
+ end else
+ Player[I].LineBonus_Visible := false;
end;
//PerfectLineTwinkle Mod (effect) Pt.2
diff --git a/Game/Code/Screens/UScreenSong.pas b/Game/Code/Screens/UScreenSong.pas
index 43cdaba5..d7ba5619 100644
--- a/Game/Code/Screens/UScreenSong.pas
+++ b/Game/Code/Screens/UScreenSong.pas
@@ -58,6 +58,9 @@ type
SongIndex: integer; //Index of Song that is playing since UScreenScore...
+ //Duet Icon
+ DuetIcon: cardinal;
+
//Video Icon Mod
VideoIcon: Cardinal;
@@ -384,10 +387,12 @@ begin
If (PressedDown) Then
begin // Key Down
- if (WaitHandler.active) and not (PressedKey IN [SDLK_RETURN, SDLK_TAB, SDLK_F,
- SDLK_A, SDLK_E, SDLK_K, SDLK_M, SDLK_P, SDLK_S, SDLK_V]) then
+ if (WaitHandler.active) and not ((PressedKey IN [SDLK_RETURN, SDLK_TAB, SDLK_F,
+ SDLK_A, SDLK_E, SDLK_K, SDLK_M, SDLK_P, SDLK_S, SDLK_V]) or
+ (PressedKey = SDLK_RIGHT) or (PressedKey = SDLK_LEFT) or
+ (PressedKey = SDLK_PAGEUP) or (PressedKey = SDLK_PAGEDOWN)) then
begin
- if (Ini.Tabs=1) and not (CatSongs.CatNumShow = -3) then
+ if (Ini.Tabs=1) and not (CatSongs.CatNumShow < -1) then
begin
//Search Cat
for I := WaitHandler.lastIndex downto low(CatSongs.Song) do
@@ -418,8 +423,10 @@ begin
if (WaitHandler.active) then
begin
WaitHandler.active := false;
- if (not PressedKey IN [SDLK_RETURN, SDLK_TAB, SDLK_F,
- SDLK_A, SDLK_E, SDLK_K, SDLK_M, SDLK_P, SDLK_S, SDLK_V]) then
+ if not ((PressedKey IN [SDLK_RETURN, SDLK_TAB, SDLK_F,
+ SDLK_A, SDLK_E, SDLK_K, SDLK_M, SDLK_P, SDLK_S, SDLK_V]) or
+ (PressedKey = SDLK_RIGHT) or (PressedKey = SDLK_LEFT) or
+ (PressedKey = SDLK_PAGEUP) or (PressedKey = SDLK_PAGEDOWN)) then
Exit;
end;
end;
@@ -675,10 +682,18 @@ begin
acClose;
FadeTo(@ScreenMain);
+ end else if (Mode = smChallenge) then
+ begin
+ Music.PlayBack;
+ CheckFadeTo(@ScreenMain,'MSG_END_PARTY');
end;
-
end;
end
+ else if (Mode = smChallenge) then
+ begin
+ Music.PlayBack;
+ CheckFadeTo(@ScreenMain,'MSG_END_PARTY');
+ end
//When in party Mode then Ask before Close
else if (Mode = smParty) then
begin
@@ -715,6 +730,12 @@ begin
end else
begin // clicked on song
+ if (CatSongs.Song[Interaction].isDuet and (PlayersPlay=1)) then
+ begin
+ ScreenPopupError.ShowPopup('It is a Duet Song! You need at least 2 Players.');
+ Exit;
+ end;
+
if (Mode = smNormal) then //Normal Mode -> Start Song
begin
if MakeMedley then
@@ -1089,6 +1110,9 @@ begin
SDLK_T:
begin
+ if Mode<>smNormal then
+ Exit;
+
if (SDL_ModState = KMOD_LSHIFT) then
begin
//Change Sorting
@@ -1174,6 +1198,8 @@ begin
ChangeMusic;
end;
+ Ini.Save;
+
InfoHandler.changed := true;
InfoHandler.change_time := 0;
end;
@@ -1330,6 +1356,9 @@ begin
//Show Video Icon Mod
VideoIcon := AddStatic(Theme.Song.VideoIcon);
+ //Duet Icon
+ DuetIcon := AddStatic(Theme.Song.DuetIcon);
+
//Meldey Icons
MedleyIcon := AddStatic(Theme.Song.MedleyIcon);
CalcMedleyIcon := AddStatic(Theme.Song.CalculatedMedleyIcon);
@@ -1423,6 +1452,9 @@ begin
//Set Visibility of Video Icon
Static[VideoIcon].Visible := (CatSongs.Song[Interaction].Video <> '');
+ //Set Visibility of Duet Icon
+ Static[DuetIcon].Visible := CatSongs.Song[Interaction].isDuet;
+
// Set visibility of medley icons
if Mode=smNormal then
begin
@@ -1456,11 +1488,12 @@ begin
begin
if (Ini.Tabs = 1) and (CatSongs.CatNumShow = -1) then
begin
- Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].OrderNum) + '/' + IntToStr(CatSongs.CatCount);
+ Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(CatSongs.NumVisibleCats);
Text[TextTitle].Text := '(' +
- IntToStr(CatSongs.Song[Interaction].CatNumber - PartySessionM2.GetSongsPlayed(CatSongs.Song[Interaction].OrderNum)) +
+ IntToStr(CatSongs.NumCatSongs(CatSongs.Song[Interaction].OrderNum)
+ - PartySessionM2.GetSongsPlayed(CatSongs.Song[Interaction].OrderNum)) +
'/' +
- IntToStr(CatSongs.Song[Interaction].CatNumber) + ' ' + Language.Translate('SING_SONGS_IN_CAT') + ')'; //AND HERE!
+ IntToStr(CatSongs.NumCatSongs(CatSongs.Song[Interaction].OrderNum)) + ' ' + Language.Translate('SING_SONGS_IN_CAT') + ')'; //AND HERE!
end else if (CatSongs.CatNumShow = -2) then
Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS)
else if (CatSongs.CatNumShow = -3) then
@@ -1470,16 +1503,15 @@ begin
' (' + IntToStr(ChooseableSongs) + ')';
end else if (Ini.Tabs = 1) then
begin
- ChooseableSongs:=CatSongs.Song[Interaction - CatSongs.Song[Interaction].CatNumber].CatNumber -
- PartySessionM2.GetSongsPlayed(CatSongs.CatNumShow) - GetSongsSkipped();
+ ChooseableSongs:=VS - PartySessionM2.GetSongsPlayed(CatSongs.CatNumShow) - GetSongsSkipped();
- Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].CatNumber) + '/' +
- IntToStr(CatSongs.Song[Interaction - CatSongs.Song[Interaction].CatNumber].CatNumber) + ' (' +
+ Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' +
+ IntToStr(VS) + ' (' +
IntToStr(ChooseableSongs) + ')'; //HERE!
end else
begin
- ChooseableSongs:=Length(CatSongs.Song)-PartySessionM2.GetSongsPlayed(CatSongs.CatNumShow)-GetSongsSkipped();
- Text[TextNumber].Text := IntToStr(Interaction+1) + '/' + IntToStr(Length(CatSongs.Song)) + ' (' +
+ ChooseableSongs:=VS-PartySessionM2.GetSongsPlayed(CatSongs.CatNumShow)-GetSongsSkipped();
+ Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS) + ' (' +
IntToStr(ChooseableSongs) + ')'; //HERE!
end
end else if PartyMedley then//PartyMedley
@@ -1520,8 +1552,8 @@ begin
end;
ChooseableSongs := Length(VisArr);
- Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].CatNumber) + '/' +
- IntToStr(CatSongs.Song[Interaction - CatSongs.Song[Interaction].CatNumber].CatNumber) + ' (' +
+ Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' +
+ IntToStr(CatSongs.NumCatSongs(CatSongs.Song[Interaction].OrderNum)) + ' (' +
IntToStr(ChooseableSongs) + ')'; //HERE!
end else
begin
@@ -1535,7 +1567,7 @@ begin
end;
end;
ChooseableSongs := Length(VisArr);
- Text[TextNumber].Text := IntToStr(Interaction+1) + '/' + IntToStr(Length(CatSongs.Song)) + ' (' +
+ Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS) + ' (' +
IntToStr(ChooseableSongs) + ')'; //HERE!
end;
end else if (Mode=smParty) then//Party
@@ -1550,7 +1582,8 @@ begin
begin
for I := 0 to Length(CatSongs.Song) - 1 do
begin
- if CatSongs.Song[I].Visible and not PartyPlayedSong(I) and not SongSkipped(I) then
+ if CatSongs.Song[I].Visible and not PartyPlayedSong(I) and not SongSkipped(I) and
+ not CatSongs.Song[I].isDuet then
begin
SetLength(VisArr, Length(VisArr)+1);
VisArr[Length(VisArr)-1] := I;
@@ -1563,7 +1596,8 @@ begin
begin
for I := 0 to Length(CatSongs.Song) - 1 do
begin
- if not CatSongs.Song[I].Main and not PartyPlayedSong(I) and not SongSkipped(I) then
+ if not CatSongs.Song[I].Main and not PartyPlayedSong(I) and not SongSkipped(I) and
+ not CatSongs.Song[I].isDuet then
begin
if (PlaylistMan.Mode=0) or ((PlaylistMan.Mode<>0) and CatSongs.Song[I].Visible) then
begin
@@ -1574,9 +1608,8 @@ begin
end;
ChooseableSongs := Length(VisArr);
- Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].CatNumber) + '/' +
- IntToStr(CatSongs.Song[Interaction - CatSongs.Song[Interaction].CatNumber].CatNumber) + ' (' +
- IntToStr(ChooseableSongs) + ')'; //HERE!
+ Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' +
+ IntToStr(VS) + ' (' + IntToStr(ChooseableSongs) + ')'; //HERE!
end else
begin
for I := 0 to Length(CatSongs.Song) - 1 do
@@ -1588,7 +1621,7 @@ begin
end;
end;
ChooseableSongs := Length(VisArr);
- Text[TextNumber].Text := IntToStr(Interaction+1) + '/' + IntToStr(Length(CatSongs.Song)) + ' (' +
+ Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS) + ' (' +
IntToStr(ChooseableSongs) + ')'; //HERE!
end;
end;
@@ -2094,6 +2127,13 @@ begin
FixSelected;
ChangeMusic;
+ end else if (Mode<>smNormal) and (Ini.Tabs = 0) then
+ begin
+ CatSongs.SetFilter('', 0);
+ end else if (Ini.Tabs = 0) then
+ begin
+ CatSongs.SetFilter('', 0);
+ FixSelected;
end;
@@ -2225,7 +2265,8 @@ begin
if not PartyMedley then
begin
if CatSongs.Song[I].Visible and not SongSkipped(I) and
- not PartySessionM2.SongPlayed(CatSongs.CatNumShow, I) then
+ not PartySessionM2.SongPlayed(CatSongs.CatNumShow, I) and
+ not CatSongs.Song[I].isDuet then
begin
SetLength(VisArr, Length(VisArr)+1);
VisArr[Length(VisArr)-1] := I;
@@ -2590,7 +2631,7 @@ begin
WaitHandler.lastCat := CatSongs.CatNumShow;
end;
- if(Ini.Tabs<>1) or (CatSongs.CatNumShow = -3) then
+ if(Ini.Tabs<>1) or (CatSongs.CatNumShow < -1) then
begin
//Random in one Category
SetLength(VisArr, 0);
@@ -3108,7 +3149,8 @@ begin
begin
if not PartyMedley then
begin
- if not CatSongs.Song[I].Main and not SongSkipped(I) and not PartyPlayedSong(I) then
+ if not CatSongs.Song[I].Main and not SongSkipped(I) and
+ not PartyPlayedSong(I) and not CatSongs.Song[I].isDuet then
begin
SetLength(VisArr, Length(VisArr)+1);
VisArr[Length(VisArr)-1] := I;
@@ -3159,7 +3201,8 @@ begin
begin
if not PartyMedley then
begin
- if not CatSongs.Song[I].Main and not SongSkipped(I) and not PartyPlayedSong(I) then
+ if not CatSongs.Song[I].Main and not SongSkipped(I) and not PartyPlayedSong(I) and
+ not CatSongs.Song[I].isDuet then
begin
SetLength(VisArr, Length(VisArr)+1);
VisArr[Length(VisArr)-1] := I;
@@ -3201,7 +3244,8 @@ begin
begin
if not PartyMedley then
begin
- if CatSongs.Song[I].Visible and not SongSkipped(I) and not PartyPlayedSong(I) then
+ if CatSongs.Song[I].Visible and not SongSkipped(I) and not PartyPlayedSong(I) and
+ not CatSongs.Song[I].isDuet then
begin
SetLength(VisArr, Length(VisArr)+1);
VisArr[Length(VisArr)-1] := I;
@@ -3240,7 +3284,8 @@ begin
begin
if not PartyMedley then
begin
- if CatSongs.Song[I].Visible and not SongSkipped(I) and not PartyPlayedSong(I) then
+ if CatSongs.Song[I].Visible and not SongSkipped(I) and not PartyPlayedSong(I) and
+ not CatSongs.Song[I].isDuet then
begin
SetLength(VisArr, Length(VisArr)+1);
VisArr[Length(VisArr)-1] := I;
@@ -3881,7 +3926,7 @@ begin
AddSong(VS);
SetLength(MedleyPlayed, Length(MedleyPlayed)+1);
- MedleyPlayed[Length(MedleyPlayed)-1] := VS;
+ MedleyPlayed[Length(MedleyPlayed)-1] := VS;
end;
end;
end else if MakeMedley then
@@ -3911,7 +3956,9 @@ begin
end;
end else if PartyMedley then
begin
- if (PlaylistMedley.NumMedleySongs = num) then
+ if (PlaylistMedley.NumMedleySongs = num) or
+ ((Mode=smParty) and (PartySession.Rounds[PartySession.CurRound].MedleySurprise)) or
+ ((Mode=smChallenge) and (PartySessionM2.Rounds[PartySessionM2.CurRound].MedleySurprise)) then
begin
Music.Stop;
FadeTo(@ScreenSingModi);
diff --git a/Game/Code/Screens/UScreenSongJumpto.pas b/Game/Code/Screens/UScreenSongJumpto.pas
index ed86757b..c79fff65 100644
--- a/Game/Code/Screens/UScreenSongJumpto.pas
+++ b/Game/Code/Screens/UScreenSongJumpto.pas
@@ -9,8 +9,9 @@ type
TScreenSongJumpto = class(TMenu)
private
//For ChangeMusic
- LastPlayed: Integer;
- VisibleBool: Boolean;
+ LastPlayed: Integer;
+ VisibleBool: Boolean;
+ isDuet: Boolean;
public
VisSongs: Integer;
@@ -45,12 +46,19 @@ begin
If (PressedDown) Then
begin // Key Down
case PressedKey of
- SDLK_0..SDLK_9, SDLK_A..SDLK_Z, SDLK_SPACE, SDLK_MINUS, SDLK_EXCLAIM, SDLK_COMMA, SDLK_SLASH, SDLK_ASTERISK, SDLK_QUESTION, SDLK_QUOTE, SDLK_QUOTEDBL, SDLK_LEFTBRACKET, SDLK_SEMICOLON:
+ SDLK_0..SDLK_9, SDLK_A..SDLK_Z,
+ SDLK_SPACE, SDLK_MINUS, SDLK_EXCLAIM,
+ SDLK_COMMA, SDLK_SLASH, SDLK_ASTERISK,
+ SDLK_QUESTION, SDLK_QUOTE, SDLK_QUOTEDBL,
+ SDLK_LEFTBRACKET, SDLK_SEMICOLON:
begin
- if Interaction = 0 then
+ if not isDuet then
begin
- Button[0].Text[0].Text := Button[0].Text[0].Text + chr(ScanCode);
- SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType));
+ if Interaction = 0 then
+ begin
+ Button[0].Text[0].Text := Button[0].Text[0].Text + chr(ScanCode);
+ SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType));
+ end;
end;
end;
@@ -85,10 +93,30 @@ begin
SDLK_BACKSPACE:
begin
- if (Interaction = 0) AND (Length(Button[0].Text[0].Text) > 0) then
+ if (Interaction = 0) AND (Length(Button[0].Text[0].Text) > 0) and not isDuet then
begin
Button[0].Text[0].DeleteLastL;
SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType));
+ end else if (Interaction = 0) and isDuet then
+ begin
+ Button[0].Text[0].Text := '';
+ SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType));
+ end;
+ end;
+
+ SDLK_F1:
+ begin
+ if not isDuet then
+ begin
+ //show/hide duet songs
+ isDuet := true;
+ Button[0].Text[0].Text := 'Duet Songs';
+ SetTextFound(CatSongs.SetFilter('', 3));
+ end else
+ begin
+ isDuet := false;
+ Button[0].Text[0].Text := '';
+ SetTextFound(CatSongs.SetFilter(Button[0].Text[0].Text, SelectType));
end;
end;
@@ -166,6 +194,7 @@ begin
Interaction := 0;
LastPlayed := 0;
+ isDuet := false;
end;
procedure TScreenSongJumpto.SetVisible(Value: Boolean);
@@ -186,6 +215,7 @@ begin
Button[0].Text[0].Text := '';
Text[0].Text := Theme.SongJumpto.NoSongsFound;
+ isDuet := false;
end;
//Select Input
diff --git a/Game/Code/UltraStar.bdsproj b/Game/Code/UltraStar.bdsproj
index 25bb9169..8cf38637 100644
--- a/Game/Code/UltraStar.bdsproj
+++ b/Game/Code/UltraStar.bdsproj
@@ -32,7 +32,7 @@
<Compiler Name="N">1</Compiler>
<Compiler Name="O">1</Compiler>
<Compiler Name="P">1</Compiler>
- <Compiler Name="Q">1</Compiler>
+ <Compiler Name="Q">0</Compiler>
<Compiler Name="R">0</Compiler>
<Compiler Name="S">0</Compiler>
<Compiler Name="T">0</Compiler>
@@ -171,6 +171,9 @@
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"></VersionInfoKeys>
</VersionInfoKeys>
+
+
+
<Excluded_Packages>
<Excluded_Packages Name="c:\program files (x86)\borland\bds\4.0\Bin\dclib100.bpl">Borland InterBase Express Components</Excluded_Packages>
<Excluded_Packages Name="c:\program files (x86)\borland\bds\4.0\Bin\dclIntraweb_80_100.bpl">Intraweb 8.0 Design Package for Borland Development Studio 2006</Excluded_Packages>
diff --git a/Game/Code/UltraStar.cfg b/Game/Code/UltraStar.cfg
index 04922655..e156555a 100644
--- a/Game/Code/UltraStar.cfg
+++ b/Game/Code/UltraStar.cfg
@@ -14,7 +14,7 @@
-$N+
-$O+
-$P+
--$Q+
+-$Q-
-$R-
-$S-
-$T-
diff --git a/Game/Code/UltraStar.dpr b/Game/Code/UltraStar.dpr
index fbef9c69..5e446624 100644
--- a/Game/Code/UltraStar.dpr
+++ b/Game/Code/UltraStar.dpr
@@ -5,6 +5,7 @@ program UltraStar;
{$R 'UltraStar.res' 'UltraStar.rc'}
uses
+ acinerella in 'lib\acinerella\acinerella.pas',
SDL in 'lib\JEDI-SDLv1.0\SDL\Pas\SDL.pas',
moduleloader in 'lib\JEDI-SDLv1.0\SDL\Pas\moduleloader.pas',
sdlutils in 'lib\JEDI-SDLv1.0\SDL\Pas\sdlutils.pas',
@@ -120,11 +121,10 @@ uses
Windows,
SysUtils,
- UVideo in 'Classes\UVideo.pas',
- acinerella in 'lib\acinerella\acinerella.pas';
+ UVideo in 'Classes\UVideo.pas';
const
- Version = 'UltraStar Deluxe v1.0.1a Challenge-Mod r7c5-10 2010-05-29';
+ Version = 'UltraStar Deluxe Challenge Duet beta 2010-06-04';
var
WndTitle: string;
@@ -315,17 +315,16 @@ begin
Log.LogBenchmark('Loading Particel System', 1);
// Joypad
- if (Ini.Joypad = 1) OR (Params.Joypad) then begin
+ {if (Ini.Joypad = 1) OR (Params.Joypad) then begin
Log.BenchmarkStart(1);
Log.LogStatus('Initialize Joystick', 'Initialization'); Joy := TJoy.Create;
Log.BenchmarkEnd(1);
Log.LogBenchmark('Initializing Joystick', 1);
- end;
+ end;}
Log.BenchmarkEnd(0);
Log.LogBenchmark('Loading Time', 0);
-
//------------------------------
//Start- Mainloop
//------------------------------
diff --git a/Game/Output/Languages/English.ini b/Game/Output/Languages/English.ini
index 951cb5e9..a3055ceb 100644
--- a/Game/Output/Languages/English.ini
+++ b/Game/Output/Languages/English.ini
@@ -529,6 +529,15 @@ ALT_J = Medley abspielen
K = gewählte Note als PreviewStart setzen
SHIFT_K = Zum PreviewStart springen
#-------------------------------------------------------#
+SEC_015 = Duett
+CTRL_SHIFT_D = 2. Spur/Sänger hinzufügen entfernen.
+SHIFT_UP = Zur 1. Spur/Sänger wechseln, wenn diese in der aktuellen Zeile Noten enthält.
+SHIFT_DOWN = Zur 2. Spur/Sänger wechseln, wenn diese in der aktuellen Zeile Noten enthält.
+CTRL_SHIFT_UP = Aktuelle Zeile der zweiten Spur in die erste Spur kopieren. Die erste Spur wird hierbei überschrieben.
+CTRL_SHIFT_DOWN = Aktuelle Zeile der ersten Spur in die zweite Spur kopieren. Die zweite Spur wird hierbei überschrieben.
+CTRL_SHIFT_ALT_UP = Aktuelle Zeile der zweiten Spur in die erste Spur verschieben. Die erste Spur wird hierbei überschrieben. Die zweite Spur wird gelöscht.
+CTRL_SHIFT_ALT_DOWN = Aktuelle Zeile der ersten Spur in die zweite Spur verschieben. Die zweite Spur wird hierbei überschrieben. Die erste Spur wird gelöscht.
+#-------------------------------------------------------#
SEC_020 = Grundsteuerung
P = MP3+Noteneinsatzklicks der gesamten Zeile abspielen
SHIFT_P = MIDI der gesamten Zeile abspielen
@@ -1224,7 +1233,7 @@ K = Experimentelle Karaoke-Funktion ein/ausschalten
#-------------------------------------------------------#
[ID_024]
Title = Liedauswahl
-Description = Hier werden alle vorhandenen Lieder für das normale Singen angezeigt. Scrollt durch die Liste oder verwendet die Suche, um euren Lieblingssong zu finden.
+Description = Hier werden alle vorhandenen Lieder für das normale Singen angezeigt. Scrollt durch die Liste oder verwendet die Suche, um euren Lieblingssong zu finden. Duett-Lieder sind über die Suche filterbar.
#-------------------------------------------------------#
SEC_001 = Allgemein
ESC = zurück
@@ -1413,6 +1422,7 @@ ESC = Suche Verlassen
RETURN = Suche Verlassen
PAGEUP = MP3-Lautstärke erhöhen
PAGEDOWN = MP3-Lautstärke reduzieren
+F1 = Nach Duett-Liedern filtern
#-------------------------------------------------------#
# ID_032: ScreenSongMenu #
diff --git a/Game/Output/Languages/German.ini b/Game/Output/Languages/German.ini
index 2d628f63..4f0c921b 100644
--- a/Game/Output/Languages/German.ini
+++ b/Game/Output/Languages/German.ini
@@ -339,7 +339,7 @@ PARTY_ROUNDM2_END=Ende
#### SreenSong in M2 mode ####
;new:
-PARTY_SONG_WHEREAMI_M2=Challange Songauswahl
+PARTY_SONG_WHEREAMI_M2=Challenge Songauswahl
#### ScreenTop ####
;delete old ones!
@@ -531,6 +531,15 @@ ALT_J = Medley abspielen
K = gewählte Note als PreviewStart setzen
SHIFT_K = Zum PreviewStart springen
#-------------------------------------------------------#
+SEC_015 = Duett
+CTRL_SHIFT_D = 2. Spur/Sänger hinzufügen entfernen.
+SHIFT_UP = Zur 1. Spur/Sänger wechseln, wenn diese in der aktuellen Zeile Noten enthält.
+SHIFT_DOWN = Zur 2. Spur/Sänger wechseln, wenn diese in der aktuellen Zeile Noten enthält.
+CTRL_SHIFT_UP = Aktuelle Zeile der zweiten Spur in die erste Spur kopieren. Die erste Spur wird hierbei überschrieben.
+CTRL_SHIFT_DOWN = Aktuelle Zeile der ersten Spur in die zweite Spur kopieren. Die zweite Spur wird hierbei überschrieben.
+CTRL_SHIFT_ALT_UP = Aktuelle Zeile der zweiten Spur in die erste Spur verschieben. Die erste Spur wird hierbei überschrieben. Die zweite Spur wird gelöscht.
+CTRL_SHIFT_ALT_DOWN = Aktuelle Zeile der ersten Spur in die zweite Spur verschieben. Die zweite Spur wird hierbei überschrieben. Die erste Spur wird gelöscht.
+#-------------------------------------------------------#
SEC_020 = Grundsteuerung
P = MP3+Noteneinsatzklicks der gesamten Zeile abspielen
SHIFT_P = MIDI der gesamten Zeile abspielen
@@ -1226,7 +1235,7 @@ K = Experimentelle Karaoke-Funktion ein/ausschalten
#-------------------------------------------------------#
[ID_024]
Title = Liedauswahl
-Description = Hier werden alle vorhandenen Lieder für das normale Singen angezeigt. Scrollt durch die Liste oder verwendet die Suche, um euren Lieblingssong zu finden.
+Description = Hier werden alle vorhandenen Lieder für das normale Singen angezeigt. Scrollt durch die Liste oder verwendet die Suche, um euren Lieblingssong zu finden. Duett-Lieder sind über die Suche filterbar.
#-------------------------------------------------------#
SEC_001 = Allgemein
ESC = zurück
@@ -1415,6 +1424,7 @@ ESC = Suche Verlassen
RETURN = Suche Verlassen
PAGEUP = MP3-Lautstärke erhöhen
PAGEDOWN = MP3-Lautstärke reduzieren
+F1 = Nach Duett-Liedern filtern
#-------------------------------------------------------#
# ID_032: ScreenSongMenu #
diff --git a/Game/Output/Languages/Italian.ini b/Game/Output/Languages/Italian.ini
index 3c69f48b..dd028e20 100644
--- a/Game/Output/Languages/Italian.ini
+++ b/Game/Output/Languages/Italian.ini
@@ -410,1022 +410,4 @@ ERROR_NO_SOUND_INPUT=No sound input devices found!
#### OptionsGame ####
;new
-SING_OPTIONS_GAME_SHUFFLETIME=Shuffle mode
-
-#-------------------------------------------------------#
-# Help System #
-#-------------------------------------------------------#
-
-[config]
-NumIDs = 33
-
-[Keymap]
-ESC=Esc
-CTRL=Strg
-ALT=Alt
-SHIFT=Shift
-BACKQUOTE=#
-BACKSPACE=Rück
-EQUALS=`
-MINUS=ß
-SLASH=-
-PERIOD=.
-RIGHT=Rechts
-LEFT=Links
-DOWN=Runter
-UP=Hoch
-SPACE=Leertaste
-KPPLUS=Key-Pad +
-KPMINUS=Key-Pad -
-DELETE=Del
-RETURN=Enter
-PRINT=Druck
-F1F12=F1..F12
-PAGEUP=Page Up
-PAGEDOWN=Page Down
-AZ=A..Z
-A=A
-B=B
-C=C
-D=D
-E=E
-F=F
-G=G
-H=H
-I=I
-J=J
-K=K
-L=L
-M=M
-N=N
-O=O
-P=P
-Q=Q
-R=R
-S=S
-T=T
-U=U
-V=V
-W=W
-X=X
-Y=Z
-Z=Y
-0=0
-1=1
-2=2
-3=3
-4=4
-5=5
-6=6
-7=7
-8=8
-9=9
-F1=F1
-F2=F2
-F3=F3
-F4=F4
-F5=F5
-F6=F6
-F7=F7
-F8=F8
-F9=F9
-F10=F10
-F11=F11
-F12=F12
-
-#### IDs must have the format: 'ID_###'
-
-#-------------------------------------------------------#
-# ID_001: UScreenEdit #
-#-------------------------------------------------------#
-[ID_001]
-Title = Song-Editor
-Description = Hier können Songs editiert werden.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-S = Song speichern (#RELATIVE:No)
-SHIFT_S = Song speichern (#RELATIVE:Yes)
-ESC = Editor verlassen / Im Textmodus: Bearbeitung abbrechen
-R = Song neu laden
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-PAGEUP = MP3-Lautstärke um 5% erhöhen
-PAGEDOWN = MP3-Lautstärke um 5% reduzieren
-#-------------------------------------------------------#
-SEC_010 = Medley/PreviewStart
-A = gewählte Note als Medley-Anfang setzen/löschen
-SHIFT_A = gewählte Note als Medley-Ende setzen/löschen
-J = Zum Medley-Anfang springen
-SHIFT_J = Zum Medley-Ende springen
-ALT_J = Medley abspielen
-K = gewählte Note als PreviewStart setzen
-SHIFT_K = Zum PreviewStart springen
-#-------------------------------------------------------#
-SEC_020 = Grundsteuerung
-P = MP3+Noteneinsatzklicks der gesamten Zeile abspielen
-SHIFT_P = MIDI der gesamten Zeile abspielen
-CTRL_SHIFT_P = MP3+Noteneinsatzklicks+MIDI der gesamten Zeile abspielen
-ALT_P = MP3+Noteneinsatzclicks ab aktueller Zeile bis zum Liedende abspielen
-SHIFT_ALT_P = MIDI ab aktueller Zeile bis zum Liedende abspielen
-CTRL_SHIFT_ALT_P = MP3+Noteneinsatzklicks+MIDI ab aktueller Zeile bis zum Liedende abspielen
-SPACE = MP3 der gewählten Note/Silbe abspielen
-SHIFT_SPACE = MIDI der gewählten Note/Silbe abspielen
-CTRL_SHIFT_SPACE = MP3+MIDI der gewählten Note/Silbe abspielen
-RIGHT = Zur nächsten Note/Silbe springen
-LEFT = Zur vorhergehenden Note/Silbe springen
-DOWN = Zur nächsten Liedzeile springen
-UP = Zur vorhergehenden Zeile springen
-#-------------------------------------------------------#
-SEC_030 = Noten
-G = Goldenen Ton setzen/löschen
-F = Freestyle Note setzten/löschen
-SHIFT_C = Überflüssige Leerzeichen in aktueller Zeile löschen
-CTRL_DELETE = Markierte Note/Silbe löschen
-CTRL_SLASH = Note teilen
-SHIFT_LEFT = Note nach links veschieben
-SHIFT_RIGHT = Note nach rechts veschieben
-CTRL_LEFT = Notenanfang nach links verschieben (Note verlängern)
-CTRL_RIGHT = Notenanfang nach rechts verschieben (Note verkürzen)
-ALT_LEFT = Notenende nach links verschieben (Note verkürzen)
-ALT_RIGHT = Notenende nach rechts verschieben (Note verlängern)
-BACKQUOTE = Note verlängern (wie [ALT]+[Rechts])
-CTRL_ALT_SHIFT_LEFT = Alle Noten ab der gewählten Note bis zum Liedende nach links verschieben
-CTRL_ALT_SHIFT_RIGHT = Alle Noten ab der gewählten Note bis zum Liedende nach rechts verschieben
-#-------------------------------------------------------#
-SEC_040 = Tonhöhe
-KPPLUS = Tonhöhe aller Noten um einen Halbtonschritt erhöhen
-KPMINUS = Tonhöhe aller Noten um einen Halbtonschritt verringern
-CTRL_UP = Tonhöhe der markierten Note um einen Halbtonschritt erhöhen
-CTRL_DOWN = Tonhöhe der markierten Note um einen Halbtonschritt verringern
-SHIFT_KPMINUS = Tonhöhe aller Noten um eine Oktave (12 Halbtonschritte) verringern
-SHIFT_KPPLUS = Tonhöhe aller Noten um eine Oktave (12 Halbtonschritte) erhöhen
-#-------------------------------------------------------#
-SEC_050 = Songtext
-F4 = Textbearbeitungs Modus starten (bzw. ohne Speichern beenden)
-RETURN = Textmodus beenden und Änderungen speichern
-BACKSPACE = Im Textmodus: Zeichen löschen
-C = Anfangsbuchstaben der Zeile groß schreiben
-PERIOD = Den ausgewählten Text dem nächsten Ton zuordnen
-T = Zeiten für Zeilenwechsel korrigieren
-SLASH = Zeilenumbruch vor der markierten Note einfügen
-SHIFT_SLASH = Aktuelle Zeile mit der darauffolgenden zusammenführen
-#-------------------------------------------------------#
-SEC_060 = GAP (Zeitverzögerung)
-0 = GAP um 10ms erhöhen
-SHIFT_0 = GAP um 1000ms erhöhen
-9 = GAP um 10ms reduzieren
-SHIFT_9 = GAP um 1000ms reduzieren
-#-------------------------------------------------------#
-SEC_070 = BPM (Beats per minute)
-CTRL_EQUALS = BPM um 0,01 erhöhen
-CTRL_MINUS = BPM um 0,01 reduzieren
-EQUALS = BPM um 0,05 erhöhen
-MINUS = BPM um 0,05 reduzieren
-SHIFT_EQUALS = BPM um 1,00 erhöhen
-SHIFT_MINUS = BPM um 1,00 reduzieren
-SHIFT_M = BMP und Notenzeitwerte verdoppeln
-SHIFT_D = BMP und Notenzeitwerte halbieren
-F5 = BMP Bearbeitungsmodus aktivieren
-#-------------------------------------------------------#
-SEC_080 = Video
-V = Video ab der aktuellen Zeile abspielen
-SHIFT_V = Video mit Klicks ab der aktuellen Zeile abspielen
-8 = VideoGap um 10ms erhöhen
-SHIFT_8 = VideoGap um 100ms erhöhen
-CTRL_8 = VideoGap um 1000ms erhöhen
-7 = VideoGap um 10ms reduzieren
-SHIFT_7 = VideoGap um 100ms reduzieren
-CTRL_7 = VideoGap um 1000ms reduzieren
-#-------------------------------------------------------#
-SEC_090 = Sonstiges
-CTRL_C = Zeile kopieren
-CTRL_V = Zeile einfügen
-CTRL_SHIFT_V = unbekannt
-CTRL_SHIFT_4 = unbekannt
-CTRL_SHIFT_ALT_4 = unbekannt
-CTRL_SHIFT_5 = unbekannt
-CTRL_SHIFT_ALT_5 = unbekannt
-
-#-------------------------------------------------------#
-# ID_002: UScreenLevel #
-#-------------------------------------------------------#
-[ID_002]
-Title = Level auswählen
-Description = Hier kann der Schwierigkeitsgrad eingestellt werden. Die Schwierigkeitsgrade beeinflussen die notwendige Treffgenauigkeit der Notenhöhen.
-#-------------------------------------------------------#
-SUB_010=Leicht
-ENT_011=Erlaubt eine Abweichung von bis zu zwei Halbtönen in beide Richtungen, um Punkte für die Note zu bekommen.
-#-------------------------------------------------------#
-SUB_020=Mittel
-ENT_021=Erlaubt eine Abweichung von bis zu einem Halbton in beide Richtungen, um Punkte für die Note zu bekommen.
-#-------------------------------------------------------#
-SUB_030=Schwierig
-ENT_031=Die Note muss exakt getroffen werden, um Punkte für die Note zu bekommen.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-BACKSPACE = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_010 = Levelauswahl
-LEFT = Linksherum durch die Auswahl gehen
-UP = Linksherum durch die Auswahl gehen
-RIGHT = Rechtsherum durch die Auswahl gehen
-DOWN = Rechtsherum durch die Auswahl gehen
-RETURN = Level setzen und weiter zur Songauswahl
-
-#-------------------------------------------------------#
-# ID_003: UScreenMain #
-#-------------------------------------------------------#
-[ID_003]
-Title = Hauptbildschirm
-Description = Dies ist das UltraStar Deluxe Startmenü.
-#-------------------------------------------------------#
-SUB_010=Singen
-ENT_011=Freie Wahl von Liedern und Spielern.
-ENT_012=Man kann hier die Lieder normal singen oder den Medley-Modus starten.
-#-------------------------------------------------------#
-SUB_020=Party
-ENT_021=Hier hat man die Wahl zwischen zwei unterschiedlichen Party-Modi.
-ENT_022=Classic: Spiele mit bis zu 12 Spielern in 3 Teams. Verschiedene Party-Plugins sorgen für Abwechslung.
-ENT_023=Challenge: Spiele mit bis zu 9 Spielern eine Art Meisterschaft bei der, ähnlich wie beim Fußball, die Rundenergebnisse tabellarisch zusammengefasst werden.
-#-------------------------------------------------------#
-SUB_030=Tools
-ENT_031=Über diesen Menüpunkt können Spielstatistiken, der interne Editor und das Optionsmenü aufgerufen werden.
-ENT_032=Statistiken: beinhalten Informationen über Highscores, beste Sänger, beliebteste Songs und Bands.
-ENT_033=Editor: hiermit lassen sich vorhandene MIDI-Dateien in UltraStar Lieder konvertieren.
-ENT_034=Optionen: hier lassen sich viele Einstellungen für das Verhalten von UltraStar Deluxe vornehmen.
-#-------------------------------------------------------#
-SUB_040=Beenden
-ENT_041=Hiermit beendet man UltraStar Deluxe nach Bestätigen einer Sicherheitsabfrage.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-BACKSPACE = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_010 = Navigation
-LEFT = Auswahl links
-UP = Auswahl hoch
-RIGHT = Auswahl rechts
-DOWN = Auswahl runter
-RETURN = aktuelle Auswahl bestätigen
-#-------------------------------------------------------#
-SEC_020 = Tastenkürzel
-M = Party --> Classic: startet den Classic Party Modus
-SHIFT_M = Party --> Challenge: startet den Challenge Modus
-S = Tools --> Statistiken: zeigt die Statistiken direkt an
-E = Tools --> Editor: startet den Editor
-ALT_C = Credits aufrufen
-
-#-------------------------------------------------------#
-# ID_004: UScreenName #
-#-------------------------------------------------------#
-[ID_004]
-Title = Spielernamen eingeben
-Description = Hier können die Spielernamen eingegeben werden. Die Anzahl der Spieler richtet sich nach der Einstellung unter Optionen --> Spiel --> Spieler.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_010 = Navigation
-LEFT = Auswahl links
-UP = Auswahl hoch
-RIGHT = Auswahl rechts
-DOWN = Auswahl runter
-RETURN = alle Spielernamen bestätigen und weiter
-#-------------------------------------------------------#
-SEC_020 = Namen ändern
-BACKSPACE = letzten Buchstaben löschen
-ALT_F1F12 = aktuellen Namen als Template 1..12 speichern
-F1F12 = Template 1..12 in gewähltes Namensfeld übernehmen
-
-#-------------------------------------------------------#
-# ID_006: UScreenOptions #
-#-------------------------------------------------------#
-[ID_006]
-Title = Hauptmenü Optionen
-Description = Von hier aus gelangt man zu allen Einstellungen, die das Aussehen und Verhalten von UltraStar Deluxe beeinflussen.
-#-------------------------------------------------------#
-SUB_010=Spiel
-ENT_011=Einstellungen zur Spieleranzahl, zur Standardschwierigkeitsstufe, zur Spielsprache, zur Anzeige von Kategorien, zur Liedsortierung und zum Debugmodus.
-#-------------------------------------------------------#
-SUB_020=Grafik
-ENT_021=Einstellungen zur Spielauflösung, zum Vollbildmodus, zur Farbtiefe, zur Anzeige eines Oszilloskop, zur Videogröße und zur Videovorschau.
-#-------------------------------------------------------#
-SUB_030=Sound
-ENT_031=Einstellungen zur Mikrofonverstärkung, zum Click-Assistenten, zu den Beat-Clicks, zur Rauschunterdrückung, zur Vorschau-Lautstärke und zum Vorschau-Fading.
-#-------------------------------------------------------#
-SUB_040=Lyrics
-ENT_041=Einstellungen zur Schriftart, zum Animationseffekt und zur Solmisation des Liedtextes
-#-------------------------------------------------------#
-SUB_050=Themes
-ENT_051=Einstellungen zum Theme, zum Skin und zur Farbe
-#-------------------------------------------------------#
-SUB_060=Aufnahme
-ENT_061=Einstellungen zu verwendeten Soundkarten, zu Audioeingängen und zu Kanalbelegungen
-#-------------------------------------------------------#
-SUB_070=Erweitert
-ENT_071=Einstellungen zum Bildschirm-Fade, zu den Singeffekten, zum Phrasenbonus, etc.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-BACKSPACE = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_010 = Navigation
-LEFT = Auswahl links
-UP = Auswahl hoch
-RIGHT = Auswahl rechts
-DOWN = Auswahl runter
-RETURN = aktuelle Auswahl bestätigen
-
-#-------------------------------------------------------#
-# ID_007: UScreenOptionsAdvanced #
-#-------------------------------------------------------#
-[ID_007]
-Title = Erweiterte Optionen
-Description = Hier findet man die erweiterten Optionen von UltraStar Deluxe.
-#-------------------------------------------------------#
-SUB_010=Bildschirm-Fade
-ENT_011=Schaltet die Überblendung zwischen den einzelnen Screens an oder aus.
-#-------------------------------------------------------#
-SUB_020=Singeffekte
-ENT_021=Schaltet Animationen bei Goldenen Noten und Ähnliches an oder aus.
-#-------------------------------------------------------#
-SUB_030=Phrasenbonus
-ENT_031=Legt fest, an welcher Stelle der Phrasenbonus angezeigt wird.
-#-------------------------------------------------------#
-SUB_040=nach Song-Wahl
-ENT_041=Legt fest, ob nach der Songauswahl direkt gesungen wird oder erst die Spieler festgelegt werden.
-#-------------------------------------------------------#
-SUB_050=Sicherheitsabfrage
-ENT_051=Legt fest, ob beim Verlassen von Ultrastar Deluxe eine Sicherheitsabfrage stattfindet.
-#-------------------------------------------------------#
-SUB_060=Auto Party-Menü
-ENT_061=Legt fest, ob das Party-Menü zur Jokerauswahl bei jedem neuen Lied automatisch angezeigt werden soll.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-BACKSPACE = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_010 = Navigation
-LEFT = Auswahlmöglichkeiten der gewählten Einstellung nach links durchgehen
-UP = Vorherige Einstellungsoption wählen
-RIGHT = Auswahlmöglichkeiten der gewählten Einstellung nach rechts durchgehen
-DOWN = Nächste Einstellungsoption wählen
-RETURN = Wenn aktuelle Auswahl auf "zurück": Zum Optionsmenü zurückkehren
-
-#-------------------------------------------------------#
-# ID_008: UScreenOptionsGame #
-#-------------------------------------------------------#
-[ID_008]
-Title = Spiel-Optionen
-Description = Hier findet man die grundlegenden Spiel-Optionen von UltraStar Deluxe.
-#-------------------------------------------------------#
-SUB_010=Spieler
-ENT_011=Legt die Anzahl der Spieler fest. Auf einem Bildschirm können maximal 3 Spieler gleichzeitig singen, auf zwei Bildschirmen sind es 4 bzw. 6 Spieler.
-#-------------------------------------------------------#
-SUB_020=Schwierigkeit
-ENT_021=Legt die standardmäßig eingestellte Schwierigkeitsstufe fest.
-#-------------------------------------------------------#
-SUB_030=Sprache
-ENT_031=Legt die Spielsprache fest.
-#-------------------------------------------------------#
-SUB_040=Ordner
-ENT_041=Legt fest, ob die Lieder gemäß der Sortierung in einzelnen Ordnern/Kategorien angezeigt werden oder nicht (Neustart erforderlich).
-#-------------------------------------------------------#
-SUB_050=Sortierung
-ENT_051=Legt fest, nach welchen Kriterium die Lieder sortiert werden.
-#-------------------------------------------------------#
-SUB_060=Debug
-ENT_061=Legt fest, ob Debug-Informationen wie Bildwiederholfrequenz angezeigt werden.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-BACKSPACE = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_010 = Navigation
-LEFT = Auswahlliste nach links durchgehen
-UP = Option hoch
-RIGHT = Auswahlliste nach rechts durchgehen
-DOWN = Option runter
-RETURN = Wenn aktuelle Auswahl auf "zurück": Zum Optionsmenü zurückkehren
-
-#-------------------------------------------------------#
-# ID_009: UScreenOptionsGraphics #
-#-------------------------------------------------------#
-[ID_009]
-Title = Grafik-Optionen
-Description = Hier findet man die Grafik-Optionen von UltraStar Deluxe.
-#-------------------------------------------------------#
-SUB_010=Auflösung
-ENT_011=Legt die Auflösung des Spiels fest. Das Spiel wird in jedem Fall auf eine Auflösung von 800x600 gerendet und anschließend nur noch auf die gewählte Auflösung skaliert.
-#-------------------------------------------------------#
-SUB_020=Vollbild
-ENT_021=Legt fest, ob das Spiel im Vollbild- oder im Fenstermodus angezeigt werden soll (Neustart erforderlich).
-#-------------------------------------------------------#
-SUB_030=Farbtiefe
-ENT_031=Legt die Farbtiefe des Spiels fest.
-#-------------------------------------------------------#
-SUB_040=Oszilloskop
-ENT_041=Legt fest, ob beim Singen ein Oszilloskop für den Mikrofonausschlag angezeigt wird.
-#-------------------------------------------------------#
-SUB_050=Videogröße
-ENT_051=Legt fest, ob und in welcher Größe Videos angezeigt werden.
-#-------------------------------------------------------#
-SUB_060=Videovorschau
-ENT_061=Legt fest, ob bei der Liedauswahl eine Videovorschau angezeigt wird.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-BACKSPACE = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_010 = Navigation
-LEFT = Auswahlliste nach links durchgehen
-UP = Option hoch
-RIGHT = Auswahlliste nach rechts durchgehen
-DOWN = Option runter
-RETURN = Wenn aktuelle Auswahl auf "zurück": Zum Optionsmenü zurückkehren
-
-#-------------------------------------------------------#
-# ID_010: UScreenOptionsLyrics #
-#-------------------------------------------------------#
-[ID_010]
-Title = Liedtext-Optionen
-Description = Hier findet man die Liedtext-Optionen von UltraStar Deluxe.
-#-------------------------------------------------------#
-SUB_010=Schriftart
-ENT_011=Legt die Schriftart des Liedtextes fest.
-#-------------------------------------------------------#
-SUB_020=Effekt
-ENT_021=Legt den Animationseffekt für die zu singende Silbe fest.
-#-------------------------------------------------------#
-SUB_030=Solmisation
-ENT_031=Legt fest, ob und wenn ja, welche Solmisation verwendet werden soll. Dabei wird der Liedtext durch die entsprechenden Tonsilben ersetzt.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-BACKSPACE = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_010 = Navigation
-LEFT = Auswahlliste nach links durchgehen
-UP = Option hoch
-RIGHT = Auswahlliste nach rechts durchgehen
-DOWN = Option runter
-RETURN = Wenn aktuelle Auswahl auf "zurück": Zum Optionsmenü zurückkehren
-
-#-------------------------------------------------------#
-# ID_011: UScreenOptionsRecord #
-#-------------------------------------------------------#
-[ID_011]
-Title = Aufnahme Optionen
-Description = Hier findet man die Aufnahme- und Mikrofon-Optionen von UltraStar Deluxe.
-#-------------------------------------------------------#
-SUB_010=Soundkarte
-ENT_011=Legt die einzustellende Soundkarte fest.
-#-------------------------------------------------------#
-SUB_020=Eingang
-ENT_021=Legt den verwendeten Eingang der Soundkarte fest.
-#-------------------------------------------------------#
-SUB_030=Linker Kanal
-ENT_031=Legt fest, welcher Spielernummer der linke Aufnahmekanal zugeordnet ist.
-#-------------------------------------------------------#
-SUB_040=Rechter Kanals
-ENT_041=Legt fest, welcher Spielernummer der rechte Aufnahmekanal zugeordnet ist.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-BACKSPACE = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_010 = Navigation
-LEFT = Auswahlliste nach links durchgehen
-UP = Option hoch
-RIGHT = Auswahlliste nach rechts durchgehen
-DOWN = Option runter
-RETURN = Wenn aktuelle Auswahl auf "zurück": Zum Optionsmenü zurückkehren
-
-#-------------------------------------------------------#
-# ID_012: UScreenOptionsSound #
-#-------------------------------------------------------#
-[ID_012]
-Title = Sound Optionen
-Description = Hier findet man die Sound-Optionen von UltraStar Deluxe.
-#-------------------------------------------------------#
-SUB_010=Mic-Anhebung
-ENT_011=Legt die Mikrofonverstärkung innerhalb von UltraStar Deluxe fest.
-#-------------------------------------------------------#
-SUB_020=Click-Assistent
-ENT_021=Legt fest, ob mit jedem Noteneinsatz ein Klick abgespielt wird.
-#-------------------------------------------------------#
-SUB_030=Beat-Click
-ENT_031=Legt fest, ob mit jedem Vierteltakt ein Klick abgespielt wird.
-#-------------------------------------------------------#
-SUB_040=Rauschunterdrückung
-ENT_041=Legt die Rauschumnterdrückung beim Mikrofonsignal fest.
-#-------------------------------------------------------#
-SUB_050=Vorschau-Lautstärke
-ENT_051=Legt die Lautstärke bei der Liedvorschau in der Liedauswahl fest.
-#-------------------------------------------------------#
-SUB_060=Vorschau-Fading
-ENT_061=Legt die Wartezeit bis zum Abspielen der Liedvorschau fest.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-BACKSPACE = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_010 = Navigation
-LEFT = Auswahlliste nach links durchgehen
-UP = Option hoch
-RIGHT = Auswahlliste nach rechts durchgehen
-DOWN = Option runter
-RETURN = Wenn aktuelle Auswahl auf "zurück": Zum Optionsmenü zurückkehren
-
-#-------------------------------------------------------#
-# ID_013: UScreenOptionsThemes #
-#-------------------------------------------------------#
-[ID_013]
-Title = Themes Optionen
-Description = Hier findet man die Theme- und Skin-Optionen von UltraStar Deluxe.
-#-------------------------------------------------------#
-SUB_010=Theme
-ENT_011=Legt das Spiel-Theme und damit die Anordnung der einzelnen Elemente fest.
-#-------------------------------------------------------#
-SUB_020=Skin
-ENT_021=Legt das Skin für das gewählte Theme fest.
-#-------------------------------------------------------#
-SUB_030=Farbe
-ENT_031=Legt die Hauptfarbe für das gewählte Theme und Skin fest.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-BACKSPACE = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_010 = Navigation
-LEFT = Auswahlliste nach links durchgehen
-UP = Option hoch
-RIGHT = Auswahlliste nach rechts durchgehen
-DOWN = Option runter
-RETURN = Wenn aktuelle Auswahl auf "zurück": Zum Optionsmenü zurückkehren
-
-#-------------------------------------------------------#
-# ID_014: UScreenPartyNewRound #
-#-------------------------------------------------------#
-[ID_014]
-Title = Party Übersicht
-Description = Hier wird die Übersicht über den aktuellen Stand des Party-Modus angezeigt. Neben dem aktuellen Punktestand wird eine Liste über alle gespielten und noch zu spielenden Runden mit den zugehörigen Plugins sowie die folgende Runde und deren Spieler und Plugin angezeigt.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = Partymodus beenden (mit Sicherheitsabfrage)
-BACKSPACE = Partymodus beenden (mit Sicherheitsabfrage)
-RETURN = Nächste Runde starten
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-
-#-------------------------------------------------------#
-# ID_015: UScreenPartyOptions #
-#-------------------------------------------------------#
-[ID_015]
-Title = Optionen Party-Modus
-Description = Hier könnten die Optionen für den Party-Modus festgelegt werden.
-#-------------------------------------------------------#
-SUB_010=Schwierigkeit
-ENT_011=Legt das Schwierigkeitslevel für alle Runden des Party-Modus' fest.
-#-------------------------------------------------------#
-SUB_020=Playlist-Modus
-ENT_021=Legt fest, welche Liederauswahl für den Party-Modus zur Verfügung stehen. Werden Ordner oder Playlist gewählt, so wird im nächsten Punkt festgelegt, welcher Ordner bzw. welche Playlist verwendet wird.
-#-------------------------------------------------------#
-SUB_030=Runden
-ENT_031=Legt die Anzahl der zu spielenden Runden fest.
-#-------------------------------------------------------#
-SUB_040=Teams
-ENT_041=Legt die Anzahl der Teams fest.
-#-------------------------------------------------------#
-SUB_050=Spieler Team 1
-ENT_051=Legt die Anzahl der Spieler in Team 1 fest.
-#-------------------------------------------------------#
-SUB_060=Spieler Team 2
-ENT_061=Legt die Anzahl der Spieler in Team 2 fest.
-#-------------------------------------------------------#
-SUB_060=Spieler Team 3
-ENT_061=Legt die Anzahl der Spieler in Team 3 fest (nur, falls 3 Teams gewählt wurden).
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-BACKSPACE = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_010 = Navigation
-LEFT = Auswahlliste nach links durchgehen
-UP = Option hoch
-RIGHT = Auswahlliste nach rechts durchgehen
-DOWN = Option runter
-RETURN = weiter
-
-#-------------------------------------------------------#
-# ID_016: UScreenPartyPlayer #
-#-------------------------------------------------------#
-[ID_016]
-Title = Spielernameneingabe Party-Modus
-Description = Hier können die Team- und Spielernamen eingegeben werden.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_010 = Navigation
-LEFT = Auswahl links
-UP = Auswahl hoch
-RIGHT = Auswahl rechts
-DOWN = Auswahl runter
-RETURN = alle Spielernamen bestätigen und weiter
-#-------------------------------------------------------#
-SEC_020 = Namen ändern
-BACKSPACE = letzten Buchstaben löschen
-ALT_F1F12 = aktuellen Namen als Template 1..12 speichern
-F1F12 = Template 1..12 in gewähltes Namensfeld übernehmen
-
-#-------------------------------------------------------#
-# ID_017: UScreenPartyScore #
-#-------------------------------------------------------#
-[ID_017]
-Title = Ergebnis Party-Modus
-Description = Hier wird das Ergebnis und der Sieger der letzten Party-Runde angezeigt.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = weiter
-BACKSPACE = weiter
-RETURN = weiter
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-
-#-------------------------------------------------------#
-# ID_010: UScreenPartyWin #
-#-------------------------------------------------------#
-[ID_018]
-Title = Sieger Party-Modus
-Description = Hier wird der endgültige Sieger nach allen gespielten Party-Runden angezeigt.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-
-#-------------------------------------------------------#
-# ID_019: UScreenPartyNewRoundM2 #
-#-------------------------------------------------------#
-[ID_019]
-Title = Übersicht Challenge-Modus
-Description = Hier wird die Übersicht über den aktuellen Stand des Challenge-Modus' angezeigt. Es wird die Punktetabelle und die Begegnungstabelle sowie folgende Runde mit Spielern angezeigt.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-
-#-------------------------------------------------------#
-# ID_020: UScreenPartyOptionsM2 #
-#-------------------------------------------------------#
-[ID_020]
-Title = Optionen Challenge-Modus
-Description = Hier könnten die Optionen für den Challenge-Modus festgelegt werden.
-#-------------------------------------------------------#
-SUB_010=Schwierigkeit
-ENT_011=Legt das Schwierigkeitslevel für alle Runden des Challenge-Modus' fest.
-#-------------------------------------------------------#
-SUB_020=Playlist-Modus
-ENT_021=Legt fest, welche Liederauswahl für den Challenge-Modus zur Verfügung stehen. Werden Ordner oder Playlist gewählt, so wird im nächsten Punkt festgelegt, welcher Ordner bzw. welche Playlist verwendet wird.
-#-------------------------------------------------------#
-SUB_030=Spieler
-ENT_031=Legt die Anzahl der Spieler für den Challenge-Modus fest.
-#-------------------------------------------------------#
-SUB_040=Runden
-ENT_041=Legt die Anzahl der zu spielenden Runden fest.
-#-------------------------------------------------------#
-SUB_050=Plugins zulassen
-ENT_051=Legt fest, ob Party-Plugins verwendet werden.
-#-------------------------------------------------------#
-SUB_060=Handicap Modus
-ENT_061=Legt fest, ob schlechte Spieler bevorzugt und gute Spieler bei der Punktevergabe im Sinne der Chancenangleichung benachteiligt werden.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-
-#-------------------------------------------------------#
-# ID_021: UScreenPartyPlayerM2 #
-#-------------------------------------------------------#
-[ID_021]
-Title = Spielernamen Challenge-Modus
-Description = Hier können die Team- und Spielernamen eingegeben werden.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_010 = Navigation
-LEFT = Auswahl links
-UP = Auswahl hoch
-RIGHT = Auswahl rechts
-DOWN = Auswahl runter
-RETURN = alle Spielernamen bestätigen und weiter
-#-------------------------------------------------------#
-SEC_020 = Namen ändern
-BACKSPACE = letzten Buchstaben löschen
-ALT_F1F12 = aktuellen Namen als Template 1..12 speichern
-F1F12 = Template 1..12 in gewähltes Namensfeld übernehmen
-
-#-------------------------------------------------------#
-# ID_022: UScreenScore #
-#-------------------------------------------------------#
-[ID_022]
-Title = Ergebnisse
-Description = Hier werden die Punktzahlen der einzelnen Spieler nach dem Singen angezeigt. Dabei wird nicht nur die Gesamtpunktzahl, sondern ebenfalls der erreichte Phrasenbonus sowie die Bonuspunkte durch Goldene Noten angezeigt.
-#-------------------------------------------------------#
-SUB_010=Mögliche Gesangsbewertungen
-ENT_011=Anti-Talent (bis 2000 Punkte)
-ENT_012=Amateur (2010 bis 4000 Punkte)
-ENT_013=Möchtegern (4010 bis 6000 Punkte)
-ENT_014=Sternchen (6010 bis 8000 Punkte)
-ENT_015=Hit-Künstler (8010 bis 9000 Punkte)
-ENT_016=Superstar (9010 bis 9800 Punkte)
-ENT_017=UltraStar (9810 bis 10000 Punkte)
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-RETURN = zurück
-ESC = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-PAGEUP = MP3-Lautstärke erhöhen
-PAGEDOWN = MP3-Lautstärke reduzieren
-
-#-------------------------------------------------------#
-# ID_023: UScreenSing #
-#-------------------------------------------------------#
-[ID_023]
-Title = Singbildschirm
-Description = Hier wird das ausgewählte Lied abgespielt. Dabei wird der Text des Liedes zeilenweise mit den zugehörigen Noten angezeigt.
-#-------------------------------------------------------#
-SUB_010=Punktevergabe
-ENT_011=Die maximal erreichbare Punktzahl inklusive aller Bonuspunkte ist für jedes Lied normiert auf 10000 Punkte.
-ENT_012=Jede Note, die richtig gesungen wird (in Abhängigkeit der eingestellten Schwierigkeitsstufe), gibt Punkte. Je länger die Note richtig gesungen wurde, desto mehr Punkte bekommt der Spieler.
-#-------------------------------------------------------#
-SUB_020=Phrasenbonus
-ENT_021=Zusätzlich erhält man für jede Zeile, die fehlerfrei gesungen wurden, einen Phrasenbonus.
-#-------------------------------------------------------#
-SUB_030=Goldene Noten
-ENT_031=Goldene Noten sind meist etwas schwerer zu treffen und geben daher ebenfalls Bonuspunkte.
-#-------------------------------------------------------#
-SUB_040=Freestyle Noten
-ENT_041=Freestyle Noten werden oft für gesprochene oder kaum bewertbare Passagen verwendet. Es werden hierfür keine Tonhöhen angezeigt, der Liedtext wird kursiv dargestellt und diese Teile geben keine Punkte. Hier darf nach Belieben mitgesprochen oder mitgegrölt werden!
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-BACKSPACE = zurück
-P = Pause / Weiter
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-PAGEUP = MP3-Lautstärke erhöhen
-PAGEDOWN = MP3-Lautstärke reduzieren
-K = Experimentelle Karaoke-Funktion ein/ausschalten
-#-------------------------------------------------------#
-# ID_024: UScreenSong #
-#-------------------------------------------------------#
-[ID_024]
-Title = Liedauswahl
-Description = Hier werden alle vorhandenen Lieder für das normale Singen angezeigt. Scrollt durch die Liste oder verwendet die Suche, um euren Lieblingssong zu finden.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-BACKSPACE = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-V = Videovorschau vergrößern/verkleinern (falls vorhanden)
-A = Bildseitenverhältnis umschalten (nur im Vollbildmodus, wird gespeichert)
-PAGEUP = MP3-Lautstärke erhöhen
-PAGEDOWN = MP3-Lautstärke reduzieren
-K = Experimentelle Karaoke-Funktion ein/ausschalten
-#-------------------------------------------------------#
-SEC_010 = Songauswahl
-LEFT = Linksherum durch die Liedauswahl blättern
-RIGHT = Rechtsherum durch die Liedauswahl blättern
-UP = Zur vorherigen Kategorie wechseln (falls Kategorien aktiviert)
-DOWN = Zur nächsten Kategorie wechseln (falls Kategorien aktiviert)
-RETURN = Lied singen
-ALT_AZ = Zu Interpreten mit gewähltem Anfangsbuchstaben springen
-SHIFT_ALT_AZ = Zu Titeln mit gewähltem Anfangsbuchstaben springen
-M = Menü aufrufen (Singen / Spieler wechseln / Song zu Playlist hinzufügen / Editor)
-J = Suchmenü aufrufen
-P = Playliste öffnen
-R = Zufällig ein neues Lied anzeigen
-E = Editor mit ausgewähltem Lied starten
-#-------------------------------------------------------#
-SEC_020 = Medley
-S = Aktuelles Lied im Medley-Modus starten (falls Medley-Tags gesetzt)
-SHIFT_S = Aktuelles Lied im Medley-Modus starten (falls Medley-Tags gesetzt oder berechnet)
-D = Ein Medley mit bis zu 5 zufällig gewählten Liedern (mit gesetzten Medley-Tags) aus der aktuellen Kategorie starten
-SHIFT_D = Ein Medley mit bis zu 5 zufällig gewählten Liedern (mit gesetzten oder berechneten Medley-Tags) aus der aktuellen Kategorie starten
-F = Ein Medley mit bis zu 99 selbst gewählten Liedern (mit gesetzten Medley-Tags) zusammenstellen
-SHIFT_F = Letztes hinzugefügte Lied von der Medley-Playlist entfernen bzw. Medley-Modus deaktivieren, wenn die Playliste leer ist
-
-#-------------------------------------------------------#
-# ID_025: UScreenSong Party #
-#-------------------------------------------------------#
-[ID_025]
-Title = Liedauswahl Party-Modus
-Description = Hier werden alle vorhandenen Lieder im klassischen Party-Modus angezeigt.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = Party-Modus beenden (Menü aufrufen, falls geöffnet)
-BACKSPACE = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-V = Videovorschau vergrößern/verkleinern (falls vorhanden)
-A = Bildseitenverhältnis umschalten (nur im Vollbildmodus, wird gespeichert)
-PAGEUP = MP3-Lautstärke erhöhen
-PAGEDOWN = MP3-Lautstärke reduzieren
-K = Experimentelle Karaoke-Funktion ein/ausschalten
-#-------------------------------------------------------#
-SEC_010 = Songauswahl
-RETURN = Menü aufrufen (Singen / Joker)
-ESC = Geöffnetes Song-Menü schließen
-M = Menü aufrufen (Singen / Joker)
-1 = per Zufall ein neues Lied aussuchen (Team 1 verwendet einen Joker)
-2 = per Zufall ein neues Lied aussuchen (Team 2 verwendet einen Joker)
-3 = per Zufall ein neues Lied aussuchen (Team 3 verwendet einen Joker; falls 3 Teams vorhanden)
-ALT_1 = per Zufall ein neues Lied aussuchen (kein Team verwendet einen Joker)
-ALT_2 = per Zufall ein neues Lied aussuchen (kein Team verwendet einen Joker)
-ALT_3 = per Zufall ein neues Lied aussuchen (kein Team verwendet einen Joker; falls 3 Teams vorhanden)
-
-#-------------------------------------------------------#
-# ID_026: UScreenSong Challenge #
-#-------------------------------------------------------#
-[ID_026]
-Title = Liedauswahl Challenge-Modus
-Description = Hier werden alle vorhandenen Lieder im Challenge-Modus angezeigt. Die Liedauswahl liegt bei Spieler P1.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = Party-Modus beenden (Menü aufrufen, falls geöffnet)
-BACKSPACE = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-V = Videovorschau vergrößern/verkleinern (falls vorhanden)
-A = Bildseitenverhältnis umschalten (nur im Vollbildmodus, wird gespeichert)
-PAGEUP = MP3-Lautstärke erhöhen
-PAGEDOWN = MP3-Lautstärke reduzieren
-K = Experimentelle Karaoke-Funktion ein/ausschalten
-#-------------------------------------------------------#
-SEC_010 = Songauswahl
-RETURN = Aktuelles Lied singen
-R = per Zufall ein neues Lied aussuchen
-J = per Zufall ein neues Lied aussuchen
-
-#-------------------------------------------------------#
-# ID_027: UScreenStatDetail #
-#-------------------------------------------------------#
-[ID_027]
-Title = Detaillierte Statistiken
-Description = Hier werden themenbezogen detailliertere Statistiken angezeigt.
-#-------------------------------------------------------#
-SUB_010=Nächste Seite
-ENT_011=Blättert zur nächsten Statistikseite.
-#-------------------------------------------------------#
-SUB_020=Vorherige Seite
-ENT_021=Blättert zur vorherigen Statistikseite.
-#-------------------------------------------------------#
-SUB_030=Umkehren
-ENT_031=Kehrt die Sortierreihenfolge um.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_002 = Navigation
-LEFT = Zum vorherigen Punkt wechseln.
-RIGHT = Zur nächsten Punkt wechseln.
-UP = Zur vorherigen Punkt wechseln.
-DOWN = Zur nächsten Punkt wechseln.
-
-#-------------------------------------------------------#
-# ID_028: UScreenStatMain #
-#-------------------------------------------------------#
-[ID_028]
-Title = Hauptbildschirm Statistiken
-Description = Hier werden die wichtigsten Statistiken über die Lieder, Spieler und Punktzahlen auf einen Blick angezeigt.
-#-------------------------------------------------------#
-SUB_010=Highscores
-ENT_011=Zeigt alle vorhandenen Highscores mit Datum und Schwierigkeitsstufe an.
-#-------------------------------------------------------#
-SUB_020=Beste Sänger
-ENT_021=Zeigt die besten Sänger mit durchschnittlicher Punktezahl an.
-#-------------------------------------------------------#
-SUB_030=Beliebteste Songs
-ENT_031=Zeigt die beliebtesten Songs mit Singhäufigkeit an.
-#-------------------------------------------------------#
-SUB_040=Beliebteste Bands
-ENT_041=Zeigt die beliebtesten Bands mit der Anzahl gesungener Lieder an.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-ESC = zurück
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-#-------------------------------------------------------#
-SEC_002 = Navigation
-LEFT = Zur vorherigen Statistik wechseln.
-RIGHT = Zur nächsten Statistik wechseln.
-UP = Zur vorherigen Statistik wechseln.
-DOWN = Zur nächsten Statistik wechseln.
-
-#-------------------------------------------------------#
-# ID_029: UScreenTop #
-#-------------------------------------------------------#
-[ID_029]
-Title = Highscores
-Description = Hier wird die Highscoreliste der besten acht Sänger mit Datum angezeigt. Falls weniger als 100 Punkte erreicht wurden oder das Lied nicht bis zur letzten Liedzeile gesungen wurde, wird es nicht gewertet.
-#-------------------------------------------------------#
-SEC_001 = Allgemein
-RETURN = weiter
-ESC = weiter
-PRINT = Screenshot erstellen
-Q = UltraStar Deluxe beenden
-PAGEUP = MP3-Lautstärke erhöhen
-PAGEDOWN = MP3-Lautstärke reduzieren
-
-#-------------------------------------------------------#
-# ID_030: Select Plugins #
-#-------------------------------------------------------#
-[ID_030]
-Title = Pluginauswahl
-Description = Hier können die Plugins einzeln aktiviert/deaktiviert werden.
-#-------------------------------------------------------#
-SEC_010 = Navigation
-UP = Plugins nach oben durchscrollen
-DOWN = Plugins nach unten durchscrollen
-ESC = Zurück zu den Optionen
-RETURN = Weiter zur Namenseingabe
-#-------------------------------------------------------#
-SEC_020 = Pluginauswahl
-SPACE = Plugin aktivieren/deaktivieren
-LEFT = Plugin deaktivieren
-RIGHT = Plugin aktivieren
-
-#-------------------------------------------------------#
-# ID_031: ScreenSongJumpTo #
-#-------------------------------------------------------#
-[ID_031]
-Title = Songsuche
-Description = Hier kann nach bestimmten Songs, Titel oder Interpreten gesucht werden.
-#-------------------------------------------------------#
-SEC_010 = Navigation
-ESC = Suche Verlassen
-RETURN = Suche Verlassen
-PAGEUP = MP3-Lautstärke erhöhen
-PAGEDOWN = MP3-Lautstärke reduzieren
-
-#-------------------------------------------------------#
-# ID_032: ScreenSongMenu #
-#-------------------------------------------------------#
-[ID_032]
-Title = Songmenu
-Description = Hier fehlt noch Text!
-#-------------------------------------------------------#
-SEC_010 = Navigation
-ESC = Menu verlassen
-PAGEUP = MP3-Lautstärke erhöhen
-PAGEDOWN = MP3-Lautstärke reduzieren
-
-#-------------------------------------------------------#
-# ID_033: ScreenSongMenu Party #
-#-------------------------------------------------------#
-[ID_033]
-Title = Party-Songmenu
-Description = Hier fehlt noch Text!
-#-------------------------------------------------------#
-SEC_010 = Navigation
-ESC = Menu verlassen
-PAGEUP = MP3-Lautstärke erhöhen
-PAGEDOWN = MP3-Lautstärke reduzieren \ No newline at end of file
+SING_OPTIONS_GAME_SHUFFLETIME=Shuffle mode \ No newline at end of file
diff --git a/Game/Output/SDL.dll b/Game/Output/SDL.dll
index 628cdfcf..a5da7bbd 100644
--- a/Game/Output/SDL.dll
+++ b/Game/Output/SDL.dll
Binary files differ
diff --git a/Game/Output/Skins/Blue Sensation/[icon]song_duet.jpg b/Game/Output/Skins/Blue Sensation/[icon]song_duet.jpg
new file mode 100644
index 00000000..55158f74
--- /dev/null
+++ b/Game/Output/Skins/Blue Sensation/[icon]song_duet.jpg
Binary files differ
diff --git a/Game/Output/Skins/Blue Sensation/blue sensation b/Game/Output/Skins/Blue Sensation/blue sensation
deleted file mode 100644
index ba2add65..00000000
--- a/Game/Output/Skins/Blue Sensation/blue sensation
+++ /dev/null
@@ -1,170 +0,0 @@
-;0.5.1
-;experimental version
-;if you are using this as a sample for your theme
-;don't be suprised it doesn't work good with newer releases
-
-[Skin]
-Theme=Blue Sensation
-Name=blue sensation
-Color=Blue
-Author=Charis
-
-[Textures]
-
-
-# # # M A I N # # #
-Button =[main]button.jpg
-Buttonmenu1 =[main]buttonmenu1.jpg
-Buttonmenu2 =[main]buttonmenu2.jpg
-Buttonmenu3 =[main]buttonmenu3.jpg
-Buttonmenu4 =[main]buttonmenu4.jpg
-Buttonmenu5 =[main]buttonmenu5.jpg
-ButtonF = [main]buttonf.jpg
-MainBar = [main]mainBar.jpg
-SelectBG = [main]selectbg.jpg
-
-#Backgrounds
-LoadingBG =[bg-load]sensation.jpg
-MenuBG = [bg-menu]sensation.jpg
-MainBG = [bg-main]sensation.jpg
-SingBG = [bg-main]sensation.jpg
-SongBG =[bg-song]sensation.jpg
-ScoreScreenBG = [bg-party]sensation.jpg
-Top5BG = [bg-top5]sensation.jpg
-OptionsBG = [bg-main]sensation.jpg
-PartyBG =[bg-party]sensation.jpg
-PartyBGWin =[bg-party]sensation.jpg
-OptionsBG2 =[bg-option]sensation.jpg
-StatisticsBG =[bg-main]sensation.jpg
-PartyBGNext =[bg-party]sensation.jpg
-PartyScoreBG =[bg-party]sensation.jpg
-
-#Icons on screen
-SongCD = [icon]cd.jpg
-MainIcon = [icon]main.jpg
-MainSearch = [icon]search.jpg
-IconOption = [icon]options.jpg
-IconSongMenu = [icon]songmenu.jpg
-ScoreIcon = [icon]score.jpg
-PartyIcon = [icon]party.jpg
-StatIcon = [icon]stats.jpg
-VideoIcon =[icon]video.jpg
-
-IconError = [icon]error.jpg
-IconQuestion = [icon]question.jpg
-
-# # # S O N G S E L E C E T # # #
-SongSelection = [main]songSelection.jpg
-SongSelection1 =[main]songSelection1.jpg
-SongSelection2 =[main]songSelection2.jpg
-SongCover = [main]songCover.jpg
-
-
-# # # S I N G # # #
-#the bar where the lyrics reside
-LyricBar = [sing]textBar.jpg
-
-#this one slides in, to tell you that singing starts immediately
-LyricHelpBar = [sing]lyricsHelpBar.bmp
-
-#the time progress bar (not skinned in this theme :P )
-TimeBar1 = [sing]timeBarBG.jpg
-
-#the bar behind the timestuff
-TimeBar2 =[sing]timeBar1.jpg
-
-#linebonus, the thing that pop ups at the score
-LineBonusBack = [sing]lineBonusPopUp.jpg
-
-#Singbar (the thing beneath the scores)
-SingBarBack = [sing]singBarBack.jpg
-SingBarBar = [sing]singBarBar.jpg
-SingBarFront = [sing]singBarFront.jpg
-
-#Background for scores
-ScoreBG = [sing]scoreBg.jpg
-
-#Background for the P1, P2 and so on
-P = [sing]p.jpg
-
-#Pointer for lyrics
-Ball = [sing]LyricsBall.bmp
-
-
-# # # S C O R E / T O P 5 # # #
-ScoreBox = [score]box.jpg
-ScoreLevel = [score]level.jpg
-ScoreLevelRound = [score]levelRound.jpg
-ScoreEndCap = [score]endcap.jpg
-ScoreLine = [score]line.jpg
-PlayerNumberBox = [main]playerNumberBox.jpg
-
-
-# # # P A R T Y # # #
-Joker =[party]Joker.jpg
-PartyPlayerButton =[party]playerButton.jpg
-PartyTeamButton1 =[party]roundTeamButton.jpg
-PartyTeamButton2 =[party]playerTeamButton.jpg
-PartyTeamButton3 =[party]winTeamButton1.jpg
-PartyTeamButton4 =[party]winTeamButton2.jpg
-PartyTeamButton5 =[party]winTeamButton3.jpg
-PartyRoundBG1 =[party]roundBG1.jpg
-PartyRoundBG2 =[party]roundBG2.jpg
-PartyRoundBG3 =[party]roundBG3.jpg
-PartyRoundBG4 =[party]roundBG4.jpg
-HDL_Pointer =[party]pointer.bmp
-PartyTeamPoints =[party]teamPoints.jpg
-PartyScoreDeco =x_[party]scoreDecoration.jpg
-PartyScoreBG1 =[party]scoreBG1.jpg
-PartyScoreBG2 =[party]scoreBG2.jpg
-PartyWinDeco1 =[party]winDecoration1.jpg
-PartyWinDeco2 =[party]winDecoration1.jpg
-PartyWinDeco3 =[party]winDecoration1.jpg
-
-# # # S T A T S # # #
-StatMainBG1 = [stat]mainBG1.jpg
-StatMainBG2 = [stat]mainBG2.jpg
-StatMainBG3 = [stat]mainBG3.jpg
-StatDetailBG1 = [stat]detailBG1.jpg
-
-
-# # # N A V I # # #
-ButtonP = [button]p.jpg
-ButtonM = [button]m.jpg
-ButtonJ = [button]j.jpg
-ButtonAlt = [button]alt.jpg
-ButtonAZ = [button]az.jpg
-ButtonEnter =[button]enter.jpg
-ButtonNavi =[button]navi.jpg
-ButtonEsc = [button]esc.jpg
-Button13 = [button]13.jpg
-
-Leiste1 =[special]bar1.jpg
-Leiste2 =[special]bar2.jpg
-
-JumpToBG = [menu]jumpToBg.jpg
-SongMenuBG = [menu]songMenuBg.jpg
-SongMenuSelectBG = [menu]songMenuSelectBg.jpg
-PopUpBG = [menu]popUpBG.jpg
-PopUpFG = [menu]popUpFG.jpg
-
-
-# # # N O T E S # # #
-GrayLeft = [sing]notesLeft.bmp
-GrayMid = [sing]notesMid.bmp
-GrayRight = [sing]notesRight.bmp
-NoteBGLeft = [sing]notesBgLeft.bmp
-NoteBGMid = [sing]notesBgMid.bmp
-NoteBGRight = [sing]notesBgRight.bmp
-
-
-# # # E F F E C T S # # #
-NoteStar = [effect]goldenNoteStar.jpg
-NotePerfectStar = [effect]perfectNoteStar.jpg
-
-
-# # # dirty helpers # # #
-Rectangle = [helper]rectangle.jpg
-ButtonFade = [helper]buttonFade.jpg
-ButtonFadeMenu =[helper]buttonFade2.jpg
-ButtonOptions=[option]button.jpg
diff --git a/Game/Output/Skins/Blue Sensation/blue sensation.ini b/Game/Output/Skins/Blue Sensation/blue sensation.ini
index 48d2498a..b2ce4699 100644
--- a/Game/Output/Skins/Blue Sensation/blue sensation.ini
+++ b/Game/Output/Skins/Blue Sensation/blue sensation.ini
@@ -177,3 +177,4 @@ CallengeIcon=[icon]challenge.jpg
ClassicIcon=[icon]classic.jpg
MedleyIcon=[icon]medley.jpg
CalcMedleyIcon=[icon]calcmedley.jpg
+DuetIcon=[icon]song_duet.jpg \ No newline at end of file
diff --git a/Game/Output/Skins/Blue Sensation/blue simple.ini b/Game/Output/Skins/Blue Sensation/blue simple.ini
index 2e7e8efc..bbf2705f 100644
--- a/Game/Output/Skins/Blue Sensation/blue simple.ini
+++ b/Game/Output/Skins/Blue Sensation/blue simple.ini
@@ -177,3 +177,4 @@ CallengeIcon=[icon]challenge.jpg
ClassicIcon=[icon]classic.jpg
MedleyIcon=[icon]medley.jpg
CalcMedleyIcon=[icon]calcmedley.jpg
+DuetIcon=[icon]song_duet.jpg
diff --git a/Game/Output/Skins/Blue Sensation/city.ini b/Game/Output/Skins/Blue Sensation/city.ini
index 843013c7..44f87ea6 100644
--- a/Game/Output/Skins/Blue Sensation/city.ini
+++ b/Game/Output/Skins/Blue Sensation/city.ini
@@ -176,4 +176,5 @@ Buttonmenu7=[main]buttonmenu7.jpg
CallengeIcon=[icon]challenge.jpg
ClassicIcon=[icon]classic.jpg
MedleyIcon=[icon]medley.jpg
-CalcMedleyIcon=[icon]calcmedley.jpg \ No newline at end of file
+CalcMedleyIcon=[icon]calcmedley.jpg
+DuetIcon=[icon]song_duet.jpg \ No newline at end of file
diff --git a/Game/Output/Skins/Blue Sensation/flower.ini b/Game/Output/Skins/Blue Sensation/flower.ini
index c9f1d1fd..2f8cba17 100644
--- a/Game/Output/Skins/Blue Sensation/flower.ini
+++ b/Game/Output/Skins/Blue Sensation/flower.ini
@@ -176,4 +176,5 @@ Buttonmenu7=[main]buttonmenu7.jpg
CallengeIcon=[icon]challenge.jpg
ClassicIcon=[icon]classic.jpg
MedleyIcon=[icon]medley.jpg
-CalcMedleyIcon=[icon]calcmedley.jpg \ No newline at end of file
+CalcMedleyIcon=[icon]calcmedley.jpg
+DuetIcon=[icon]song_duet.jpg \ No newline at end of file
diff --git a/Game/Output/Skins/Deluxe/Blue.ini b/Game/Output/Skins/Deluxe/Blue.ini
index a1ee31bc..1a306e8e 100644
--- a/Game/Output/Skins/Deluxe/Blue.ini
+++ b/Game/Output/Skins/Deluxe/Blue.ini
@@ -38,6 +38,7 @@ StatIcon = [icon]stats.jpg
VideoIcon = [icon]video.jpg
CalcMedleyIcon = [icon]calcmedley.jpg
MedleyIcon = [icon]medley.jpg
+DuetIcon = [icon]song_duet.jpg
IconError = [icon]error.jpg
IconQuestion = [icon]question.jpg
diff --git a/Game/Output/Skins/Deluxe/Fall.ini b/Game/Output/Skins/Deluxe/Fall.ini
index c63aacb6..caafe762 100644
--- a/Game/Output/Skins/Deluxe/Fall.ini
+++ b/Game/Output/Skins/Deluxe/Fall.ini
@@ -38,6 +38,7 @@ StatIcon = [icon]stats.jpg
VideoIcon = [icon]video.jpg
CalcMedleyIcon = [icon]calcmedley.jpg
MedleyIcon = [icon]medley.jpg
+DuetIcon = [icon]song_duet.jpg
IconError = [icon]error.jpg
IconQuestion = [icon]question.jpg
diff --git a/Game/Output/Skins/Deluxe/Summer.ini b/Game/Output/Skins/Deluxe/Summer.ini
index b9bd3dc8..3f3cc8a5 100644
--- a/Game/Output/Skins/Deluxe/Summer.ini
+++ b/Game/Output/Skins/Deluxe/Summer.ini
@@ -38,6 +38,7 @@ StatIcon = [icon]stats.jpg
VideoIcon = [icon]video.jpg
CalcMedleyIcon = [icon]calcmedley.jpg
MedleyIcon = [icon]medley.jpg
+DuetIcon = [icon]song_duet.jpg
IconError = [icon]error.jpg
IconQuestion = [icon]question.jpg
diff --git a/Game/Output/Skins/Deluxe/Winter.ini b/Game/Output/Skins/Deluxe/Winter.ini
index 79b31ffb..eee3425b 100644
--- a/Game/Output/Skins/Deluxe/Winter.ini
+++ b/Game/Output/Skins/Deluxe/Winter.ini
@@ -38,6 +38,7 @@ StatIcon = [icon]stats.jpg
VideoIcon = [icon]video.jpg
CalcMedleyIcon = [icon]calcmedley.jpg
MedleyIcon = [icon]medley.jpg
+DuetIcon = [icon]song_duet.jpg
IconError = [icon]error.jpg
IconQuestion = [icon]question.jpg
diff --git a/Game/Output/Skins/Deluxe/[icon]song_duet.jpg b/Game/Output/Skins/Deluxe/[icon]song_duet.jpg
new file mode 100644
index 00000000..55158f74
--- /dev/null
+++ b/Game/Output/Skins/Deluxe/[icon]song_duet.jpg
Binary files differ
diff --git a/Game/Output/Skins/iStar/Apple.ini b/Game/Output/Skins/iStar/Apple.ini
index 71e69094..a997579f 100644
--- a/Game/Output/Skins/iStar/Apple.ini
+++ b/Game/Output/Skins/iStar/Apple.ini
@@ -163,6 +163,7 @@ ButtonFade =[helper]buttonFade2.jpg
ButtonFadeMenu =[helper]buttonFade.jpg
MedleyIcon=[icon]medley.jpg
CalcMedleyIcon=[icon]calcmedley.jpg
+DuetIcon=[icon]song_duet.jpg
ButtonFadeMenu4=[helper]buttonFade2.jpg
Buttonmenu7=[main]buttonmenu7.jpg
ButtonMenu9a=[main]buttonmenu9a.jpg
diff --git a/Game/Output/Skins/iStar/[icon]song_duet.jpg b/Game/Output/Skins/iStar/[icon]song_duet.jpg
new file mode 100644
index 00000000..55158f74
--- /dev/null
+++ b/Game/Output/Skins/iStar/[icon]song_duet.jpg
Binary files differ
diff --git a/Game/Output/Themes/Blue Sensation.ini b/Game/Output/Themes/Blue Sensation.ini
index 577267ce..713cec17 100644
--- a/Game/Output/Themes/Blue Sensation.ini
+++ b/Game/Output/Themes/Blue Sensation.ini
@@ -995,6 +995,16 @@ H =8
Color=Gray
Type=Font Black
+[SingStaticLyricDuetBar]
+;TextBG
+Tex =LyricBar
+X =0
+Y =3
+W =800
+H =80
+Color =White
+Type=Font Black
+
[SingTimeText]
Text =SING_TIME
X =729
@@ -1489,6 +1499,16 @@ Color=White
Tex =CalcMedleyIcon
Type=Font Black
+[SongDuetIcon]
+X =304
+Y =487
+W =28
+H =28
+Z=1
+Color=White
+Tex =DuetIcon
+Type=Font Black
+
[SongTextPartyTeam1NumJoker]
X = 600
Y = 400
diff --git a/Game/Output/Themes/Deluxe.ini b/Game/Output/Themes/Deluxe.ini
index 82b2c235..83ac80ce 100644
--- a/Game/Output/Themes/Deluxe.ini
+++ b/Game/Output/Themes/Deluxe.ini
@@ -659,6 +659,16 @@ H =7
Color=GrayLightest
Type=Font Black
+[SingStaticLyricDuetBar]
+;TextBG
+Tex =LyricBar
+X =0
+Y =3
+W =800
+H =80
+Color =White
+Type=Font Black
+
[SingTimeText]
Text =SING_TIME
X =750
@@ -9197,6 +9207,16 @@ Color=White
Tex =MedleyIcon
Type=Font Black
+[SongDuetIcon]
+X =334
+Y =487
+W =28
+H =28
+Z=1
+Color=White
+Tex =DuetIcon
+Type=Font Black
+
[SongCalculatedMedleyIcon]
X =334
Y =487
diff --git a/Game/Output/Themes/iStar.ini b/Game/Output/Themes/iStar.ini
index 8ccf0323..f8afe854 100644
--- a/Game/Output/Themes/iStar.ini
+++ b/Game/Output/Themes/iStar.ini
@@ -972,6 +972,16 @@ H =7
Color=GrayDark
Type=Font Black
+[SingStaticLyricDuetBar]
+;TextBG
+Tex =LyricBar
+X =0
+Y =3
+W =800
+H =80
+Color =White
+Type=Font Black
+
[SingTimeText]
Text =SING_TIME
X =754
@@ -1466,6 +1476,16 @@ Color=White
Tex =CalcMedleyIcon
Type=Font Black
+[SongDuetIcon]
+X =334
+Y =487
+W =28
+H =28
+Z=1
+Color=White
+Tex =DuetIcon
+Type=Font Black
+
[SongTextPartyTeam1NumJoker]
X = 600
Y = 400