aboutsummaryrefslogtreecommitdiffstats
path: root/Game/Code
diff options
context:
space:
mode:
Diffstat (limited to 'Game/Code')
-rw-r--r--Game/Code/Classes/TextGL.pas769
-rw-r--r--Game/Code/Classes/UCommon.pas230
-rw-r--r--Game/Code/Classes/UCovers.pas494
-rw-r--r--Game/Code/Classes/UDLLManager.pas480
-rw-r--r--Game/Code/Classes/UDataBase.pas597
-rw-r--r--Game/Code/Classes/UDraw.pas3145
-rw-r--r--Game/Code/Classes/UGraphic.pas1218
-rw-r--r--Game/Code/Classes/UGraphicClasses.pas1345
-rw-r--r--Game/Code/Classes/UJoystick.pas555
-rw-r--r--Game/Code/Classes/ULanguage.pas470
-rw-r--r--Game/Code/Classes/ULight.pas311
-rw-r--r--Game/Code/Classes/ULog.pas496
-rw-r--r--Game/Code/Classes/UMain.pas1573
-rw-r--r--Game/Code/Classes/UMusic.pas1356
-rw-r--r--Game/Code/Classes/URecord.pas706
-rw-r--r--Game/Code/Classes/UTexture.pas2071
-rw-r--r--Game/Code/Classes/UTime.pas212
-rw-r--r--Game/Code/Menu/UDisplay.pas929
-rw-r--r--Game/Code/Menu/UMenuButton.pas1137
-rw-r--r--Game/Code/Menu/UMenuText.pas668
-rw-r--r--Game/Code/Screens/UScreenCredits.pas2197
-rw-r--r--Game/Code/Screens/UScreenMain.pas554
-rw-r--r--Game/Code/Screens/UScreenSing.pas2492
-rw-r--r--Game/Code/Screens/UScreenSingModi.pas1334
-rw-r--r--Game/Code/Screens/UScreenSong.pas4047
-rw-r--r--Game/Code/Screens/UScreenSongMenu.pas1251
-rw-r--r--Game/Code/Screens/UScreenStatMain.pas516
-rw-r--r--Game/Code/UltraStar.lpi456
-rw-r--r--Game/Code/UltraStar.lpr203
-rw-r--r--Game/Code/switches.inc20
30 files changed, 16209 insertions, 15623 deletions
diff --git a/Game/Code/Classes/TextGL.pas b/Game/Code/Classes/TextGL.pas
index 8a702ca7..ee1a74f3 100644
--- a/Game/Code/Classes/TextGL.pas
+++ b/Game/Code/Classes/TextGL.pas
@@ -1,381 +1,388 @@
-unit TextGL;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-
-uses OpenGL12,
- SDL,
- UTexture,
- Classes,
- ULog;
-
-procedure BuildFont; // Build Our Bitmap Font
-procedure KillFont; // Delete The Font
-function glTextWidth(text: pchar): real; // Returns Text Width
-procedure glPrintDone(text: pchar; Done: real; ColR, ColG, ColB: real);
-procedure glPrintLetter(letter: char);
-procedure glPrintLetterCut(letter: char; Start, Finish: real);
-procedure glPrint(text: pchar); // Custom GL "Print" Routine
-procedure glPrintCut(text: pchar);
-procedure SetFontPos(X, Y: real); // Sets X And Y
-procedure SetFontSize(Size: real);
-procedure SetFontStyle(Style: integer); // sets active font style (normal, bold, etc)
-procedure SetFontItalic(Enable: boolean); // sets italic type letter (works for all fonts)
-procedure SetFontAspectW(Aspect: real);
-
-type
- TTextGL = record
- X: real;
- Y: real;
- Text: string;
- Size: real;
- ColR: real;
- ColG: real;
- ColB: real;
- end;
-
- TFont = record
- Tex: TTexture;
- Width: array[0..255] of byte;
- AspectW: real;
- Centered: boolean;
- Done: real;
- Outline: real;
- Italic: boolean;
- end;
-
-
-var
- base: GLuint; // Base Display List For The Font Set
- Fonts: array of TFont;
- ActFont: integer;
- PColR: real; // temps for glPrintDone
- PColG: real;
- PColB: real;
-
-implementation
-
-uses UMain,
- Windows,
- SysUtils,
- {$IFDEF FPC}
- LResources,
- {$ENDIF}
- UGraphic;
-
-procedure BuildFont; // Build Our Bitmap Font
-
- procedure loadfont( aID : integer; aType, aResourceName : String);
- var
- Rejestr: TResourceStream;
- begin
- {$IFNDEF FPC}
- Rejestr := TResourceStream.Create(HInstance, aResourceName , pchar( aType ) );
- try
- Rejestr.Read(Fonts[ aID ].Width, 256);
- finally
- Rejestr.Free;
- end;
- {$ENDIF}
- end;
-
-var
- font: HFONT; // Windows Font ID
- h_dc: hdc;
- Pet: integer;
-begin
- ActFont := 0;
-
- SetLength(Fonts, 5);
- Fonts[0].Tex := Texture.LoadTexture(true, 'Font', 'PNG', 'Font', 0);
- Fonts[0].Tex.H := 30;
- Fonts[0].AspectW := 0.9;
- Fonts[0].Done := -1;
- Fonts[0].Outline := 0;
-
- Fonts[1].Tex := Texture.LoadTexture(true, 'FontB', 'PNG', 'Font', 0);
- Fonts[1].Tex.H := 30;
- Fonts[1].AspectW := 1;
- Fonts[1].Done := -1;
- Fonts[1].Outline := 0;
-
- Fonts[2].Tex := Texture.LoadTexture(true, 'FontO', 'PNG', 'Font Outline', 0);
- Fonts[2].Tex.H := 30;
- Fonts[2].AspectW := 0.95;
- Fonts[2].Done := -1;
- Fonts[2].Outline := 5;
-
- Fonts[3].Tex := Texture.LoadTexture(true, 'FontO2', 'PNG', 'Font Outline 2', 0);
- Fonts[3].Tex.H := 30;
- Fonts[3].AspectW := 0.95;
- Fonts[3].Done := -1;
- Fonts[3].Outline := 4;
-
-{ Fonts[4].Tex := Texture.LoadTexture('FontO', 'BMP', 'Arrow', 0); // for score screen
- Fonts[4].Tex.H := 30;
- Fonts[4].AspectW := 0.95;
- Fonts[4].Done := -1;
- Fonts[4].Outline := 5;}
-
-
-
- {$IFDEF FPC}
- loadfont( 0, 'DAT', 'eurostar_regular' );
- loadfont( 1, 'DAT', 'eurostar_regular_bold' );
- loadfont( 2, 'DAT', 'Outline 1' );
- loadfont( 3, 'DAT', 'Outline 2' );
- {$ELSE}
- loadfont( 0, 'FNT', 'Font' );
- loadfont( 1, 'FNT', 'FontB' );
- loadfont( 2, 'FNT', 'FontO' );
- loadfont( 3, 'FNT', 'FontO2' );
- {$ENDIF}
-
-
-
-
-{ Rejestr := TResourceStream.Create(HInstance, 'FontO', 'FNT');
- Rejestr.Read(Fonts[4].Width, 256);
- Rejestr.Free;}
-
- for Pet := 0 to 255 do
- Fonts[1].Width[Pet] := Fonts[1].Width[Pet] div 2;
-
- for Pet := 0 to 255 do
- Fonts[2].Width[Pet] := Fonts[2].Width[Pet] div 2 + 2;
-
- for Pet := 0 to 255 do
- Fonts[3].Width[Pet] := Fonts[3].Width[Pet] + 1;
-
-{ for Pet := 0 to 255 do
- Fonts[4].Width[Pet] := Fonts[4].Width[Pet] div 2 + 2;}
-
-end;
-
-procedure KillFont; // Delete The Font
-begin
-// glDeleteLists(base, 256); // Delete All 96 Characters
-end;
-
-function glTextWidth(text: pchar): real;
-var
- Letter: char;
-begin
-// Log.LogStatus(Text, 'glTextWidth');
- Result := 0;
- while (length(text) > 0) do begin
- Letter := Text[0];
- text := pchar(Copy(text, 2, Length(text)-1));
- Result := Result + Fonts[ActFont].Width[Ord(Letter)] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW;
- end; // while
-end;
-
-procedure glPrintDone(text: pchar; Done: real; ColR, ColG, ColB: real);
-begin
- Fonts[ActFont].Done := Done;
- PColR := ColR;
- PColG := ColG;
- PColB := ColB;
- glPrintCut(text);
- Fonts[ActFont].Done := -1;
-end;
-
-procedure glPrintLetter(Letter: char);
-var
- TexX, TexY: real;
- TexR, TexB: real;
- FWidth: real;
- PL, PT: real;
- PR, PB: real;
- XItal: real; // X shift for italic type letter
-begin
- with Fonts[ActFont].Tex do begin
- FWidth := Fonts[ActFont].Width[Ord(Letter)];
-
- W := FWidth * (H/30) * Fonts[ActFont].AspectW;
-// H := 30;
-
- // set texture positions
- TexX := (ord(Letter) mod 16) * 1/16 + 1/32 - FWidth/1024 - Fonts[ActFont].Outline/1024;
- TexY := (ord(Letter) div 16) * 1/16 + 2/1024; // 2/1024
- TexR := (ord(Letter) mod 16) * 1/16 + 1/32 + FWidth/1024 + Fonts[ActFont].Outline/1024;
- TexB := (1 + ord(Letter) div 16) * 1/16 - 2/1024;
-
- // set vector positions
- PL := X - Fonts[ActFont].Outline * (H/30) * Fonts[ActFont].AspectW /2;
- PT := Y;
- PR := PL + W + Fonts[ActFont].Outline * (H/30) * Fonts[ActFont].AspectW;
- PB := PT + H;
- if Fonts[ActFont].Italic = false then
- XItal := 0
- else
- XItal := 12;
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(TexX, TexY); glVertex2f(PL+XItal, PT);
- glTexCoord2f(TexX, TexB); glVertex2f(PL, PB);
- glTexCoord2f(TexR, TexB); glVertex2f(PR, PB);
- glTexCoord2f(TexR, TexY); glVertex2f(PR+XItal, PT);
- glEnd;
- X := X + W;
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- end; // with
-end;
-
-procedure glPrintLetterCut(letter: char; Start, Finish: real);
-var
- TexX, TexY: real;
- TexR, TexB: real;
- TexTemp: real;
- FWidth: real;
- PL, PT: real;
- PR, PB: real;
- OutTemp: real;
- XItal: real;
-begin
- with Fonts[ActFont].Tex do begin
- FWidth := Fonts[ActFont].Width[Ord(Letter)];
-
- W := FWidth * (H/30) * Fonts[ActFont].AspectW;
-// H := 30;
- OutTemp := Fonts[ActFont].Outline * (H/30) * Fonts[ActFont].AspectW;
-
- // set texture positions
- TexX := (ord(Letter) mod 16) * 1/16 + 1/32 - FWidth/1024 - Fonts[ActFont].Outline/1024;
- TexY := (ord(Letter) div 16) * 1/16 + 2/1024; // 2/1024
- TexR := (ord(Letter) mod 16) * 1/16 + 1/32 + FWidth/1024 + Fonts[ActFont].Outline/1024;
- TexB := (1 + ord(Letter) div 16) * 1/16 - 2/1024;
-
- TexTemp := TexX + Start * (TexR - TexX);
- TexR := TexX + Finish * (TexR - TexX);
- TexX := TexTemp;
-
- // set vector positions
- PL := X - OutTemp / 2 + OutTemp * Start;
- PT := Y;
- PR := PL + (W + OutTemp) * (Finish - Start);
- PB := PT + H;
- if Fonts[ActFont].Italic = false then
- XItal := 0
- else
- XItal := 12;
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(TexX, TexY); glVertex2f(PL+XItal, PT);
- glTexCoord2f(TexX, TexB); glVertex2f(PL, PB);
- glTexCoord2f(TexR, TexB); glVertex2f(PR, PB);
- glTexCoord2f(TexR, TexY); glVertex2f(PR+XItal, PT); // not tested with XItal
- glEnd;
- X := X + W * (Finish - Start);
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- end; // with
-
-end;
-
-procedure glPrint(text: pchar); // Custom GL "Print" Routine
-var
- Letter: char;
-begin
- if (Text = '') then // If There's No Text
- Exit; // Do Nothing
-
- while (length(text) > 0) do begin
- // cut
- Letter := Text[0];
- Text := pchar(Copy(Text, 2, Length(Text)-1));
-
- // print
- glPrintLetter(Letter);
- end; // while
-end;
-
-procedure glPrintCut(text: pchar);
-var
- Letter: char;
- PToDo: real;
- PTotWidth: real;
- PDoingNow: real;
- S: string;
-begin
- if (Text = '') then // If There's No Text
- Exit; // Do Nothing
-
- PTotWidth := glTextWidth(Text);
- PToDo := Fonts[ActFont].Done;
-
- while (length(text) > 0) do begin
- // cut
- Letter := Text[0];
- Text := pchar(Copy(Text, 2, Length(Text)-1));
-
- // analyze
- S := Letter;
- PDoingNow := glTextWidth(pchar(S)) / PTotWidth;
-
- // drawing
- if (PToDo > 0) and (PDoingNow <= PToDo) then
- glPrintLetter(Letter);
-
- if (PToDo > 0) and (PDoingNow > PToDo) then begin
- glPrintLetterCut(Letter, 0, PToDo / PDoingNow);
- glColor3f(PColR, PColG, PColB);
- glPrintLetterCut(Letter, PToDo / PDoingNow, 1);
- end;
-
- if (PToDo <= 0) then
- glPrintLetter(Letter);
-
- PToDo := PToDo - PDoingNow;
-
- end; // while
-end;
-
-
-procedure SetFontPos(X, Y: real);
-begin
- Fonts[ActFont].Tex.X := X;
- Fonts[ActFont].Tex.Y := Y;
-end;
-
-procedure SetFontSize(Size: real);
-begin
- Fonts[ActFont].Tex.H := 30 * (Size/10);
-end;
-
-procedure SetFontStyle(Style: integer);
-begin
- ActFont := Style;
-end;
-
-procedure SetFontItalic(Enable: boolean);
-begin
- Fonts[ActFont].Italic := Enable;
-end;
-
-procedure SetFontAspectW(Aspect: real);
-begin
- Fonts[ActFont].AspectW := Aspect;
-end;
-
-{$IFDEF FPC}
-initialization
- {$I UltraStar.lrs}
-{$ENDIF}
-
-end.
-
-
+unit TextGL;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+
+uses OpenGL12,
+ SDL,
+ UTexture,
+ Classes,
+ ULog;
+
+procedure BuildFont; // Build Our Bitmap Font
+procedure KillFont; // Delete The Font
+function glTextWidth(text: pchar): real; // Returns Text Width
+procedure glPrintDone(text: pchar; Done: real; ColR, ColG, ColB: real);
+procedure glPrintLetter(letter: char);
+procedure glPrintLetterCut(letter: char; Start, Finish: real);
+procedure glPrint(text: pchar); // Custom GL "Print" Routine
+procedure glPrintCut(text: pchar);
+procedure SetFontPos(X, Y: real); // Sets X And Y
+procedure SetFontSize(Size: real);
+procedure SetFontStyle(Style: integer); // sets active font style (normal, bold, etc)
+procedure SetFontItalic(Enable: boolean); // sets italic type letter (works for all fonts)
+procedure SetFontAspectW(Aspect: real);
+
+type
+ TTextGL = record
+ X: real;
+ Y: real;
+ Text: string;
+ Size: real;
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ end;
+
+ TFont = record
+ Tex: TTexture;
+ Width: array[0..255] of byte;
+ AspectW: real;
+ Centered: boolean;
+ Done: real;
+ Outline: real;
+ Italic: boolean;
+ end;
+
+
+var
+ base: GLuint; // Base Display List For The Font Set
+ Fonts: array of TFont;
+ ActFont: integer;
+ PColR: real; // temps for glPrintDone
+ PColG: real;
+ PColB: real;
+
+implementation
+
+uses UMain,
+ {$IFDEF win32}
+ windows,
+ {$ELSE}
+ lclintf,
+ lcltype,
+ {$ENDIF}
+ SysUtils,
+ {$IFDEF FPC}
+ LResources,
+ {$ENDIF}
+ UGraphic;
+
+procedure BuildFont; // Build Our Bitmap Font
+
+ procedure loadfont( aID : integer; aType, aResourceName : String);
+ var
+ Rejestr: TResourceStream;
+ begin
+ {$IFNDEF FPC}
+ Rejestr := TResourceStream.Create(HInstance, aResourceName , pchar( aType ) );
+ try
+ Rejestr.Read(Fonts[ aID ].Width, 256);
+ finally
+ Rejestr.Free;
+ end;
+ {$ENDIF}
+ end;
+
+var
+ font: HFONT; // Windows Font ID
+ h_dc: hdc;
+ Pet: integer;
+begin
+ ActFont := 0;
+
+ SetLength(Fonts, 5);
+ Fonts[0].Tex := Texture.LoadTexture(true, 'Font', 'PNG', 'Font', 0);
+ Fonts[0].Tex.H := 30;
+ Fonts[0].AspectW := 0.9;
+ Fonts[0].Done := -1;
+ Fonts[0].Outline := 0;
+
+ Fonts[1].Tex := Texture.LoadTexture(true, 'FontB', 'PNG', 'Font', 0);
+ Fonts[1].Tex.H := 30;
+ Fonts[1].AspectW := 1;
+ Fonts[1].Done := -1;
+ Fonts[1].Outline := 0;
+
+ Fonts[2].Tex := Texture.LoadTexture(true, 'FontO', 'PNG', 'Font Outline', 0);
+ Fonts[2].Tex.H := 30;
+ Fonts[2].AspectW := 0.95;
+ Fonts[2].Done := -1;
+ Fonts[2].Outline := 5;
+
+ Fonts[3].Tex := Texture.LoadTexture(true, 'FontO2', 'PNG', 'Font Outline 2', 0);
+ Fonts[3].Tex.H := 30;
+ Fonts[3].AspectW := 0.95;
+ Fonts[3].Done := -1;
+ Fonts[3].Outline := 4;
+
+{ Fonts[4].Tex := Texture.LoadTexture('FontO', 'BMP', 'Arrow', 0); // for score screen
+ Fonts[4].Tex.H := 30;
+ Fonts[4].AspectW := 0.95;
+ Fonts[4].Done := -1;
+ Fonts[4].Outline := 5;}
+
+
+
+ {$IFDEF FPC}
+ loadfont( 0, 'DAT', 'eurostar_regular' );
+ loadfont( 1, 'DAT', 'eurostar_regular_bold' );
+ loadfont( 2, 'DAT', 'Outline 1' );
+ loadfont( 3, 'DAT', 'Outline 2' );
+ {$ELSE}
+ loadfont( 0, 'FNT', 'Font' );
+ loadfont( 1, 'FNT', 'FontB' );
+ loadfont( 2, 'FNT', 'FontO' );
+ loadfont( 3, 'FNT', 'FontO2' );
+ {$ENDIF}
+
+
+
+
+{ Rejestr := TResourceStream.Create(HInstance, 'FontO', 'FNT');
+ Rejestr.Read(Fonts[4].Width, 256);
+ Rejestr.Free;}
+
+ for Pet := 0 to 255 do
+ Fonts[1].Width[Pet] := Fonts[1].Width[Pet] div 2;
+
+ for Pet := 0 to 255 do
+ Fonts[2].Width[Pet] := Fonts[2].Width[Pet] div 2 + 2;
+
+ for Pet := 0 to 255 do
+ Fonts[3].Width[Pet] := Fonts[3].Width[Pet] + 1;
+
+{ for Pet := 0 to 255 do
+ Fonts[4].Width[Pet] := Fonts[4].Width[Pet] div 2 + 2;}
+
+end;
+
+procedure KillFont; // Delete The Font
+begin
+// glDeleteLists(base, 256); // Delete All 96 Characters
+end;
+
+function glTextWidth(text: pchar): real;
+var
+ Letter: char;
+begin
+// Log.LogStatus(Text, 'glTextWidth');
+ Result := 0;
+ while (length(text) > 0) do begin
+ Letter := Text[0];
+ text := pchar(Copy(text, 2, Length(text)-1));
+ Result := Result + Fonts[ActFont].Width[Ord(Letter)] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW;
+ end; // while
+end;
+
+procedure glPrintDone(text: pchar; Done: real; ColR, ColG, ColB: real);
+begin
+ Fonts[ActFont].Done := Done;
+ PColR := ColR;
+ PColG := ColG;
+ PColB := ColB;
+ glPrintCut(text);
+ Fonts[ActFont].Done := -1;
+end;
+
+procedure glPrintLetter(Letter: char);
+var
+ TexX, TexY: real;
+ TexR, TexB: real;
+ FWidth: real;
+ PL, PT: real;
+ PR, PB: real;
+ XItal: real; // X shift for italic type letter
+begin
+ with Fonts[ActFont].Tex do begin
+ FWidth := Fonts[ActFont].Width[Ord(Letter)];
+
+ W := FWidth * (H/30) * Fonts[ActFont].AspectW;
+// H := 30;
+
+ // set texture positions
+ TexX := (ord(Letter) mod 16) * 1/16 + 1/32 - FWidth/1024 - Fonts[ActFont].Outline/1024;
+ TexY := (ord(Letter) div 16) * 1/16 + 2/1024; // 2/1024
+ TexR := (ord(Letter) mod 16) * 1/16 + 1/32 + FWidth/1024 + Fonts[ActFont].Outline/1024;
+ TexB := (1 + ord(Letter) div 16) * 1/16 - 2/1024;
+
+ // set vector positions
+ PL := X - Fonts[ActFont].Outline * (H/30) * Fonts[ActFont].AspectW /2;
+ PT := Y;
+ PR := PL + W + Fonts[ActFont].Outline * (H/30) * Fonts[ActFont].AspectW;
+ PB := PT + H;
+ if Fonts[ActFont].Italic = false then
+ XItal := 0
+ else
+ XItal := 12;
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(TexX, TexY); glVertex2f(PL+XItal, PT);
+ glTexCoord2f(TexX, TexB); glVertex2f(PL, PB);
+ glTexCoord2f(TexR, TexB); glVertex2f(PR, PB);
+ glTexCoord2f(TexR, TexY); glVertex2f(PR+XItal, PT);
+ glEnd;
+ X := X + W;
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ end; // with
+end;
+
+procedure glPrintLetterCut(letter: char; Start, Finish: real);
+var
+ TexX, TexY: real;
+ TexR, TexB: real;
+ TexTemp: real;
+ FWidth: real;
+ PL, PT: real;
+ PR, PB: real;
+ OutTemp: real;
+ XItal: real;
+begin
+ with Fonts[ActFont].Tex do begin
+ FWidth := Fonts[ActFont].Width[Ord(Letter)];
+
+ W := FWidth * (H/30) * Fonts[ActFont].AspectW;
+// H := 30;
+ OutTemp := Fonts[ActFont].Outline * (H/30) * Fonts[ActFont].AspectW;
+
+ // set texture positions
+ TexX := (ord(Letter) mod 16) * 1/16 + 1/32 - FWidth/1024 - Fonts[ActFont].Outline/1024;
+ TexY := (ord(Letter) div 16) * 1/16 + 2/1024; // 2/1024
+ TexR := (ord(Letter) mod 16) * 1/16 + 1/32 + FWidth/1024 + Fonts[ActFont].Outline/1024;
+ TexB := (1 + ord(Letter) div 16) * 1/16 - 2/1024;
+
+ TexTemp := TexX + Start * (TexR - TexX);
+ TexR := TexX + Finish * (TexR - TexX);
+ TexX := TexTemp;
+
+ // set vector positions
+ PL := X - OutTemp / 2 + OutTemp * Start;
+ PT := Y;
+ PR := PL + (W + OutTemp) * (Finish - Start);
+ PB := PT + H;
+ if Fonts[ActFont].Italic = false then
+ XItal := 0
+ else
+ XItal := 12;
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(TexX, TexY); glVertex2f(PL+XItal, PT);
+ glTexCoord2f(TexX, TexB); glVertex2f(PL, PB);
+ glTexCoord2f(TexR, TexB); glVertex2f(PR, PB);
+ glTexCoord2f(TexR, TexY); glVertex2f(PR+XItal, PT); // not tested with XItal
+ glEnd;
+ X := X + W * (Finish - Start);
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ end; // with
+
+end;
+
+procedure glPrint(text: pchar); // Custom GL "Print" Routine
+var
+ Letter: char;
+begin
+ if (Text = '') then // If There's No Text
+ Exit; // Do Nothing
+
+ while (length(text) > 0) do begin
+ // cut
+ Letter := Text[0];
+ Text := pchar(Copy(Text, 2, Length(Text)-1));
+
+ // print
+ glPrintLetter(Letter);
+ end; // while
+end;
+
+procedure glPrintCut(text: pchar);
+var
+ Letter: char;
+ PToDo: real;
+ PTotWidth: real;
+ PDoingNow: real;
+ S: string;
+begin
+ if (Text = '') then // If There's No Text
+ Exit; // Do Nothing
+
+ PTotWidth := glTextWidth(Text);
+ PToDo := Fonts[ActFont].Done;
+
+ while (length(text) > 0) do begin
+ // cut
+ Letter := Text[0];
+ Text := pchar(Copy(Text, 2, Length(Text)-1));
+
+ // analyze
+ S := Letter;
+ PDoingNow := glTextWidth(pchar(S)) / PTotWidth;
+
+ // drawing
+ if (PToDo > 0) and (PDoingNow <= PToDo) then
+ glPrintLetter(Letter);
+
+ if (PToDo > 0) and (PDoingNow > PToDo) then begin
+ glPrintLetterCut(Letter, 0, PToDo / PDoingNow);
+ glColor3f(PColR, PColG, PColB);
+ glPrintLetterCut(Letter, PToDo / PDoingNow, 1);
+ end;
+
+ if (PToDo <= 0) then
+ glPrintLetter(Letter);
+
+ PToDo := PToDo - PDoingNow;
+
+ end; // while
+end;
+
+
+procedure SetFontPos(X, Y: real);
+begin
+ Fonts[ActFont].Tex.X := X;
+ Fonts[ActFont].Tex.Y := Y;
+end;
+
+procedure SetFontSize(Size: real);
+begin
+ Fonts[ActFont].Tex.H := 30 * (Size/10);
+end;
+
+procedure SetFontStyle(Style: integer);
+begin
+ ActFont := Style;
+end;
+
+procedure SetFontItalic(Enable: boolean);
+begin
+ Fonts[ActFont].Italic := Enable;
+end;
+
+procedure SetFontAspectW(Aspect: real);
+begin
+ Fonts[ActFont].AspectW := Aspect;
+end;
+
+{$IFDEF FPC}
+{$IFDEF win32}
+initialization
+ {$I UltraStar.lrs}
+{$ENDIF}
+{$ENDIF}
+
+end.
+
+
diff --git a/Game/Code/Classes/UCommon.pas b/Game/Code/Classes/UCommon.pas
index f25e025b..b7ddd7ba 100644
--- a/Game/Code/Classes/UCommon.pas
+++ b/Game/Code/Classes/UCommon.pas
@@ -1,98 +1,132 @@
-unit UCommon;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-uses
- windows;
-
-{$IFDEF FPC}
-
-type
- TWndMethod = procedure(var Message: TMessage) of object;
-
-function RandomRange(aMin: Integer; aMax: Integer) : Integer;
-function AllocateHWnd(Method: TWndMethod): HWND;
-procedure DeallocateHWnd(Wnd: HWND);
-
-function MaxValue(const Data: array of Double): Double;
-function MinValue(const Data: array of Double): Double;
-{$ENDIF}
-
-implementation
-
-{$IFDEF FPC}
-
-function MaxValue(const Data: array of Double): Double;
-var
- I: Integer;
-begin
- Result := Data[Low(Data)];
- for I := Low(Data) + 1 to High(Data) do
- if Result < Data[I] then
- Result := Data[I];
-end;
-
-function MinValue(const Data: array of Double): Double;
-var
- I: Integer;
-begin
- Result := Data[Low(Data)];
- for I := Low(Data) + 1 to High(Data) do
- if Result > Data[I] then
- Result := Data[I];
-end;
-
-function RandomRange(aMin: Integer; aMax: Integer) : Integer;
-begin
-RandomRange := Random(aMax-aMin) + aMin ;
-end;
-
-
-
-// TODO : JB this is dodgey and bad... find a REAL solution !
-function AllocateHWnd(Method: TWndMethod): HWND;
-var
- TempClass: TWndClass;
- ClassRegistered: Boolean;
-begin
-(*
- UtilWindowClass.hInstance := HInstance;
-{$IFDEF PIC}
- UtilWindowClass.lpfnWndProc := @DefWindowProc;
-{$ENDIF}
- ClassRegistered := GetClassInfo(HInstance, UtilWindowClass.lpszClassName, TempClass);
- if not ClassRegistered or (TempClass.lpfnWndProc <> @DefWindowProc) then
- begin
- if ClassRegistered then
- Windows.UnregisterClass(UtilWindowClass.lpszClassName, HInstance);
- Windows.RegisterClass(UtilWindowClass);
- end;
- Result := CreateWindowEx(WS_EX_TOOLWINDOW, UtilWindowClass.lpszClassName, '', WS_POPUP {+ 0}, 0, 0, 0, 0, 0, 0, HInstance, nil);
-*)
- Result := CreateWindowEx(WS_EX_TOOLWINDOW, '', '', WS_POPUP {+ 0}, 0, 0, 0, 0, 0, 0, HInstance, nil);
-
-(*
- if Assigned(Method) then
- SetWindowLong(Result, GWL_WNDPROC, Longint(MakeObjectInstance(Method)));
-*)
-end;
-
-procedure DeallocateHWnd(Wnd: HWND);
-var
- Instance: Pointer;
-begin
- Instance := Pointer(GetWindowLong(Wnd, GWL_WNDPROC));
- DestroyWindow(Wnd);
-
-// if Instance <> @DefWindowProc then
-// FreeObjectInstance(Instance);
-end;
-
-{$ENDIF}
-
-
-end.
+unit UCommon;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+uses
+
+{$IFDEF win32}
+ windows;
+{$ELSE}
+ lcltype,
+ messages;
+{$ENDIF}
+
+{$IFNDEF win32}
+type
+ hStream = THandle;
+ HGLRC = THandle;
+ TLargeInteger = Int64;
+ TWin32FindData = LongInt;
+{$ENDIF}
+
+{$IFDEF FPC}
+
+type
+ TWndMethod = procedure(var Message: TMessage) of object;
+
+function RandomRange(aMin: Integer; aMax: Integer) : Integer;
+//function AllocateHWnd(Method: TWndMethod): HWND;
+//procedure DeallocateHWnd(Wnd: HWND);
+
+function MaxValue(const Data: array of Double): Double;
+function MinValue(const Data: array of Double): Double;
+{$ENDIF}
+
+{$IFNDEF win32}
+(*
+ function QueryPerformanceCounter(lpPerformanceCount:TLARGEINTEGER):Bool;
+ function QueryPerformanceFrequency(lpFrequency:TLARGEINTEGER):Bool;
+*)
+ procedure ZeroMemory( Destination: Pointer; Length: DWORD );
+{$ENDIF}
+
+implementation
+
+{$IFNDEF win32}
+procedure ZeroMemory( Destination: Pointer; Length: DWORD );
+begin
+ FillChar( Destination^, Length, 0 );
+end; //ZeroMemory
+
+(*
+function QueryPerformanceCounter(lpPerformanceCount:TLARGEINTEGER):Bool;
+
+ // From http://en.wikipedia.org/wiki/RDTSC
+ function RDTSC: Int64; register;
+ asm
+ rdtsc
+ end;
+
+begin
+ // Use clock_gettime here maybe ... from libc
+ lpPerformanceCount := RDTSC();
+ result := true;
+end;
+
+function QueryPerformanceFrequency(lpFrequency:TLARGEINTEGER):Bool;
+begin
+ lpFrequency := 0;
+ result := true;
+end;
+*)
+{$ENDIF}
+
+
+{$IFDEF FPC}
+
+function MaxValue(const Data: array of Double): Double;
+var
+ I: Integer;
+begin
+ Result := Data[Low(Data)];
+ for I := Low(Data) + 1 to High(Data) do
+ if Result < Data[I] then
+ Result := Data[I];
+end;
+
+function MinValue(const Data: array of Double): Double;
+var
+ I: Integer;
+begin
+ Result := Data[Low(Data)];
+ for I := Low(Data) + 1 to High(Data) do
+ if Result > Data[I] then
+ Result := Data[I];
+end;
+
+function RandomRange(aMin: Integer; aMax: Integer) : Integer;
+begin
+RandomRange := Random(aMax-aMin) + aMin ;
+end;
+
+
+// NOTE !!!!!!!!!!
+// AllocateHWnd is in lclintfh.inc
+
+{
+// TODO : JB this is dodgey and bad... find a REAL solution !
+function AllocateHWnd(Method: TWndMethod): HWND;
+var
+ TempClass: TWndClass;
+ ClassRegistered: Boolean;
+begin
+ Result := CreateWindowEx(WS_EX_TOOLWINDOW, '', '', WS_POPUP , 0, 0, 0, 0, 0, 0, HInstance, nil);
+end;
+
+procedure DeallocateHWnd(Wnd: HWND);
+var
+ Instance: Pointer;
+begin
+ Instance := Pointer(GetWindowLong(Wnd, GWL_WNDPROC));
+ DestroyWindow(Wnd);
+end;
+}
+
+{$ENDIF}
+
+
+end.
diff --git a/Game/Code/Classes/UCovers.pas b/Game/Code/Classes/UCovers.pas
index efed1435..094fe43c 100644
--- a/Game/Code/Classes/UCovers.pas
+++ b/Game/Code/Classes/UCovers.pas
@@ -1,246 +1,248 @@
-unit UCovers;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-uses OpenGL12,
- Windows,
- Math,
- Classes,
- SysUtils,
- {$IFNDEF FPC}
- Graphics,
- {$ENDIF}
- UThemes,
- UTexture;
-
-type
- TCover = record
- Name: string;
- W: word;
- H: word;
- Size: integer;
- Position: integer; // position of picture in the cache file
-// Data: array of byte;
- end;
-
- TCovers = class
- Cover: array of TCover;
- W: word;
- H: word;
- Size: integer;
- Data: array of byte;
- WritetoFile: Boolean;
-
- constructor Create;
- procedure Load;
- procedure Save;
- procedure AddCover(Name: string);
- function CoverExists(Name: string): boolean;
- function CoverNumber(Name: string): integer;
- procedure PrepareData(Name: string);
- end;
-
-var
- Covers: TCovers;
-
-implementation
-
-uses UMain,
- // UFiles,
- ULog,
- DateUtils;
-
-constructor TCovers.Create;
-begin
- W := 128;
- H := 128;
- Size := W*H*3;
- Load;
- WritetoFile := True;
-end;
-
-procedure TCovers.Load;
-var
- F: File;
- C: integer; // cover number
- W: word;
- H: word;
- Bits: byte;
- NLen: word;
- Name: string;
-// Data: array of byte;
-begin
- if FileExists(GamePath + 'covers.cache') then
- begin
- AssignFile(F, GamePath + 'covers.cache');
- Reset(F, 1);
-
- WritetoFile := not FileIsReadOnly(GamePath + 'covers.cache');
-
- SetLength(Cover, 0);
-
- while not EOF(F) do
- begin
- SetLength(Cover, Length(Cover)+1);
-
- BlockRead(F, W, 2);
- Cover[High(Cover)].W := W;
-
- BlockRead(F, H, 2);
- Cover[High(Cover)].H := H;
-
- BlockRead(F, Bits, 1);
-
- Cover[High(Cover)].Size := W * H * (Bits div 8);
-
- // test
- // W := 128;
- // H := 128;
- // Bits := 24;
- // Seek(F, FilePos(F) + 3);
-
- BlockRead(F, NLen, 2);
- SetLength(Name, NLen);
-
- BlockRead(F, Name[1], NLen);
- Cover[High(Cover)].Name := Name;
-
- Cover[High(Cover)].Position := FilePos(F);
- Seek(F, FilePos(F) + W*H*(Bits div 8));
-
- // SetLength(Cover[High(Cover)].Data, W*H*(Bits div 8));
- // BlockRead(F, Cover[High(Cover)].Data[0], W*H*(Bits div 8));
-
- end; // While
-
- CloseFile(F);
- end; // fileexists
-end;
-
-procedure TCovers.Save;
-var
- F: File;
- C: integer; // cover number
- W: word;
- H: word;
- NLen: word;
- Bits: byte;
-begin
-{ AssignFile(F, GamePath + 'covers.cache');
- Rewrite(F, 1);
-
- Bits := 24;
- for C := 0 to High(Cover) do begin
- W := Cover[C].W;
- H := Cover[C].H;
-
- BlockWrite(F, W, 2);
- BlockWrite(F, H, 2);
- BlockWrite(F, Bits, 1);
-
- NLen := Length(Cover[C].Name);
- BlockWrite(F, NLen, 2);
- BlockWrite(F, Cover[C].Name[1], NLen);
- BlockWrite(F, Cover[C].Data[0], W*H*(Bits div 8));
- end;
-
- CloseFile(F);}
-end;
-
-procedure TCovers.AddCover(Name: string);
-var
- B: integer;
- F: File;
- C: integer; // cover number
- NLen: word;
- Bits: byte;
-begin
- if not CoverExists(Name) then begin
- SetLength(Cover, Length(Cover)+1);
- Cover[High(Cover)].Name := Name;
-
- Cover[High(Cover)].W := W;
- Cover[High(Cover)].H := H;
- Cover[High(Cover)].Size := Size;
-
- // do not copy data. write them directly to file
-// SetLength(Cover[High(Cover)].Data, Size);
-// for B := 0 to Size-1 do
-// Cover[High(Cover)].Data[B] := CacheMipmap[B];
-
- if WritetoFile then
- begin
- AssignFile(F, GamePath + 'covers.cache');
- if FileExists(GamePath + 'covers.cache') then begin
- Reset(F, 1);
- Seek(F, FileSize(F));
- end else
- Rewrite(F, 1);
-
- Bits := 24;
-
- BlockWrite(F, W, 2);
- BlockWrite(F, H, 2);
- BlockWrite(F, Bits, 1);
-
- NLen := Length(Name);
- BlockWrite(F, NLen, 2);
- BlockWrite(F, Name[1], NLen);
-
- Cover[High(Cover)].Position := FilePos(F);
- BlockWrite(F, CacheMipmap[0], W*H*(Bits div 8));
-
- CloseFile(F);
- end;
- end
- else
- Cover[High(Cover)].Position := 0;
-end;
-
-function TCovers.CoverExists(Name: string): boolean;
-var
- C: integer; // cover
-begin
- Result := false;
- C := 0;
- while (C <= High(Cover)) and (Result = false) do begin
- if Cover[C].Name = Name then Result := true;
- Inc(C);
- end;
-end;
-
-function TCovers.CoverNumber(Name: string): integer;
-var
- C: integer;
-begin
- Result := -1;
- C := 0;
- while (C <= High(Cover)) and (Result = -1) do begin
- if Cover[C].Name = Name then Result := C;
- Inc(C);
- end;
-end;
-
-procedure TCovers.PrepareData(Name: string);
-var
- F: File;
- C: integer;
-begin
- if FileExists(GamePath + 'covers.cache') then begin
- AssignFile(F, GamePath + 'covers.cache');
- Reset(F, 1);
-
- C := CoverNumber(Name);
- SetLength(Data, Cover[C].Size);
- if Length(Data) < 6 then beep;
- Seek(F, Cover[C].Position);
- BlockRead(F, Data[0], Cover[C].Size);
- CloseFile(F);
- end;
-end;
-
-end.
+unit UCovers;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+uses OpenGL12,
+ {$IFDEF win32}
+ windows,
+ {$ENDIF}
+ Math,
+ Classes,
+ SysUtils,
+ {$IFNDEF FPC}
+ Graphics,
+ {$ENDIF}
+ UThemes,
+ UTexture;
+
+type
+ TCover = record
+ Name: string;
+ W: word;
+ H: word;
+ Size: integer;
+ Position: integer; // position of picture in the cache file
+// Data: array of byte;
+ end;
+
+ TCovers = class
+ Cover: array of TCover;
+ W: word;
+ H: word;
+ Size: integer;
+ Data: array of byte;
+ WritetoFile: Boolean;
+
+ constructor Create;
+ procedure Load;
+ procedure Save;
+ procedure AddCover(Name: string);
+ function CoverExists(Name: string): boolean;
+ function CoverNumber(Name: string): integer;
+ procedure PrepareData(Name: string);
+ end;
+
+var
+ Covers: TCovers;
+
+implementation
+
+uses UMain,
+ // UFiles,
+ ULog,
+ DateUtils;
+
+constructor TCovers.Create;
+begin
+ W := 128;
+ H := 128;
+ Size := W*H*3;
+ Load;
+ WritetoFile := True;
+end;
+
+procedure TCovers.Load;
+var
+ F: File;
+ C: integer; // cover number
+ W: word;
+ H: word;
+ Bits: byte;
+ NLen: word;
+ Name: string;
+// Data: array of byte;
+begin
+ if FileExists(GamePath + 'covers.cache') then
+ begin
+ AssignFile(F, GamePath + 'covers.cache');
+ Reset(F, 1);
+
+ WritetoFile := not FileIsReadOnly(GamePath + 'covers.cache');
+
+ SetLength(Cover, 0);
+
+ while not EOF(F) do
+ begin
+ SetLength(Cover, Length(Cover)+1);
+
+ BlockRead(F, W, 2);
+ Cover[High(Cover)].W := W;
+
+ BlockRead(F, H, 2);
+ Cover[High(Cover)].H := H;
+
+ BlockRead(F, Bits, 1);
+
+ Cover[High(Cover)].Size := W * H * (Bits div 8);
+
+ // test
+ // W := 128;
+ // H := 128;
+ // Bits := 24;
+ // Seek(F, FilePos(F) + 3);
+
+ BlockRead(F, NLen, 2);
+ SetLength(Name, NLen);
+
+ BlockRead(F, Name[1], NLen);
+ Cover[High(Cover)].Name := Name;
+
+ Cover[High(Cover)].Position := FilePos(F);
+ Seek(F, FilePos(F) + W*H*(Bits div 8));
+
+ // SetLength(Cover[High(Cover)].Data, W*H*(Bits div 8));
+ // BlockRead(F, Cover[High(Cover)].Data[0], W*H*(Bits div 8));
+
+ end; // While
+
+ CloseFile(F);
+ end; // fileexists
+end;
+
+procedure TCovers.Save;
+var
+ F: File;
+ C: integer; // cover number
+ W: word;
+ H: word;
+ NLen: word;
+ Bits: byte;
+begin
+{ AssignFile(F, GamePath + 'covers.cache');
+ Rewrite(F, 1);
+
+ Bits := 24;
+ for C := 0 to High(Cover) do begin
+ W := Cover[C].W;
+ H := Cover[C].H;
+
+ BlockWrite(F, W, 2);
+ BlockWrite(F, H, 2);
+ BlockWrite(F, Bits, 1);
+
+ NLen := Length(Cover[C].Name);
+ BlockWrite(F, NLen, 2);
+ BlockWrite(F, Cover[C].Name[1], NLen);
+ BlockWrite(F, Cover[C].Data[0], W*H*(Bits div 8));
+ end;
+
+ CloseFile(F);}
+end;
+
+procedure TCovers.AddCover(Name: string);
+var
+ B: integer;
+ F: File;
+ C: integer; // cover number
+ NLen: word;
+ Bits: byte;
+begin
+ if not CoverExists(Name) then begin
+ SetLength(Cover, Length(Cover)+1);
+ Cover[High(Cover)].Name := Name;
+
+ Cover[High(Cover)].W := W;
+ Cover[High(Cover)].H := H;
+ Cover[High(Cover)].Size := Size;
+
+ // do not copy data. write them directly to file
+// SetLength(Cover[High(Cover)].Data, Size);
+// for B := 0 to Size-1 do
+// Cover[High(Cover)].Data[B] := CacheMipmap[B];
+
+ if WritetoFile then
+ begin
+ AssignFile(F, GamePath + 'covers.cache');
+ if FileExists(GamePath + 'covers.cache') then begin
+ Reset(F, 1);
+ Seek(F, FileSize(F));
+ end else
+ Rewrite(F, 1);
+
+ Bits := 24;
+
+ BlockWrite(F, W, 2);
+ BlockWrite(F, H, 2);
+ BlockWrite(F, Bits, 1);
+
+ NLen := Length(Name);
+ BlockWrite(F, NLen, 2);
+ BlockWrite(F, Name[1], NLen);
+
+ Cover[High(Cover)].Position := FilePos(F);
+ BlockWrite(F, CacheMipmap[0], W*H*(Bits div 8));
+
+ CloseFile(F);
+ end;
+ end
+ else
+ Cover[High(Cover)].Position := 0;
+end;
+
+function TCovers.CoverExists(Name: string): boolean;
+var
+ C: integer; // cover
+begin
+ Result := false;
+ C := 0;
+ while (C <= High(Cover)) and (Result = false) do begin
+ if Cover[C].Name = Name then Result := true;
+ Inc(C);
+ end;
+end;
+
+function TCovers.CoverNumber(Name: string): integer;
+var
+ C: integer;
+begin
+ Result := -1;
+ C := 0;
+ while (C <= High(Cover)) and (Result = -1) do begin
+ if Cover[C].Name = Name then Result := C;
+ Inc(C);
+ end;
+end;
+
+procedure TCovers.PrepareData(Name: string);
+var
+ F: File;
+ C: integer;
+begin
+ if FileExists(GamePath + 'covers.cache') then begin
+ AssignFile(F, GamePath + 'covers.cache');
+ Reset(F, 1);
+
+ C := CoverNumber(Name);
+ SetLength(Data, Cover[C].Size);
+ if Length(Data) < 6 then beep;
+ Seek(F, Cover[C].Position);
+ BlockRead(F, Data[0], Cover[C].Size);
+ CloseFile(F);
+ end;
+end;
+
+end.
diff --git a/Game/Code/Classes/UDLLManager.pas b/Game/Code/Classes/UDLLManager.pas
index 0d328c37..d25efb35 100644
--- a/Game/Code/Classes/UDLLManager.pas
+++ b/Game/Code/Classes/UDLLManager.pas
@@ -1,233 +1,247 @@
-unit UDLLManager;
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-
-interface
-
-uses ModiSDK,
- UFiles;
-
-type
- TDLLMan = class
- private
- hLib: THandle;
- P_Init: fModi_Init;
- P_Draw: fModi_Draw;
- P_Finish: fModi_Finish;
- P_RData: pModi_RData;
- public
- Plugins: array of TPluginInfo;
- PluginPaths: array of String;
- Selected: ^TPluginInfo;
-
- constructor Create;
-
- procedure GetPluginList;
- procedure ClearPluginInfo(No: Cardinal);
- function LoadPluginInfo(Filename: String; No: Cardinal): boolean;
-
- function LoadPlugin(No: Cardinal): boolean;
- procedure UnLoadPlugin;
-
- function PluginInit (const TeamInfo: TTeamInfo; var Playerinfo: TPlayerinfo; const Sentences: TSentences; const LoadTex: fModi_LoadTex; const Print: fModi_Print; LoadSound: fModi_LoadSound; PlaySound: pModi_PlaySound): boolean;
- function PluginDraw (var Playerinfo: TPlayerinfo; const CurSentence: Cardinal): boolean;
- function PluginFinish (var Playerinfo: TPlayerinfo): byte;
- procedure PluginRData (handle: HSTREAM; buffer: Pointer; len: DWORD; user: DWORD);
- end;
-
-var
- DLLMan: TDLLMan;
-
-const DLLPath = 'Plugins\';
-
-implementation
-uses Windows, ULog, SysUtils;
-
-
-constructor TDLLMan.Create;
-begin
- SetLength(Plugins, 0);
- SetLength(PluginPaths, Length(Plugins));
- GetPluginList;
-end;
-
-procedure TDLLMan.GetPluginList;
-var
- SR: TSearchRec;
-begin
-
- if FindFirst(DLLPath + '*.dll', faAnyFile , SR) = 0 then
- begin
- repeat
- SetLength(Plugins, Length(Plugins)+1);
- SetLength(PluginPaths, Length(Plugins));
-
- if LoadPluginInfo(SR.Name, High(Plugins)) then //Loaded succesful
- begin
- PluginPaths[High(PluginPaths)] := SR.Name;
- end
- else //Error Loading
- begin
- SetLength(Plugins, Length(Plugins)-1);
- SetLength(PluginPaths, Length(Plugins));
- end;
-
- until FindNext(SR) <> 0;
- FindClose(SR);
- end;
-end;
-
-procedure TDLLMan.ClearPluginInfo(No: Cardinal);
-begin
- //Set to Party Modi Plugin
- Plugins[No].Typ := 8;
-
- Plugins[No].Name := 'unknown';
- Plugins[No].NumPlayers := 0;
-
- Plugins[No].Creator := 'Nobody';
- Plugins[No].PluginDesc := 'NO_PLUGIN_DESC';
-
- Plugins[No].LoadSong := True;
- Plugins[No].ShowScore := True;
- Plugins[No].ShowBars := False;
- Plugins[No].ShowNotes := True;
- Plugins[No].LoadVideo := True;
- Plugins[No].LoadBack := True;
-
- Plugins[No].TeamModeOnly := False;
- Plugins[No].GetSoundData := False;
- Plugins[No].Dummy := False;
-
-
- Plugins[No].BGShowFull := False;
- Plugins[No].BGShowFull_O := True;
-
- Plugins[No].ShowRateBar:= False;
- Plugins[No].ShowRateBar_O := True;
-
- Plugins[No].EnLineBonus := False;
- Plugins[No].EnLineBonus_O := True;
-end;
-
-function TDLLMan.LoadPluginInfo(Filename: String; No: Cardinal): boolean;
-var
- hLibg: THandle;
- Info: pModi_PluginInfo;
- I: Integer;
-begin
- Result := False;
- //Clear Plugin Info
- ClearPluginInfo(No);
-
- {//Workaround Plugins Loaded 2 Times
- For I := low(PluginPaths) to high(PluginPaths) do
- if (PluginPaths[I] = Filename) then
- exit; }
-
- //Load Libary
- hLibg := LoadLibrary(PChar(DLLPath + Filename));
- //If Loaded
- if (hLibg <> 0) then
- begin
- //Load Info Procedure
- @Info := GetProcAddress (hLibg, PChar('PluginInfo'));
-
- //If Loaded
- if (@Info <> nil) then
- begin
- //Load PluginInfo
- Info (Plugins[No]);
- Result := True;
- end
- else
- Log.LogError('Could not Load Plugin "' + Filename + '": Info Procedure not Found');
-
- FreeLibrary (hLibg);
- end
- else
- Log.LogError('Could not Load Plugin "' + Filename + '": Libary not Loaded');
-end;
-
-function TDLLMan.LoadPlugin(No: Cardinal): boolean;
-begin
- Result := False;
- //Load Libary
- hLib := LoadLibrary(PChar(DLLPath + PluginPaths[No]));
- //If Loaded
- if (hLib <> 0) then
- begin
- //Load Info Procedure
- @P_Init := GetProcAddress (hLib, PChar('Init'));
- @P_Draw := GetProcAddress (hLib, PChar('Draw'));
- @P_Finish := GetProcAddress (hLib, PChar('Finish'));
-
- //If Loaded
- if (@P_Init <> nil) And (@P_Draw <> nil) And (@P_Finish <> nil) then
- begin
- Selected := @Plugins[No];
- Result := True;
- end
- else
- begin
- Log.LogError('Could not Load Plugin "' + PluginPaths[No] + '": Procedures not Found');
-
- end;
- end
- else
- Log.LogError('Could not Load Plugin "' + PluginPaths[No] + '": Libary not Loaded');
-end;
-
-procedure TDLLMan.UnLoadPlugin;
-begin
-if (hLib <> 0) then
- FreeLibrary (hLib);
-
-//Selected := nil;
-@P_Init := nil;
-@P_Draw := nil;
-@P_Finish := nil;
-@P_RData := nil;
-end;
-
-function TDLLMan.PluginInit (const TeamInfo: TTeamInfo; var Playerinfo: TPlayerinfo; const Sentences: TSentences; const LoadTex: fModi_LoadTex; const Print: fModi_Print; LoadSound: fModi_LoadSound; PlaySound: pModi_PlaySound): boolean;
-var
- Methods: TMethodRec;
-begin
- Methods.LoadTex := LoadTex;
- Methods.Print := Print;
- Methods.LoadSound := LoadSound;
- Methods.PlaySound := PlaySound;
-
- if (@P_Init <> nil) then
- Result := P_Init (TeamInfo, PlayerInfo, Sentences, Methods)
- else
- Result := False
-end;
-
-function TDLLMan.PluginDraw (var Playerinfo: TPlayerinfo; const CurSentence: Cardinal): boolean;
-begin
-if (@P_Draw <> nil) then
- Result := P_Draw (PlayerInfo, CurSentence)
-else
- Result := False
-end;
-
-function TDLLMan.PluginFinish (var Playerinfo: TPlayerinfo): byte;
-begin
-if (@P_Finish <> nil) then
- Result := P_Finish (PlayerInfo)
-else
- Result := 0;
-end;
-
-procedure TDLLMan.PluginRData (handle: HSTREAM; buffer: Pointer; len: DWORD; user: DWORD);
-begin
-if (@P_RData <> nil) then
- P_RData (handle, buffer, len, user);
-end;
-
-end.
+unit UDLLManager;
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+{$ENDIF}
+
+
+interface
+
+uses ModiSDK,
+ UFiles;
+
+type
+ TDLLMan = class
+ private
+ hLib: THandle;
+ P_Init: fModi_Init;
+ P_Draw: fModi_Draw;
+ P_Finish: fModi_Finish;
+ P_RData: pModi_RData;
+ public
+ Plugins: array of TPluginInfo;
+ PluginPaths: array of String;
+ Selected: ^TPluginInfo;
+
+ constructor Create;
+
+ procedure GetPluginList;
+ procedure ClearPluginInfo(No: Cardinal);
+ function LoadPluginInfo(Filename: String; No: Cardinal): boolean;
+
+ function LoadPlugin(No: Cardinal): boolean;
+ procedure UnLoadPlugin;
+
+ function PluginInit (const TeamInfo: TTeamInfo; var Playerinfo: TPlayerinfo; const Sentences: TSentences; const LoadTex: fModi_LoadTex; const Print: fModi_Print; LoadSound: fModi_LoadSound; PlaySound: pModi_PlaySound): boolean;
+ function PluginDraw (var Playerinfo: TPlayerinfo; const CurSentence: Cardinal): boolean;
+ function PluginFinish (var Playerinfo: TPlayerinfo): byte;
+ procedure PluginRData (handle: HSTREAM; buffer: Pointer; len: DWORD; user: DWORD);
+ end;
+
+var
+ DLLMan: TDLLMan;
+
+const
+ {$IFDEF win32}
+ DLLPath = 'Plugins\';
+ DLLExt = '.dll';
+ {$ELSE}
+ DLLPath = 'Plugins/';
+ DLLExt = '.so';
+ {$ENDIF}
+
+implementation
+
+uses {$IFDEF win32}
+ windows,
+ {$ELSE}
+ dynlibs,
+ {$ENDIF}
+ ULog,
+ SysUtils;
+
+
+constructor TDLLMan.Create;
+begin
+ SetLength(Plugins, 0);
+ SetLength(PluginPaths, Length(Plugins));
+ GetPluginList;
+end;
+
+procedure TDLLMan.GetPluginList;
+var
+ SR: TSearchRec;
+begin
+
+ if FindFirst(DLLPath + '*' + DLLExt, faAnyFile , SR) = 0 then
+ begin
+ repeat
+ SetLength(Plugins, Length(Plugins)+1);
+ SetLength(PluginPaths, Length(Plugins));
+
+ if LoadPluginInfo(SR.Name, High(Plugins)) then //Loaded succesful
+ begin
+ PluginPaths[High(PluginPaths)] := SR.Name;
+ end
+ else //Error Loading
+ begin
+ SetLength(Plugins, Length(Plugins)-1);
+ SetLength(PluginPaths, Length(Plugins));
+ end;
+
+ until FindNext(SR) <> 0;
+ FindClose(SR);
+ end;
+end;
+
+procedure TDLLMan.ClearPluginInfo(No: Cardinal);
+begin
+ //Set to Party Modi Plugin
+ Plugins[No].Typ := 8;
+
+ Plugins[No].Name := 'unknown';
+ Plugins[No].NumPlayers := 0;
+
+ Plugins[No].Creator := 'Nobody';
+ Plugins[No].PluginDesc := 'NO_PLUGIN_DESC';
+
+ Plugins[No].LoadSong := True;
+ Plugins[No].ShowScore := True;
+ Plugins[No].ShowBars := False;
+ Plugins[No].ShowNotes := True;
+ Plugins[No].LoadVideo := True;
+ Plugins[No].LoadBack := True;
+
+ Plugins[No].TeamModeOnly := False;
+ Plugins[No].GetSoundData := False;
+ Plugins[No].Dummy := False;
+
+
+ Plugins[No].BGShowFull := False;
+ Plugins[No].BGShowFull_O := True;
+
+ Plugins[No].ShowRateBar:= False;
+ Plugins[No].ShowRateBar_O := True;
+
+ Plugins[No].EnLineBonus := False;
+ Plugins[No].EnLineBonus_O := True;
+end;
+
+function TDLLMan.LoadPluginInfo(Filename: String; No: Cardinal): boolean;
+var
+ hLibg: THandle;
+ Info: pModi_PluginInfo;
+ I: Integer;
+begin
+ Result := False;
+ //Clear Plugin Info
+ ClearPluginInfo(No);
+
+ {//Workaround Plugins Loaded 2 Times
+ For I := low(PluginPaths) to high(PluginPaths) do
+ if (PluginPaths[I] = Filename) then
+ exit; }
+
+ //Load Libary
+ hLibg := LoadLibrary(PChar(DLLPath + Filename));
+ //If Loaded
+ if (hLibg <> 0) then
+ begin
+ //Load Info Procedure
+ @Info := GetProcAddress (hLibg, PChar('PluginInfo'));
+
+ //If Loaded
+ if (@Info <> nil) then
+ begin
+ //Load PluginInfo
+ Info (Plugins[No]);
+ Result := True;
+ end
+ else
+ Log.LogError('Could not Load Plugin "' + Filename + '": Info Procedure not Found');
+
+ FreeLibrary (hLibg);
+ end
+ else
+ Log.LogError('Could not Load Plugin "' + Filename + '": Libary not Loaded');
+end;
+
+function TDLLMan.LoadPlugin(No: Cardinal): boolean;
+begin
+ Result := False;
+ //Load Libary
+ hLib := LoadLibrary(PChar(DLLPath + PluginPaths[No]));
+ //If Loaded
+ if (hLib <> 0) then
+ begin
+ //Load Info Procedure
+ @P_Init := GetProcAddress (hLib, PChar('Init'));
+ @P_Draw := GetProcAddress (hLib, PChar('Draw'));
+ @P_Finish := GetProcAddress (hLib, PChar('Finish'));
+
+ //If Loaded
+ if (@P_Init <> nil) And (@P_Draw <> nil) And (@P_Finish <> nil) then
+ begin
+ Selected := @Plugins[No];
+ Result := True;
+ end
+ else
+ begin
+ Log.LogError('Could not Load Plugin "' + PluginPaths[No] + '": Procedures not Found');
+
+ end;
+ end
+ else
+ Log.LogError('Could not Load Plugin "' + PluginPaths[No] + '": Libary not Loaded');
+end;
+
+procedure TDLLMan.UnLoadPlugin;
+begin
+if (hLib <> 0) then
+ FreeLibrary (hLib);
+
+//Selected := nil;
+@P_Init := nil;
+@P_Draw := nil;
+@P_Finish := nil;
+@P_RData := nil;
+end;
+
+function TDLLMan.PluginInit (const TeamInfo: TTeamInfo; var Playerinfo: TPlayerinfo; const Sentences: TSentences; const LoadTex: fModi_LoadTex; const Print: fModi_Print; LoadSound: fModi_LoadSound; PlaySound: pModi_PlaySound): boolean;
+var
+ Methods: TMethodRec;
+begin
+ Methods.LoadTex := LoadTex;
+ Methods.Print := Print;
+ Methods.LoadSound := LoadSound;
+ Methods.PlaySound := PlaySound;
+
+ if (@P_Init <> nil) then
+ Result := P_Init (TeamInfo, PlayerInfo, Sentences, Methods)
+ else
+ Result := False
+end;
+
+function TDLLMan.PluginDraw (var Playerinfo: TPlayerinfo; const CurSentence: Cardinal): boolean;
+begin
+if (@P_Draw <> nil) then
+ Result := P_Draw (PlayerInfo, CurSentence)
+else
+ Result := False
+end;
+
+function TDLLMan.PluginFinish (var Playerinfo: TPlayerinfo): byte;
+begin
+if (@P_Finish <> nil) then
+ Result := P_Finish (PlayerInfo)
+else
+ Result := 0;
+end;
+
+procedure TDLLMan.PluginRData (handle: HSTREAM; buffer: Pointer; len: DWORD; user: DWORD);
+begin
+if (@P_RData <> nil) then
+ P_RData (handle, buffer, len, user);
+end;
+
+end.
diff --git a/Game/Code/Classes/UDataBase.pas b/Game/Code/Classes/UDataBase.pas
index 009d0d63..deee85c0 100644
--- a/Game/Code/Classes/UDataBase.pas
+++ b/Game/Code/Classes/UDataBase.pas
@@ -1,299 +1,298 @@
-unit UDataBase;
-
-interface
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-
-uses USongs, SQLiteTable3;
-
-//--------------------
-//DataBaseSystem - Class including all DB Methods
-//--------------------
-type
- TStatResult = record
- Case Typ: Byte of
- 0: (Singer: ShortString;
- Score: Word;
- Difficulty: Byte;
- SongArtist: ShortString;
- SongTitle: ShortString);
-
- 1: (Player: ShortString;
- AverageScore: Word);
-
- 2: (Artist: ShortString;
- Title: ShortString;
- TimesSung: Word);
-
- 3: (ArtistName: ShortString;
- TimesSungtot: Word);
- end;
- AStatResult = Array of TStatResult;
-
- TDataBaseSystem = class
- private
- ScoreDB: TSqliteDatabase;
- sFilename: string;
- public
-
-
- property Filename: String read sFilename;
-
- Destructor Free;
-
- Procedure Init(const Filename: string);
- procedure ReadScore(var Song: TSong);
- procedure AddScore(var Song: TSong; Level: integer; Name: string; Score: integer);
- procedure WriteScore(var Song: TSong);
-
- Function GetStats(var Stats: AStatResult; const Typ, Count: Byte; const Page: Cardinal; const Reversed: Boolean): Boolean;
- Function GetTotalEntrys(const Typ: Byte): Cardinal;
- end;
-
-var
- DataBase: TDataBaseSystem;
-
-implementation
-
-uses IniFiles, SysUtils;
-
-//--------------------
-//Create - Opens Database and Create Tables if not Exist
-//--------------------
-
-Procedure TDataBaseSystem.Init(const Filename: string);
-begin
- //Open Database
- ScoreDB := TSqliteDatabase.Create(Filename);
- sFilename := Filename;
-
- try
- //Look for Tables => When not exist Create them
- if not ScoreDB.TableExists('US_Scores') then
- ScoreDB.execsql('CREATE TABLE `US_Scores` (`SongID` INT( 11 ) NOT NULL , `Difficulty` INT( 1 ) NOT NULL , `Player` VARCHAR( 150 ) NOT NULL , `Score` INT( 5 ) NOT NULL );');
-
- if not ScoreDB.TableExists('US_Songs') then
- ScoreDB.execsql('CREATE TABLE `US_Songs` (`ID` INTEGER PRIMARY KEY, `Artist` VARCHAR( 255 ) NOT NULL , `Title` VARCHAR( 255 ) NOT NULL , `TimesPlayed` int(5) NOT NULL );');
- //Not possible because of String Limitation to 255 Chars //Need to rewrite Wrapper
- {if not ScoreDB.TableExists('US_SongCache') then
- ScoreDB.ExecSQL('CREATE TABLE `US_SongCache` (`Path` VARCHAR( 255 ) NOT NULL , `Filename` VARCHAR( 255 ) NOT NULL , `Title` VARCHAR( 255 ) NOT NULL , `Artist` VARCHAR( 255 ) NOT NULL , `Folder` VARCHAR( 255 ) NOT NULL , `Genre` VARCHAR( 255 ) NOT NULL , `Edition` VARCHAR( 255 ) NOT NULL , `Language` VARCHAR( 255 ) NOT NULL , `Creator` VARCHAR( 255 ) NOT NULL , `Cover` VARCHAR( 255 ) NOT NULL , `Background` VARCHAR( 255 ) NOT NULL , `Video` VARCHAR( 255 ) NOT NULL , `VideoGap` FLOAT NOT NULL , `Gap` FLOAT NOT NULL , `Start` FLOAT NOT NULL , `Finish` INT( 11 ) NOT NULL , `BPM` INT( 5 ) NOT NULL , `Relative` BOOLEAN NOT NULL , `NotesGap` INT( 11 ) NOT NULL);');}
-
-
- finally
- //ScoreDB.Free;
- end;
-
-end;
-
-//--------------------
-//Free - Frees Database
-//--------------------
-Destructor TDataBaseSystem.Free;
-begin
- ScoreDB.Free;
-end;
-
-//--------------------
-//ReadScore - Read Scores into SongArray
-//--------------------
-procedure TDataBaseSystem.ReadScore(var Song: TSong);
-var
- TableData: TSqliteTable;
- Dif: Byte;
-begin
- //ScoreDB := TSqliteDatabase.Create(sFilename);
- try
- try
- //Search Song in DB
- TableData := ScoreDB.GetTable('SELECT `Difficulty`, `Player`, `Score` FROM `us_scores` WHERE `SongID` = (SELECT `ID` FROM `us_songs` WHERE `Artist` = "' + Song.Artist + '" AND `Title` = "' + Song.Title + '" LIMIT 1) ORDER BY `Score` DESC LIMIT 15');
- //Empty Old Scores
- SetLength (Song.Score[0], 0);
- SetLength (Song.Score[1], 0);
- SetLength (Song.Score[2], 0);
-
- while not TableData.Eof do//Go through all Entrys
- begin//Add one Entry to Array
- Dif := StrtoInt(TableData.FieldAsString(TableData.FieldIndex['Difficulty']));
- if (Dif>=0) AND (Dif<=2) then
- begin
- SetLength(Song.Score[Dif], Length(Song.Score[Dif]) + 1);
-
- Song.Score[Dif, high(Song.Score[Dif])].Name := TableData.FieldAsString(TableData.FieldIndex['Player']);
- Song.Score[Dif, high(Song.Score[Dif])].Score:= StrtoInt(TableData.FieldAsString(TableData.FieldIndex['Score']));
- end;
- TableData.Next;
- end;
-
- except //Im Fehlerfall
- for Dif := 0 to 2 do
- begin
- SetLength(Song.Score[Dif], 1);
- Song.Score[Dif, 1].Name := 'Error Reading ScoreDB';
- end;
- end;
- finally
- //ScoreDb.Free;
- end;
-end;
-
-//--------------------
-//AddScore - Add one new Score to DB
-//--------------------
-procedure TDataBaseSystem.AddScore(var Song: TSong; Level: integer; Name: string; Score: integer);
-var
-ID: Integer;
-TableData: TSqliteTable;
-begin
- //ScoreDB := TSqliteDatabase.Create(sFilename);
- try
- //Prevent 0 Scores from being added
- if (Score > 0) then
- begin
-
- ID := ScoreDB.GetTableValue('SELECT `ID` FROM `US_Songs` WHERE `Artist` = "' + Song.Artist + '" AND `Title` = "' + Song.Title + '"');
- if ID = 0 then //Song doesn't exist -> Create
- begin
- ScoreDB.ExecSQL ('INSERT INTO `US_Songs` ( `ID` , `Artist` , `Title` , `TimesPlayed` ) VALUES (NULL , "' + Song.Artist + '", "' + Song.Title + '", "0");');
- ID := ScoreDB.GetTableValue('SELECT `ID` FROM `US_Songs` WHERE `Artist` = "' + Song.Artist + '" AND `Title` = "' + Song.Title + '"');
- if ID = 0 then //Could not Create Table
- exit;
- end;
- //Create new Entry
- ScoreDB.ExecSQL('INSERT INTO `US_Scores` ( `SongID` , `Difficulty` , `Player` , `Score` ) VALUES ("' + InttoStr(ID) + '", "' + InttoStr(Level) + '", "' + Name + '", "' + InttoStr(Score) + '");');
-
- //Delete Last Position when there are more than 5 Entrys
- if ScoreDB.GetTableValue('SELECT COUNT(`SongID`) FROM `US_Scores` WHERE `SongID` = "' + InttoStr(ID) + '" AND `Difficulty` = "' + InttoStr(Level) +'"') > 5 then
- begin
- TableData := ScoreDB.GetTable('SELECT `Player`, `Score` FROM `US_Scores` WHERE SongID = "' + InttoStr(ID) + '" AND `Difficulty` = "' + InttoStr(Level) +'" ORDER BY `Score` ASC LIMIT 1');
- ScoreDB.ExecSQL('DELETE FROM `US_Scores` WHERE SongID = "' + InttoStr(ID) + '" AND `Difficulty` = "' + InttoStr(Level) +'" AND `Player` = "' + TableData.FieldAsString(TableData.FieldIndex['Player']) + '" AND `Score` = "' + TableData.FieldAsString(TableData.FieldIndex['Score']) + '"');
- end;
-
- end;
- finally
- //ScoreDB.Free;
- end;
-end;
-
-//--------------------
-//WriteScore - Not needed with new System; But used for Increment Played Count
-//--------------------
-procedure TDataBaseSystem.WriteScore(var Song: TSong);
-begin
- try
- //Increase TimesPlayed
- ScoreDB.ExecSQL ('UPDATE `us_songs` SET `TimesPlayed` = `TimesPlayed` + "1" WHERE `Title` = "' + Song.Title + '" AND `Artist` = "' + Song.Artist + '";');
- except
-
- end;
-end;
-
-//--------------------
-//GetStats - Write some Stats to Array, Returns True if Chossen Page has Entrys
-//Case Typ of
-//0 - Best Scores
-//1 - Best Singers
-//2 - Most sung Songs
-//3 - Most popular Band
-//--------------------
-Function TDataBaseSystem.GetStats(var Stats: AStatResult; const Typ, Count: Byte; const Page: Cardinal; const Reversed: Boolean): Boolean;
-var
- Query: String;
- TableData: TSqliteTable;
-begin
- Result := False;
-
- if (Length(Stats) < Count) then
- Exit;
-
- {Todo:
- Add Prevention that only Players with more than 5 Scores are Selected at Typ 2}
-
- //Create Query
- Case Typ of
- 0: Query := 'SELECT `Player` , `Difficulty` , `Score` , `Artist` , `Title` FROM `US_Scores` INNER JOIN `US_Songs` ON (`SongID` = `ID`) ORDER BY `Score`';
- 1: Query := 'SELECT `Player` , ROUND (Sum(`Score`) / COUNT(`Score`)) FROM `US_Scores` GROUP BY `Player` ORDER BY (Sum(`Score`) / COUNT(`Score`))';
- 2: Query := 'SELECT `Artist` , `Title` , `TimesPlayed` FROM `US_Songs` ORDER BY `TimesPlayed`';
- 3: Query := 'SELECT `Artist` , Sum(`TimesPlayed`) FROM `US_Songs` GROUP BY `Artist` ORDER BY Sum(`TimesPlayed`)';
- end;
-
- //Add Order Direction
- If Reversed then
- Query := Query + ' ASC'
- else
- Query := Query + ' DESC';
-
- //Add Limit
- Query := Query + ' LIMIT ' + InttoStr(Count * Page) + ', ' + InttoStr(Count) + ';';
-
- //Execute Query
- //try
- TableData := ScoreDB.GetTable(Query);
- {except
- exit;
- end;}
-
- //if Result empty -> Exit
- if (TableData.RowCount < 1) then
- exit;
-
- //Copy Result to Stats Array
- while not TableData.Eof do
- begin
- Stats[TableData.Row].Typ := Typ;
-
- Case Typ of
- 0:begin
- Stats[TableData.Row].Singer := TableData.Fields[0];
-
- Stats[TableData.Row].Difficulty := StrtoIntDef(TableData.Fields[1], 0);
-
- Stats[TableData.Row].Score := StrtoIntDef(TableData.Fields[2], 0){TableData.FieldAsInteger(2)};
- Stats[TableData.Row].SongArtist := TableData.Fields[3];
- Stats[TableData.Row].SongTitle := TableData.Fields[4];
- end;
-
- 1:begin
- Stats[TableData.Row].Player := TableData.Fields[0];
- Stats[TableData.Row].AverageScore := StrtoIntDef(TableData.Fields[1], 0);
- end;
-
- 2:begin
- Stats[TableData.Row].Artist := TableData.Fields[0];
- Stats[TableData.Row].Title := TableData.Fields[1];
- Stats[TableData.Row].TimesSung := StrtoIntDef(TableData.Fields[2], 0);
- end;
-
- 3:begin
- Stats[TableData.Row].ArtistName := TableData.Fields[0];
- Stats[TableData.Row].TimesSungtot := StrtoIntDef(TableData.Fields[1], 0);
- end;
-
- end;
-
- TableData.Next;
- end;
-
- Result := True;
-end;
-
-//--------------------
-//GetTotalEntrys - Get Total Num of entrys for a Stats Query
-//--------------------
-Function TDataBaseSystem.GetTotalEntrys(const Typ: Byte): Cardinal;
-var Query: String;
-begin
- //Create Query
- Case Typ of
- 0: Query := 'SELECT COUNT(`SongID`) FROM `US_Scores`;';
- 1: Query := 'SELECT COUNT(DISTINCT `Player`) FROM `US_Scores`;';
- 2: Query := 'SELECT COUNT(`ID`) FROM `US_Songs`;';
- 3: Query := 'SELECT COUNT(DISTINCT `Artist`) FROM `US_Songs`;';
- end;
-
- Result := ScoreDB.GetTableValue(Query);
-end;
-
-end.
+unit UDataBase;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+{$ENDIF}
+
+
+uses USongs, SQLiteTable3;
+
+//--------------------
+//DataBaseSystem - Class including all DB Methods
+//--------------------
+type
+ TStatResult = record
+ Case Typ: Byte of
+ 0: (Singer: ShortString;
+ Score: Word;
+ Difficulty: Byte;
+ SongArtist: ShortString;
+ SongTitle: ShortString);
+
+ 1: (Player: ShortString;
+ AverageScore: Word);
+
+ 2: (Artist: ShortString;
+ Title: ShortString;
+ TimesSung: Word);
+
+ 3: (ArtistName: ShortString;
+ TimesSungtot: Word);
+ end;
+ AStatResult = Array of TStatResult;
+
+ TDataBaseSystem = class
+ private
+ ScoreDB: TSqliteDatabase;
+ sFilename: string;
+ public
+
+
+ property Filename: String read sFilename;
+
+ Destructor Free;
+
+ Procedure Init(const Filename: string);
+ procedure ReadScore(var Song: TSong);
+ procedure AddScore(var Song: TSong; Level: integer; Name: string; Score: integer);
+ procedure WriteScore(var Song: TSong);
+
+ Function GetStats(var Stats: AStatResult; const Typ, Count: Byte; const Page: Cardinal; const Reversed: Boolean): Boolean;
+ Function GetTotalEntrys(const Typ: Byte): Cardinal;
+ end;
+
+var
+ DataBase: TDataBaseSystem;
+
+implementation
+
+uses IniFiles, SysUtils;
+
+//--------------------
+//Create - Opens Database and Create Tables if not Exist
+//--------------------
+
+Procedure TDataBaseSystem.Init(const Filename: string);
+begin
+ //Open Database
+ ScoreDB := TSqliteDatabase.Create(Filename);
+ sFilename := Filename;
+
+ try
+ //Look for Tables => When not exist Create them
+ if not ScoreDB.TableExists('US_Scores') then
+ ScoreDB.execsql('CREATE TABLE `US_Scores` (`SongID` INT( 11 ) NOT NULL , `Difficulty` INT( 1 ) NOT NULL , `Player` VARCHAR( 150 ) NOT NULL , `Score` INT( 5 ) NOT NULL );');
+
+ if not ScoreDB.TableExists('US_Songs') then
+ ScoreDB.execsql('CREATE TABLE `US_Songs` (`ID` INTEGER PRIMARY KEY, `Artist` VARCHAR( 255 ) NOT NULL , `Title` VARCHAR( 255 ) NOT NULL , `TimesPlayed` int(5) NOT NULL );');
+ //Not possible because of String Limitation to 255 Chars //Need to rewrite Wrapper
+ {if not ScoreDB.TableExists('US_SongCache') then
+ ScoreDB.ExecSQL('CREATE TABLE `US_SongCache` (`Path` VARCHAR( 255 ) NOT NULL , `Filename` VARCHAR( 255 ) NOT NULL , `Title` VARCHAR( 255 ) NOT NULL , `Artist` VARCHAR( 255 ) NOT NULL , `Folder` VARCHAR( 255 ) NOT NULL , `Genre` VARCHAR( 255 ) NOT NULL , `Edition` VARCHAR( 255 ) NOT NULL , `Language` VARCHAR( 255 ) NOT NULL , `Creator` VARCHAR( 255 ) NOT NULL , `Cover` VARCHAR( 255 ) NOT NULL , `Background` VARCHAR( 255 ) NOT NULL , `Video` VARCHAR( 255 ) NOT NULL , `VideoGap` FLOAT NOT NULL , `Gap` FLOAT NOT NULL , `Start` FLOAT NOT NULL , `Finish` INT( 11 ) NOT NULL , `BPM` INT( 5 ) NOT NULL , `Relative` BOOLEAN NOT NULL , `NotesGap` INT( 11 ) NOT NULL);');}
+
+
+ finally
+ //ScoreDB.Free;
+ end;
+
+end;
+
+//--------------------
+//Free - Frees Database
+//--------------------
+Destructor TDataBaseSystem.Free;
+begin
+ ScoreDB.Free;
+end;
+
+//--------------------
+//ReadScore - Read Scores into SongArray
+//--------------------
+procedure TDataBaseSystem.ReadScore(var Song: TSong);
+var
+ TableData: TSqliteTable;
+ Dif: Byte;
+begin
+ //ScoreDB := TSqliteDatabase.Create(sFilename);
+ try
+ try
+ //Search Song in DB
+ TableData := ScoreDB.GetTable('SELECT `Difficulty`, `Player`, `Score` FROM `us_scores` WHERE `SongID` = (SELECT `ID` FROM `us_songs` WHERE `Artist` = "' + Song.Artist + '" AND `Title` = "' + Song.Title + '" LIMIT 1) ORDER BY `Score` DESC LIMIT 15');
+ //Empty Old Scores
+ SetLength (Song.Score[0], 0);
+ SetLength (Song.Score[1], 0);
+ SetLength (Song.Score[2], 0);
+
+ while not TableData.Eof do//Go through all Entrys
+ begin//Add one Entry to Array
+ Dif := StrtoInt(TableData.FieldAsString(TableData.FieldIndex['Difficulty']));
+ if (Dif>=0) AND (Dif<=2) then
+ begin
+ SetLength(Song.Score[Dif], Length(Song.Score[Dif]) + 1);
+
+ Song.Score[Dif, high(Song.Score[Dif])].Name := TableData.FieldAsString(TableData.FieldIndex['Player']);
+ Song.Score[Dif, high(Song.Score[Dif])].Score:= StrtoInt(TableData.FieldAsString(TableData.FieldIndex['Score']));
+ end;
+ TableData.Next;
+ end;
+
+ except //Im Fehlerfall
+ for Dif := 0 to 2 do
+ begin
+ SetLength(Song.Score[Dif], 1);
+ Song.Score[Dif, 1].Name := 'Error Reading ScoreDB';
+ end;
+ end;
+ finally
+ //ScoreDb.Free;
+ end;
+end;
+
+//--------------------
+//AddScore - Add one new Score to DB
+//--------------------
+procedure TDataBaseSystem.AddScore(var Song: TSong; Level: integer; Name: string; Score: integer);
+var
+ID: Integer;
+TableData: TSqliteTable;
+begin
+ //ScoreDB := TSqliteDatabase.Create(sFilename);
+ try
+ //Prevent 0 Scores from being added
+ if (Score > 0) then
+ begin
+
+ ID := ScoreDB.GetTableValue('SELECT `ID` FROM `US_Songs` WHERE `Artist` = "' + Song.Artist + '" AND `Title` = "' + Song.Title + '"');
+ if ID = 0 then //Song doesn't exist -> Create
+ begin
+ ScoreDB.ExecSQL ('INSERT INTO `US_Songs` ( `ID` , `Artist` , `Title` , `TimesPlayed` ) VALUES (NULL , "' + Song.Artist + '", "' + Song.Title + '", "0");');
+ ID := ScoreDB.GetTableValue('SELECT `ID` FROM `US_Songs` WHERE `Artist` = "' + Song.Artist + '" AND `Title` = "' + Song.Title + '"');
+ if ID = 0 then //Could not Create Table
+ exit;
+ end;
+ //Create new Entry
+ ScoreDB.ExecSQL('INSERT INTO `US_Scores` ( `SongID` , `Difficulty` , `Player` , `Score` ) VALUES ("' + InttoStr(ID) + '", "' + InttoStr(Level) + '", "' + Name + '", "' + InttoStr(Score) + '");');
+
+ //Delete Last Position when there are more than 5 Entrys
+ if ScoreDB.GetTableValue('SELECT COUNT(`SongID`) FROM `US_Scores` WHERE `SongID` = "' + InttoStr(ID) + '" AND `Difficulty` = "' + InttoStr(Level) +'"') > 5 then
+ begin
+ TableData := ScoreDB.GetTable('SELECT `Player`, `Score` FROM `US_Scores` WHERE SongID = "' + InttoStr(ID) + '" AND `Difficulty` = "' + InttoStr(Level) +'" ORDER BY `Score` ASC LIMIT 1');
+ ScoreDB.ExecSQL('DELETE FROM `US_Scores` WHERE SongID = "' + InttoStr(ID) + '" AND `Difficulty` = "' + InttoStr(Level) +'" AND `Player` = "' + TableData.FieldAsString(TableData.FieldIndex['Player']) + '" AND `Score` = "' + TableData.FieldAsString(TableData.FieldIndex['Score']) + '"');
+ end;
+
+ end;
+ finally
+ //ScoreDB.Free;
+ end;
+end;
+
+//--------------------
+//WriteScore - Not needed with new System; But used for Increment Played Count
+//--------------------
+procedure TDataBaseSystem.WriteScore(var Song: TSong);
+begin
+ try
+ //Increase TimesPlayed
+ ScoreDB.ExecSQL ('UPDATE `us_songs` SET `TimesPlayed` = `TimesPlayed` + "1" WHERE `Title` = "' + Song.Title + '" AND `Artist` = "' + Song.Artist + '";');
+ except
+
+ end;
+end;
+
+//--------------------
+//GetStats - Write some Stats to Array, Returns True if Chossen Page has Entrys
+//Case Typ of
+//0 - Best Scores
+//1 - Best Singers
+//2 - Most sung Songs
+//3 - Most popular Band
+//--------------------
+Function TDataBaseSystem.GetStats(var Stats: AStatResult; const Typ, Count: Byte; const Page: Cardinal; const Reversed: Boolean): Boolean;
+var
+ Query: String;
+ TableData: TSqliteTable;
+begin
+ Result := False;
+
+ if (Length(Stats) < Count) then
+ Exit;
+
+ {Todo: Add Prevention that only Players with more than 5 Scores are Selected at Typ 2}
+
+ //Create Query
+ Case Typ of
+ 0: Query := 'SELECT `Player` , `Difficulty` , `Score` , `Artist` , `Title` FROM `US_Scores` INNER JOIN `US_Songs` ON (`SongID` = `ID`) ORDER BY `Score`';
+ 1: Query := 'SELECT `Player` , ROUND (Sum(`Score`) / COUNT(`Score`)) FROM `US_Scores` GROUP BY `Player` ORDER BY (Sum(`Score`) / COUNT(`Score`))';
+ 2: Query := 'SELECT `Artist` , `Title` , `TimesPlayed` FROM `US_Songs` ORDER BY `TimesPlayed`';
+ 3: Query := 'SELECT `Artist` , Sum(`TimesPlayed`) FROM `US_Songs` GROUP BY `Artist` ORDER BY Sum(`TimesPlayed`)';
+ end;
+
+ //Add Order Direction
+ If Reversed then
+ Query := Query + ' ASC'
+ else
+ Query := Query + ' DESC';
+
+ //Add Limit
+ Query := Query + ' LIMIT ' + InttoStr(Count * Page) + ', ' + InttoStr(Count) + ';';
+
+ //Execute Query
+ //try
+ TableData := ScoreDB.GetTable(Query);
+ {except
+ exit;
+ end;}
+
+ //if Result empty -> Exit
+ if (TableData.RowCount < 1) then
+ exit;
+
+ //Copy Result to Stats Array
+ while not TableData.Eof do
+ begin
+ Stats[TableData.Row].Typ := Typ;
+
+ Case Typ of
+ 0:begin
+ Stats[TableData.Row].Singer := TableData.Fields[0];
+
+ Stats[TableData.Row].Difficulty := StrtoIntDef(TableData.Fields[1], 0);
+
+ Stats[TableData.Row].Score := StrtoIntDef(TableData.Fields[2], 0){TableData.FieldAsInteger(2)};
+ Stats[TableData.Row].SongArtist := TableData.Fields[3];
+ Stats[TableData.Row].SongTitle := TableData.Fields[4];
+ end;
+
+ 1:begin
+ Stats[TableData.Row].Player := TableData.Fields[0];
+ Stats[TableData.Row].AverageScore := StrtoIntDef(TableData.Fields[1], 0);
+ end;
+
+ 2:begin
+ Stats[TableData.Row].Artist := TableData.Fields[0];
+ Stats[TableData.Row].Title := TableData.Fields[1];
+ Stats[TableData.Row].TimesSung := StrtoIntDef(TableData.Fields[2], 0);
+ end;
+
+ 3:begin
+ Stats[TableData.Row].ArtistName := TableData.Fields[0];
+ Stats[TableData.Row].TimesSungtot := StrtoIntDef(TableData.Fields[1], 0);
+ end;
+
+ end;
+
+ TableData.Next;
+ end;
+
+ Result := True;
+end;
+
+//--------------------
+//GetTotalEntrys - Get Total Num of entrys for a Stats Query
+//--------------------
+Function TDataBaseSystem.GetTotalEntrys(const Typ: Byte): Cardinal;
+var Query: String;
+begin
+ //Create Query
+ Case Typ of
+ 0: Query := 'SELECT COUNT(`SongID`) FROM `US_Scores`;';
+ 1: Query := 'SELECT COUNT(DISTINCT `Player`) FROM `US_Scores`;';
+ 2: Query := 'SELECT COUNT(`ID`) FROM `US_Songs`;';
+ 3: Query := 'SELECT COUNT(DISTINCT `Artist`) FROM `US_Songs`;';
+ end;
+
+ Result := ScoreDB.GetTableValue(Query);
+end;
+
+end.
diff --git a/Game/Code/Classes/UDraw.pas b/Game/Code/Classes/UDraw.pas
index a28f1efc..ef1f2709 100644
--- a/Game/Code/Classes/UDraw.pas
+++ b/Game/Code/Classes/UDraw.pas
@@ -1,1562 +1,1583 @@
-unit UDraw;
-
-interface
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-uses UThemes,
- ModiSDK,
- UGraphicClasses;
-
-procedure SingDraw;
-procedure SingModiDraw (PlayerInfo: TPlayerInfo);
-procedure SingDrawBackground;
-procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer);
-procedure SingDrawNoteLines(Left, Top, Right: real; Space: integer);
-procedure SingDrawBeatDelimeters(Left, Top, Right: real; NrCzesci: integer);
-procedure SingDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer);
-procedure SingDrawPlayerCzesc(X, Y, W: real; NrGracza: integer; Space: integer);
-procedure SingDrawPlayerBGCzesc(Left, Top, Right: real; NrCzesci, NrGracza: integer; Space: integer);
-
-// TimeBar
-procedure SingDrawTimeBar();
-
-// The Singbar
-procedure SingDrawSingbar(X, Y, W, H: real; Percent: integer);
-
-//Phrasen Bonus - Line Bonus
-procedure SingDrawLineBonus( const X, Y: Single; Color: TRGB; Alpha: Single; Text: string; Age: Integer);
-
-//Draw Editor NoteLines
-procedure EditDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer);
-
-
-type
- TRecR = record
- Top: real;
- Left: real;
- Right: real;
- Bottom: real;
-
- Width: real;
- WMid: real;
- Height: real;
- HMid: real;
-
- Mid: real;
- end;
-
-var
- NotesW: real;
- NotesH: real;
- Starfr: integer;
- StarfrG: integer;
-
- //SingBar
- TickOld: cardinal;
- TickOld2:cardinal;
-
-const
- Przedz = 32;
-
-implementation
-
-uses Windows, OpenGL12, UGraphic, SysUtils, UMusic, URecord, ULog, UScreenSing, UScreenSingModi, ULyrics, UMain, TextGL, UTexture, UDrawTexture, UIni, Math, UDLLManager;
-
-procedure SingDrawBackground;
-var
- Rec: TRecR;
- TexRec: TRecR;
-begin
- if ScreenSing.Tex_Background.TexNum >= 1 then begin
-
- glClearColor (1, 1, 1, 1);
- glColor4f (1, 1, 1, 1);
-
- if (Ini.MovieSize <= 1) then //HalfSize BG
- begin
- (* half screen + gradient *)
- Rec.Top := 110; // 80
- Rec.Bottom := Rec.Top + 20;
- Rec.Left := 0;
- Rec.Right := 800;
-
- TexRec.Top := (Rec.Top / 600) * ScreenSing.Tex_Background.TexH;
- TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH;
- TexRec.Left := 0;
- TexRec.Right := ScreenSing.Tex_Background.TexW;
-
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, ScreenSing.Tex_Background.TexNum);
- glEnable(GL_BLEND);
- glBegin(GL_QUADS);
- (* gradient draw *)
- (* top *)
- glColor4f(1, 1, 1, 0);
- glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top);
- glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top);
- glColor4f(1, 1, 1, 1);
- glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom);
- (* mid *)
- Rec.Top := Rec.Bottom;
- Rec.Bottom := 490 - 20; // 490 - 20
- TexRec.Top := TexRec.Bottom;
- TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH;
- glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top);
- (* bottom *)
- Rec.Top := Rec.Bottom;
- Rec.Bottom := 490; // 490
- TexRec.Top := TexRec.Bottom;
- TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH;
- glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top);
- glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top);
- glColor4f(1, 1, 1, 0);
- glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom);
-
- glEnd;
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- end
- else //Full Size BG
- begin
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, ScreenSing.Tex_Background.TexNum);
- //glEnable(GL_BLEND);
- glBegin(GL_QUADS);
-
- glTexCoord2f(0, 0); glVertex2f(0, 0);
- glTexCoord2f(0, ScreenSing.Tex_Background.TexH); glVertex2f(0, 600);
- glTexCoord2f( ScreenSing.Tex_Background.TexW, ScreenSing.Tex_Background.TexH); glVertex2f(800, 600);
- glTexCoord2f( ScreenSing.Tex_Background.TexW, 0); glVertex2f(800, 0);
-
- glEnd;
- glDisable(GL_TEXTURE_2D);
- //glDisable(GL_BLEND);
- end;
- end;
-end;
-
-procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer);
-var
- Pet: integer;
-begin;
-// Log.LogStatus('Oscilloscope', 'SingDraw');
- glColor3f(Skin_OscR, Skin_OscG, Skin_OscB);
- {if (ParamStr(1) = '-black') or (ParamStr(1) = '-fsblack') then
- glColor3f(1, 1, 1); }
-
- glBegin(GL_LINE_STRIP);
- glVertex2f(X, -Sound[NrSound].BufferArray[1] / $10000 * H + Y + H/2);
- for Pet := 2 to Sound[NrSound].n div 1 do begin
- glVertex2f(X + (Pet-1) * W / (Sound[NrSound].n - 1),
- -Sound[NrSound].BufferArray[Pet] / $10000 * H + Y + H/2);
- end;
- glEnd;
-end;
-
-procedure SingDrawNoteLines(Left, Top, Right: real; Space: integer);
-var
- Pet: integer;
-begin
- glEnable(GL_BLEND);
- glColor4f(Skin_P1_LinesR, Skin_P1_LinesG, Skin_P1_LinesB, 0.4);
- glBegin(GL_LINES);
- for Pet := 0 to 9 do begin
- glVertex2f(Left, Top + Pet * Space);
- glVertex2f(Right, Top + Pet * Space);
- end;
- glEnd;
- glDisable(GL_BLEND);
-end;
-
-procedure SingDrawBeatDelimeters(Left, Top, Right: real; NrCzesci: integer);
-var
- Pet: integer;
- TempR: real;
-begin
- TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote);
- glEnable(GL_BLEND);
- glBegin(GL_LINES);
- for Pet := Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote to Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec do begin
- if (Pet mod Czesci[NrCzesci].Resolution) = Czesci[NrCzesci].NotesGAP then
- glColor4f(0, 0, 0, 1)
- else
- glColor4f(0, 0, 0, 0.3);
- glVertex2f(Left + TempR * (Pet - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote), Top);
- glVertex2f(Left + TempR * (Pet - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote), Top + 135);
- end;
- glEnd;
- glDisable(GL_BLEND);
-end;
-
-// draw blank Notebars
-procedure SingDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer);
-var
- Rec: TRecR;
- Pet: integer;
- TempR: real;
- R,G,B: real;
-
- PlayerNumber: Integer;
-
- GoldenStarPos : real;
-begin
-// We actually don't have a playernumber in this procedure, it should reside in NrCzesci - but it's always set to zero
-// So we exploit this behavior a bit - we give NrCzesci the playernumber, keep it in playernumber - and then we set NrCzesci to zero
-// This could also come quite in handy when we do the duet mode, cause just the notes for the player that has to sing should be drawn then
-// BUT this is not implemented yet, all notes are drawn! :D
-
- PlayerNumber := NrCzesci + 1; // Player 1 is 0
- NrCzesci := 0;
-
-// exploit done
-
- glColor3f(1, 1, 1);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote);
- with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt] do begin
- for Pet := 0 to HighNut do begin
- with Nuta[Pet] do begin
- if not FreeStyle then begin
-
-
- if Ini.EffectSing = 0 then
- // If Golden note Effect of then Change not Color
- begin
- case Wartosc of
- 1: glColor4f(1, 1, 1, 1); // We set alpha to 1, cause we can control the transparency through the png itself
- 2: glColor4f(1, 1, 0.3, 1); // no stars, paint yellow -> glColor4f(1, 1, 0.3, 0.85); - we could
- end; // case
- end //Else all Notes same Color
- else
- glColor4f(1, 1, 1, 1); // We set alpha to 1, cause we can control the transparency through the png itself
- // Czesci == teil, element == piece, element | koniec == ende, schluss
- // lewa czesc - left part
- Rec.Left := (Start-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left + 0.5 + 10*ScreenX;
- Rec.Right := Rec.Left + NotesW;
- Rec.Top := Top - (Ton-BaseNote)*Space/2 - NotesH;
- Rec.Bottom := Rec.Top + 2 * NotesH;
- glBindTexture(GL_TEXTURE_2D, Tex_plain_Left[PlayerNumber].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- //We keep the postion of the top left corner b4 it's overwritten
- GoldenStarPos := Rec.Left;
- //done
-
- // srodkowa czesc - middle part
- Rec.Left := Rec.Right;
- Rec.Right := (Start+Dlugosc-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left - NotesW - 0.5 + 10*ScreenX; // Dlugosc == länge
-
- glBindTexture(GL_TEXTURE_2D, Tex_plain_Mid[PlayerNumber].TexNum);
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(round((Rec.Right-Rec.Left)/32), 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(round((Rec.Right-Rec.Left)/32), 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- // prawa czesc - right part
- Rec.Left := Rec.Right;
- Rec.Right := Rec.Right + NotesW;
-
- glBindTexture(GL_TEXTURE_2D, Tex_plain_Right[PlayerNumber].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- // Golden Star Patch
- if (Wartosc = 2) AND (Ini.EffectSing=1) then
- begin
- GoldenRec.SaveGoldenStarsRec(GoldenStarPos, Rec.Top, Rec.Right, Rec.Bottom);
- end;
-
- end; // if not FreeStyle
- end; // with
- end; // for
- end; // with
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-end;
-
-
-// draw sung notes
-procedure SingDrawPlayerCzesc(X, Y, W: real; NrGracza: integer; Space: integer);
-var
- TempR: real;
- Rec: TRecR;
- N: integer;
- R: real;
- G: real;
- B: real;
- A: real;
- NotesH2: real;
- begin
-// Log.LogStatus('Player notes', 'SingDraw');
-
-// if NrGracza = 0 then LoadColor(R, G, B, 'P1Light')
-// else LoadColor(R, G, B, 'P2Light');
-
-// R := 71/255;
-// G := 175/255;
-// B := 247/255;
-
- glColor3f(1, 1, 1);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- if Player[NrGracza].IlNut > 0 then
- begin
- TempR := W / (Czesci[0].Czesc[Czesci[0].Akt].Koniec - Czesci[0].Czesc[Czesci[0].Akt].StartNote);
- for N := 0 to Player[NrGracza].HighNut do
- begin
- with Player[NrGracza].Nuta[N] do
- begin
- // Left part of note
- Rec.Left := X + (Start-Czesci[0].Czesc[Czesci[0].Akt].StartNote) * TempR + 0.5 + 10*ScreenX;
- Rec.Right := Rec.Left + NotesW;
-
- // Draw it in half size, if not hit
- if Hit then
- begin
- NotesH2 := NotesH
- end
- else
- begin
- NotesH2 := int(NotesH * 0.65);
- end;
-
- Rec.Top := Y - (Ton-Czesci[0].Czesc[Czesci[0].Akt].BaseNote)*Space/2 - NotesH2;
- Rec.Bottom := Rec.Top + 2 *NotesH2;
-
- // draw the left part
- glColor3f(1, 1, 1);
- glBindTexture(GL_TEXTURE_2D, Tex_Left[NrGracza+1].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- // Middle part of the note
- Rec.Left := Rec.Right;
- Rec.Right := X + (Start+Dlugosc-Czesci[0].Czesc[Czesci[0].Akt].StartNote) * TempR - NotesW - 0.5 + 10*ScreenX;
-
- // (nowe) - dunno
- if (Start+Dlugosc-1 = Czas.AktBeatD) then
- Rec.Right := Rec.Right - (1-Frac(Czas.MidBeatD)) * TempR;
- // the left note is more right than the right note itself, sounds weird - so we fix that xD
- if Rec.Right <= Rec.Left then Rec.Right := Rec.Left;
-
- // draw the middle part
- glBindTexture(GL_TEXTURE_2D, Tex_Mid[NrGracza+1].TexNum);
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(round((Rec.Right-Rec.Left)/32), 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(round((Rec.Right-Rec.Left)/32), 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
- glColor3f(1, 1, 1);
-
- // the right part of the note
- Rec.Left := Rec.Right;
- Rec.Right := Rec.Right + NotesW;
-
- glBindTexture(GL_TEXTURE_2D, Tex_Right[NrGracza+1].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- // Perfect note is stored
- if Perfect and (Ini.EffectSing=1) then
- begin
- A := 1 - 2*(Czas.Teraz - GetTimeFromBeat(Start+Dlugosc));
- if not (Start+Dlugosc-1 = Czas.AktBeatD) then
-
- //Star animation counter
- //inc(Starfr);
- //Starfr := Starfr mod 128;
- GoldenRec.SavePerfectNotePos(Rec.Left, Rec.Top);
- end;
- end; // with
- end; // for
- // eigentlich brauchen wir hier einen vergleich, um festzustellen, ob wir mit
- // singen schon weiter wären, als bei Rec.Right, _auch, wenn nicht gesungen wird_
-
- // passing on NrGracza... hope this is really something like the player-number, not only
- // some kind of weird index into a colour-table
-
- if (Ini.EffectSing=1) then
- GoldenRec.GoldenNoteTwinkle(Rec.Top,Rec.Bottom,Rec.Right, NrGracza);
- end; // if
-end;
-
-//draw Note glow
-procedure SingDrawPlayerBGCzesc(Left, Top, Right: real; NrCzesci, NrGracza: integer; Space: integer);
-var
- Rec: TRecR;
- Pet: integer;
- TempR: real;
- R,G,B: real;
- X1, X2, X3, X4: real;
- W, H: real;
-begin
- if (Player[NrGracza].ScoreTotalI >= 0) then begin
- glColor4f(1, 1, 1, sqrt((1+sin(Music.Position * 3))/4)/ 2 + 0.5 );
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote);
- with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt] do begin
- for Pet := 0 to HighNut do begin
- with Nuta[Pet] do begin
- if not FreeStyle then begin
- // begin: 14, 20
- // easy: 6, 11
- W := NotesW * 2 + 2;
- H := NotesH * 1.5 + 3.5;
-
- X2 := (Start-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left + 0.5 + 10*ScreenX + 4; // wciecie
- X1 := X2-W;
-
- X3 := (Start+Dlugosc-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left - 0.5 + 10*ScreenX - 4; // wciecie
- X4 := X3+W;
-
- // left
- Rec.Left := X1;
- Rec.Right := X2;
- Rec.Top := Top - (Ton-BaseNote)*Space/2 - H;
- Rec.Bottom := Rec.Top + 2 * H;
-
- glBindTexture(GL_TEXTURE_2D, Tex_BG_Left[NrGracza+1].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
-
- // srodkowa czesc
- Rec.Left := X2;
- Rec.Right := X3;
-
- glBindTexture(GL_TEXTURE_2D, Tex_BG_Mid[NrGracza+1].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- // prawa czesc
- Rec.Left := X3;
- Rec.Right := X4;
-
- glBindTexture(GL_TEXTURE_2D, Tex_BG_Right[NrGracza+1].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
- end; // if not FreeStyle
- end; // with
- end; // for
- end; // with
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- end;
-end;
-
-procedure SingDraw;
-var
- Pet: integer;
- Pet2: integer;
- TempR: real;
- Rec: TRecR;
- TexRec: TRecR;
- NR: TRecR;
- FS: real;
- BarFrom: integer;
- BarAlpha: real;
- BarWspol: real;
- TempCol: real;
- Tekst: string;
- LyricTemp: string;
- PetCz: integer;
-
- //SingBar Mod
- A: Integer;
- E: Integer;
- I: Integer;
- //end Singbar Mod
-
-begin
- // positions
- if Ini.SingWindow = 0 then begin
- NR.Left := 120;
- end else begin
- NR.Left := 20;
- end;
- NR.Right := 780;
-
- NR.Width := NR.Right - NR.Left;
- NR.WMid := NR.Width / 2;
- NR.Mid := NR.Left + NR.WMid;
-
- // background //BG Fullsize Mod
- //SingDrawBackground;
-
- //TimeBar mod
- SingDrawTimeBar();
- //eoa TimeBar mod
-
- // rysuje paski pod nutami
- if PlayersPlay = 1 then
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
- if (PlayersPlay = 2) or (PlayersPlay = 4) then begin
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P1_NotesB - 105, Nr.Right + 10*ScreenX, 15);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
- end;
-
- if (PlayersPlay = 3) or (PlayersPlay = 6) then begin
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 120, Nr.Right + 10*ScreenX, 12);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 245, Nr.Right + 10*ScreenX, 12);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 370, Nr.Right + 10*ScreenX, 12);
- end;
-
- // rysuje tekst - new Lyric engine
- ScreenSing.LyricMain.Draw;
- ScreenSing.LyricSub.Draw;
-
- // rysuje pasek, podpowiadajacy poczatek spiwania w scenie
- FS := 1.3;
- BarFrom := Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start;
- if BarFrom > 40 then BarFrom := 40;
- if (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start > 8) and // dluga przerwa //16->12 for more help bars and then 12->8 for even more
- (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat > 0) and // przed tekstem
- (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat < 40) then begin // ale nie za wczesnie
- BarWspol := (Czas.MidBeat - (Czesci[0].Czesc[Czesci[0].Akt].StartNote - BarFrom)) / BarFrom;
- Rec.Left := NR.Left + BarWspol *
-// (NR.WMid - Czesci[0].Czesc[Czesci[0].Akt].LyricWidth / 2 * FS - 50);
- (ScreenSing.LyricMain.ClientX - NR.Left - 50) + 10*ScreenX;
- Rec.Right := Rec.Left + 50;
- Rec.Top := Skin_LyricsT + 3;
- Rec.Bottom := Rec.Top + 33;//SingScreen.LyricMain.Size * 3;
-{ // zapalanie
- BarAlpha := (BarWspol*10) * 0.5;
- if BarAlpha > 0.5 then BarAlpha := 0.5;
-
- // gaszenie
- if BarWspol > 0.95 then BarAlpha := 0.5 * (1 - (BarWspol - 0.95) * 20);}
-
- //Change fuer Crazy Joker
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, Tex_Lyric_Help_Bar.TexNum);
- glBegin(GL_QUADS);
- glColor4f(1, 1, 1, 0);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glColor4f(1, 1, 1, 0.5);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
- glDisable(GL_BLEND);
-
- end;
-
- // oscilloscope
- if Ini.Oscilloscope = 1 then begin
- if PlayersPlay = 1 then
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
-
- if PlayersPlay = 2 then begin
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
- SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
- end;
-
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
- SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
- end;
- if ScreenAct = 2 then begin
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2);
- SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3);
- end;
- end;
-
- if PlayersPlay = 3 then begin
- SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0);
- SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
- SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0);
- SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
- SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
- end;
- if ScreenAct = 2 then begin
- SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3);
- SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4);
- SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5);
- end;
- end;
-
- end
-
- //SingBar Mod
- //modded again to make it moveable: it's working, so why try harder
- else if Ini.Oscilloscope = 2 then begin
- A := GetTickCount div 33;
- if A <> Tickold then begin
- Tickold := A;
- for E := 0 to (PlayersPlay - 1) do begin //Set new Pos + Alpha
- I := Player[E].ScorePercentTarget - Player[E].ScorePercent;
- if I > 0 then Inc(Player[E].ScorePercent)
- else if I < 0 then Dec(Player[E].ScorePercent);
- end; //for
- end; //if
-
- if PlayersPlay = 1 then begin
- SingDrawSingbar(Theme.Sing.StaticP1SingBar.x, Theme.Sing.StaticP1SingBar.y, Theme.Sing.StaticP1SingBar.w, Theme.Sing.StaticP1SingBar.h , Player[0].ScorePercent);
- end;
-
- if PlayersPlay = 2 then begin
- SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent);
- SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent);
- end;
-
- if PlayersPlay = 3 then begin
- SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent);
- SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent);
- SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent);
- end;
-
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent);
- SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent);
- end;
- if ScreenAct = 2 then begin
- SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[2].ScorePercent);
- SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[3].ScorePercent);
- end;
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent);
- SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent);
- SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent);
- end;
- if ScreenAct = 2 then begin
- SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[3].ScorePercent);
- SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[4].ScorePercent);
- SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[5].ScorePercent);
- end;
- end;
- end;
- //end Singbar Mod
-
- //PhrasenBonus - Line Bonus Mod
- if Ini.LineBonus > 0 then begin
- A := GetTickCount div 33;
- if (A <> Tickold2) AND (Player[0].LineBonus_Visible) then begin
- Tickold2 := A;
- for E := 0 to (PlayersPlay - 1) do begin
- //Change Alpha
- Player[E].LineBonus_Alpha := Player[E].LineBonus_Alpha - 0.02;
- if Player[E].LineBonus_Alpha <= 0 then
- begin
- Player[E].LineBonus_Age := 0;
- Player[E].LineBonus_Visible := False
- end
- else
- begin
- inc(Player[E].LineBonus_Age, 1);
- //Change Position
- if (Player[E].LineBonus_PosX < Player[E].LineBonus_TargetX) then
- Player[E].LineBonus_PosX := Player[E].LineBonus_PosX + (2 - Player[E].LineBonus_Alpha * 1.5)
- else if (Player[E].LineBonus_PosX > Player[E].LineBonus_TargetX) then
- Player[E].LineBonus_PosX := Player[E].LineBonus_PosX - (2 - Player[E].LineBonus_Alpha * 1.5);
-
- if (Player[E].LineBonus_PosY < Player[E].LineBonus_TargetY) then
- Player[E].LineBonus_PosY := Player[E].LineBonus_PosY + (2 - Player[E].LineBonus_Alpha * 1.5)
- else if (Player[E].LineBonus_PosY > Player[E].LineBonus_TargetY) then
- Player[E].LineBonus_PosY := Player[E].LineBonus_PosY - (2 - Player[E].LineBonus_Alpha * 1.5);
-
- end; // shift position of the pop up (if not dead)
- end; // loop - for all players
- end; // if - linebonus
-
-
- if PlayersPlay = 1 then begin
- SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
- end
-
- else if PlayersPlay = 2 then begin
- SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
- SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
- end
-
- else if PlayersPlay = 3 then begin
- SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
- SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
- SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age);
- end
-
- else if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
- SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
- end;
- if ScreenAct = 2 then begin
- SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age);
- SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age);
- end;
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
- SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
- SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age);
- end;
- if ScreenAct = 2 then begin
- SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age);
- SingDrawLineBonus( Player[4].LineBonus_PosX, Player[4].LineBonus_PosY, Player[4].LineBonus_Color, Player[4].LineBonus_Alpha, Player[4].LineBonus_Text, Player[4].LineBonus_Age);
- SingDrawLineBonus( Player[5].LineBonus_PosX, Player[5].LineBonus_PosY, Player[5].LineBonus_Color, Player[5].LineBonus_Alpha, Player[5].LineBonus_Text, Player[5].LineBonus_Age);
- end;
- end;
- end;
- //PhrasenBonus - Line Bonus Mod End
-
-// Set the note heights according to the difficulty level
- case Ini.Difficulty of
- 0:
- begin
- NotesH := 11; // 9
- NotesW := 6; // 5
- end;
- 1:
- begin
- NotesH := 8; // 7
- NotesW := 4; // 4
- end;
- 2:
- begin
- NotesH := 5;
- NotesW := 3;
- end;
- end;
-
-// Draw the Notes
- if PlayersPlay = 1 then begin
- SingDrawPlayerBGCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 0, 15); // Background glow - colorized in playercolor
- SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15); // Plain unsung notes - colorized in playercolor
- SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 15); // imho the sung notes
- end;
-
- if (PlayersPlay = 2) then begin
- SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
- SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
-
- SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
- SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 1, 15);
-
- SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
- SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
- end;
-
- if PlayersPlay = 3 then begin
- NotesW := NotesW * 0.8;
- NotesH := NotesH * 0.8;
-
- SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
- SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
- SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
-
- SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
- SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 1, 12);
- SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 2, 12);
-
- SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
- SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
- SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
- end;
-
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
- SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 2, 15);
- SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 3, 15);
- end;
-
- if ScreenAct = 1 then begin
- SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
- SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 1, 15);
- end;
- if ScreenAct = 2 then begin
- SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 2, 15);
- SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 3, 15);
- end;
-
- if ScreenAct = 1 then begin
- SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
- SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 2, 15);
- SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 3, 15);
- end;
- end;
-
- if PlayersPlay = 6 then begin
- NotesW := NotesW * 0.8;
- NotesH := NotesH * 0.8;
-
- if ScreenAct = 1 then begin
- SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
- SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
- SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 3, 12);
- SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 4, 12);
- SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 5, 12);
- end;
-
- if ScreenAct = 1 then begin
- SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
- SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 1, 12);
- SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 2, 12);
- end;
- if ScreenAct = 2 then begin
- SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 3, 12);
- SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 4, 12);
- SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 5, 12);
- end;
-
- if ScreenAct = 1 then begin
- SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
- SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
- SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 3, 12);
- SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 4, 12);
- SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 5, 12);
- end;
- end;
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-end;
-
-// q'n'd for using the game mode dll's
-procedure SingModiDraw (PlayerInfo: TPlayerInfo);
-var
- Pet: integer;
- Pet2: integer;
- TempR: real;
- Rec: TRecR;
- TexRec: TRecR;
- NR: TRecR;
- FS: real;
- BarFrom: integer;
- BarAlpha: real;
- BarWspol: real;
- TempCol: real;
- Tekst: string;
- LyricTemp: string;
- PetCz: integer;
-
- //SingBar Mod
- A: Integer;
- E: Integer;
- I: Integer;
- //end Singbar Mod
-
-begin
- // positions
- if Ini.SingWindow = 0 then begin
- NR.Left := 120;
- end else begin
- NR.Left := 20;
- end;
-
- NR.Right := 780;
- NR.Width := NR.Right - NR.Left;
- NR.WMid := NR.Width / 2;
- NR.Mid := NR.Left + NR.WMid;
-
- // time bar
- SingDrawTimeBar();
-
- if DLLMan.Selected.ShowNotes then
- begin
- if PlayersPlay = 1 then
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
- if (PlayersPlay = 2) or (PlayersPlay = 4) then begin
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P1_NotesB - 105, Nr.Right + 10*ScreenX, 15);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
- end;
-
- if (PlayersPlay = 3) or (PlayersPlay = 6) then begin
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 120, Nr.Right + 10*ScreenX, 12);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 245, Nr.Right + 10*ScreenX, 12);
- SingDrawNoteLines(Nr.Left + 10*ScreenX, 370, Nr.Right + 10*ScreenX, 12);
- end;
- end;
-
- // Lyric engine
- ScreenSingModi.LyricMain.Draw;
- ScreenSingModi.LyricSub.Draw;
-
- // rysuje pasek, podpowiadajacy poczatek spiwania w scenie
- FS := 1.3;
- BarFrom := Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start;
- if BarFrom > 40 then BarFrom := 40;
- if (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start > 8) and // dluga przerwa //16->12 for more help bars and then 12->8 for even more
- (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat > 0) and // przed tekstem
- (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat < 40) then begin // ale nie za wczesnie
- BarWspol := (Czas.MidBeat - (Czesci[0].Czesc[Czesci[0].Akt].StartNote - BarFrom)) / BarFrom;
- Rec.Left := NR.Left + BarWspol * (ScreenSingModi.LyricMain.ClientX - NR.Left - 50) + 10*ScreenX;
- Rec.Right := Rec.Left + 50;
- Rec.Top := Skin_LyricsT + 3;
- Rec.Bottom := Rec.Top + 33;//SingScreen.LyricMain.Size * 3;
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, Tex_Lyric_Help_Bar.TexNum);
- glBegin(GL_QUADS);
- glColor4f(1, 1, 1, 0);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glColor4f(1, 1, 1, 0.5);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
- glDisable(GL_BLEND);
- end;
-
- // oscilloscope | the thing that moves when you yell into your mic (imho)
- if (((Ini.Oscilloscope = 1) AND (DLLMan.Selected.ShowRateBar_O)) AND (NOT DLLMan.Selected.ShowRateBar)) then begin
- if PlayersPlay = 1 then
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
-
- if PlayersPlay = 2 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
- end;
-
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
- end;
- if ScreenAct = 2 then begin
- if PlayerInfo.Playerinfo[2].Enabled then
- SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2);
- if PlayerInfo.Playerinfo[3].Enabled then
- SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3);
- end;
- end;
-
- if PlayersPlay = 3 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
- if PlayerInfo.Playerinfo[2].Enabled then
- SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
- if PlayerInfo.Playerinfo[2].Enabled then
- SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
- end;
- if ScreenAct = 2 then begin
- if PlayerInfo.Playerinfo[3].Enabled then
- SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3);
- if PlayerInfo.Playerinfo[4].Enabled then
- SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4);
- if PlayerInfo.Playerinfo[5].Enabled then
- SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5);
- end;
- end;
-
- end
-
- //SingBar Mod
- // seems like we don't want the flicker thing, we want the linebonus rating bar beneath the scores
- else if ((Ini.Oscilloscope = 2) AND (DLLMan.Selected.ShowRateBar_O)) OR (DLLMan.Selected.ShowRateBar) then begin
- A := GetTickCount div 33;
- if A <> Tickold then begin
- Tickold := A;
- for E := 0 to (PlayersPlay - 1) do begin //Set new Pos + Alpha
- I := Player[E].ScorePercentTarget - Player[E].ScorePercent;
- if I > 0 then Inc(Player[E].ScorePercent)
- else if I < 0 then Dec(Player[E].ScorePercent);
- end; //for
- end; //if
-
- if PlayersPlay = 1 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP1SingBar.x, Theme.Sing.StaticP1SingBar.y, Theme.Sing.StaticP1SingBar.w, Theme.Sing.StaticP1SingBar.h , Player[0].ScorePercent);
- end;
-
- if PlayersPlay = 2 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent);
- end;
-
- if PlayersPlay = 3 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent);
- if PlayerInfo.Playerinfo[2].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent);
- end;
-
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent);
- end;
- if ScreenAct = 2 then begin
- if PlayerInfo.Playerinfo[2].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[2].ScorePercent);
- if PlayerInfo.Playerinfo[3].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[3].ScorePercent);
- end;
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent);
- if PlayerInfo.Playerinfo[2].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent);
- end;
- if ScreenAct = 2 then begin
- if PlayerInfo.Playerinfo[3].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[3].ScorePercent);
- if PlayerInfo.Playerinfo[4].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[4].ScorePercent);
- if PlayerInfo.Playerinfo[5].Enabled then
- SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[5].ScorePercent);
- end;
- end;
- end;
- //end Singbar Mod
-
- //PhrasenBonus - Line Bonus Mod
- if ((Ini.LineBonus > 0) AND (DLLMan.Selected.EnLineBonus_O)) OR (DLLMan.Selected.EnLineBonus) then begin
- A := GetTickCount div 33;
- if (A <> Tickold2) AND (Player[0].LineBonus_Visible) then begin
- Tickold2 := A;
- for E := 0 to (PlayersPlay - 1) do begin
- //Change Alpha
- Player[E].LineBonus_Alpha := Player[E].LineBonus_Alpha - 0.02;
-
- if Player[E].LineBonus_Alpha <= 0 then
- begin
- Player[E].LineBonus_Age := 0;
- Player[E].LineBonus_Visible := False
- end
- else
- begin
- inc(Player[E].LineBonus_Age, 1);
- //Change Position
- if (Player[E].LineBonus_PosX < Player[E].LineBonus_TargetX) then // pop up has not yet reached it's position -> blend in
- Player[E].LineBonus_PosX := Player[E].LineBonus_PosX + (2 - Player[E].LineBonus_Alpha * 1.5)
- else if (Player[E].LineBonus_PosX > Player[E].LineBonus_TargetX) then // pop up has reached it's position -> blend out
- Player[E].LineBonus_PosX := Player[E].LineBonus_PosX - (2 - Player[E].LineBonus_Alpha * 1.5);
-
- if (Player[E].LineBonus_PosY < Player[E].LineBonus_TargetY) then
- Player[E].LineBonus_PosY := Player[E].LineBonus_PosY + (2 - Player[E].LineBonus_Alpha * 1.5)
- else if (Player[E].LineBonus_PosY > Player[E].LineBonus_TargetY) then
- Player[E].LineBonus_PosY := Player[E].LineBonus_PosY - (2 - Player[E].LineBonus_Alpha * 1.5);
-
- end; // pop up still visible, has not reached it's position - move it
- end; // loop through all players
- end; // if it's time to draw them
-
- if PlayersPlay = 1 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
- end
-
- else if PlayersPlay = 2 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
- end
-
- else if PlayersPlay = 3 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
- if PlayerInfo.Playerinfo[2].Enabled then
- SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age);
- end
-
- else if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
- end;
- if ScreenAct = 2 then begin
- if PlayerInfo.Playerinfo[2].Enabled then
- SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age);
- if PlayerInfo.Playerinfo[3].Enabled then
- SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age);
- end;
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
- if PlayerInfo.Playerinfo[1].Enabled then
- SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
- if PlayerInfo.Playerinfo[2].Enabled then
- SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age);
- end;
- if ScreenAct = 2 then begin
- if PlayerInfo.Playerinfo[3].Enabled then
- SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age);
- if PlayerInfo.Playerinfo[4].Enabled then
- SingDrawLineBonus( Player[4].LineBonus_PosX, Player[4].LineBonus_PosY, Player[4].LineBonus_Color, Player[4].LineBonus_Alpha, Player[4].LineBonus_Text, Player[4].LineBonus_Age);
- if PlayerInfo.Playerinfo[5].Enabled then
- SingDrawLineBonus( Player[5].LineBonus_PosX, Player[5].LineBonus_PosY, Player[5].LineBonus_Color, Player[5].LineBonus_Alpha, Player[5].LineBonus_Text, Player[5].LineBonus_Age);
- end;
- end;
- end;
-//PhrasenBonus - Line Bonus Mod End
-
-// resize the notes according to the difficulty level
- case Ini.Difficulty of
- 0:
- begin
- NotesH := 11; // 9
- NotesW := 6; // 5
- end;
- 1:
- begin
- NotesH := 8; // 7
- NotesW := 4; // 4
- end;
- 2:
- begin
- NotesH := 5;
- NotesW := 3;
- end;
- end;
-
- if (DLLMAn.Selected.ShowNotes And DLLMan.Selected.LoadSong) then
- begin
- if (PlayersPlay = 1) And PlayerInfo.Playerinfo[0].Enabled then begin
- SingDrawPlayerBGCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 0, 15);
- SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
- SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 15);
- end;
-
- if (PlayersPlay = 2) then begin
- if PlayerInfo.Playerinfo[0].Enabled then
- begin
- SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
- SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
- SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
- end;
- if PlayerInfo.Playerinfo[1].Enabled then
- begin
- SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
- SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
- SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
- end;
-
- end;
-
- if PlayersPlay = 3 then begin
- NotesW := NotesW * 0.8;
- NotesH := NotesH * 0.8;
-
- if PlayerInfo.Playerinfo[0].Enabled then
- begin
- SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
- SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
- SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
- end;
-
- if PlayerInfo.Playerinfo[1].Enabled then
- begin
- SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
- SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 0, 12);
- SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
- end;
-
- if PlayerInfo.Playerinfo[2].Enabled then
- begin
- SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
- SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 0, 12);
- SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
- end;
- end;
-
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
- SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 2, 15);
- SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 3, 15);
- end;
-
- SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
- SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
-
- if ScreenAct = 1 then begin
- SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
- SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 2, 15);
- SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 3, 15);
- end;
- end;
-
- if PlayersPlay = 6 then begin
- NotesW := NotesW * 0.8;
- NotesH := NotesH * 0.8;
-
- if ScreenAct = 1 then begin
- SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
- SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
- SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 3, 12);
- SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 4, 12);
- SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 5, 12);
- end;
-
- SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
- SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 0, 12);
- SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 0, 12);
-
- if ScreenAct = 1 then begin
- SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
- SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
- SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
- end;
- if ScreenAct = 2 then begin
- SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 3, 12);
- SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 4, 12);
- SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 5, 12);
- end;
- end;
- end;
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-end;
-
-
-//SingBar Mod
-procedure SingDrawSingbar(X, Y, W, H: real; Percent: integer);
-var
- R: Real;
- G: Real;
- B: Real;
- A: cardinal;
- I: Integer;
-
-begin;
-
- //SingBar Background
- glColor4f(1, 1, 1, 0.8);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Back.TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(X, Y);
- glTexCoord2f(0, 1); glVertex2f(X, Y+H);
- glTexCoord2f(1, 1); glVertex2f(X+W, Y+H);
- glTexCoord2f(1, 0); glVertex2f(X+W, Y);
- glEnd;
-
- //SingBar coloured Bar
- Case Percent of
- 0..22: begin
- R := 1;
- G := 0;
- B := 0;
- end;
- 23..42: begin
- R := 1;
- G := ((Percent-23)/100)*5;
- B := 0;
- end;
- 43..57: begin
- R := 1;
- G := 1;
- B := 0;
- end;
- 58..77: begin
- R := 1-(Percent - 58)/100*5;
- G := 1;
- B := 0;
- end;
- 78..99: begin
- R := 0;
- G := 1;
- B := 0;
- end;
- End; //Case
-
- glColor4f(R, G, B, 1);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Bar.TexNum);
- //Size= Player[PlayerNum].ScorePercent of W
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(X, Y);
- glTexCoord2f(0, 1); glVertex2f(X, Y+H);
- glTexCoord2f(1, 1); glVertex2f(X+(W/100 * (Percent +1)), Y+H);
- glTexCoord2f(1, 0); glVertex2f(X+(W/100 * (Percent +1)), Y);
- glEnd;
-
- //SingBar Front
- glColor4f(1, 1, 1, 0.6);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Front.TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(X, Y);
- glTexCoord2f(0, 1); glVertex2f(X, Y+H);
- glTexCoord2f(1, 1); glVertex2f(X+W, Y+H);
- glTexCoord2f(1, 0); glVertex2f(X+W, Y);
- glEnd;
-end;
-//end Singbar Mod
-
-//PhrasenBonus - Line Bonus Pop Up
-procedure SingDrawLineBonus( const X, Y: Single; Color: TRGB; Alpha: Single; Text: string; Age: Integer);
-var
-Length, X2: Real; //Length of Text
-Size: Integer; //Size of Popup
-begin
-if Alpha <> 0 then
-begin
-
-//Set Font Propertys
-SetFontStyle(2); //Font: Outlined1
-if Age < 5 then SetFontSize(Age + 1) else SetFontSize(6);
-SetFontItalic(False);
-
-//Check Font Size
-Length := glTextWidth ( PChar(Text)) + 3; //Little Space for a Better Look ^^
-
-//Text
-SetFontPos (X + 50 - (Length / 2), Y + 12); //Position
-
-
-if Age < 5 then Size := Age * 10 else Size := 50;
-
- //Draw Background
- //glColor4f(Color.R, Color.G, Color.B, Alpha); //Set Color
- glColor4f(1, 1, 1, Alpha);
-
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
-
- //New Method, Not Variable
- glBindTexture(GL_TEXTURE_2D, Tex_SingLineBonusBack[2].TexNum);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(X + 50 - Size, Y + 25 - (Size/2));
- glTexCoord2f(0, 1); glVertex2f(X + 50 - Size, Y + 25 + (Size/2));
- glTexCoord2f(1, 1); glVertex2f(X + 50 + Size, Y + 25 + (Size/2));
- glTexCoord2f(1, 0); glVertex2f(X + 50 + Size, Y + 25 - (Size/2));
- glEnd;
-
- glColor4f(1, 1, 1, Alpha); //Set Color
- //Draw Text
- glPrint (PChar(Text));
-end;
-end;
-//PhrasenBonus - Line Bonus Mod
-
-// Draw Note Bars for Editor
-//There are 11 Resons for a new Procdedure:
-// 1. It don't look good when you Draw the Golden Note Star Effect in the Editor
-// 2. You can see the Freestyle Notes in the Editor SemiTransparent
-// 3. Its easier and Faster then changing the old Procedure
-procedure EditDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer);
-var
- Rec: TRecR;
- Pet: integer;
- TempR: real;
-begin
- glColor3f(1, 1, 1);
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote);
- with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt] do begin
- for Pet := 0 to HighNut do begin
- with Nuta[Pet] do begin
-
- // Golden Note Patch
- case Wartosc of
- 0: glColor4f(1, 1, 1, 0.35);
- 1: glColor4f(1, 1, 1, 0.85);
- 2: glColor4f(1, 1, 0.3, 0.85);
- end; // case
-
-
-
- // lewa czesc - left part
- Rec.Left := (Start-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left + 0.5 + 10*ScreenX;
- Rec.Right := Rec.Left + NotesW;
- Rec.Top := Top - (Ton-BaseNote)*Space/2 - NotesH;
- Rec.Bottom := Rec.Top + 2 * NotesH;
- glBindTexture(GL_TEXTURE_2D, Tex_Left[Color].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- // srodkowa czesc - middle part
- Rec.Left := Rec.Right;
- Rec.Right := (Start+Dlugosc-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left - NotesW - 0.5 + 10*ScreenX;
-
- glBindTexture(GL_TEXTURE_2D, Tex_Mid[Color].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- // prawa czesc - right part
- Rec.Left := Rec.Right;
- Rec.Right := Rec.Right + NotesW;
-
- glBindTexture(GL_TEXTURE_2D, Tex_Right[Color].TexNum);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
- glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
- glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
- glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
- glEnd;
-
- end; // with
- end; // for
- end; // with
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-end;
-
-procedure SingDrawTimeBar();
-var x,y: real;
- width, height: real;
-begin
- x := Theme.Sing.StaticTimeProgress.x;
- y := Theme.Sing.StaticTimeProgress.y;
- width:= Theme.Sing.StaticTimeProgress.w;
- height:= Theme.Sing.StaticTimeProgress.h;
-
- glColor4f(Theme.Sing.StaticTimeProgress.ColR,
- Theme.Sing.StaticTimeProgress.ColG,
- Theme.Sing.StaticTimeProgress.ColB, 1); //Set Color
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
-
- glBindTexture(GL_TEXTURE_2D, Tex_TimeProgress.TexNum);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(x,y);
- glTexCoord2f((width*(Czas.Teraz/Czas.Razem))/8, 0); glVertex2f(x+width*(Czas.Teraz/Czas.Razem), y);
- glTexCoord2f((width*(Czas.Teraz/Czas.Razem))/8, 1); glVertex2f(x+width*(Czas.Teraz/Czas.Razem), y+height);
- glTexCoord2f(0, 1); glVertex2f(x, y+height);
- glEnd;
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
- glcolor4f(1,1,1,1);
-end;
-
-end.
-
+unit UDraw;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+{$ENDIF}
+
+uses UThemes,
+ ModiSDK,
+ UGraphicClasses;
+
+procedure SingDraw;
+procedure SingModiDraw (PlayerInfo: TPlayerInfo);
+procedure SingDrawBackground;
+procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer);
+procedure SingDrawNoteLines(Left, Top, Right: real; Space: integer);
+procedure SingDrawBeatDelimeters(Left, Top, Right: real; NrCzesci: integer);
+procedure SingDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer);
+procedure SingDrawPlayerCzesc(X, Y, W: real; NrGracza: integer; Space: integer);
+procedure SingDrawPlayerBGCzesc(Left, Top, Right: real; NrCzesci, NrGracza: integer; Space: integer);
+
+// TimeBar
+procedure SingDrawTimeBar();
+
+// The Singbar
+procedure SingDrawSingbar(X, Y, W, H: real; Percent: integer);
+
+//Phrasen Bonus - Line Bonus
+procedure SingDrawLineBonus( const X, Y: Single; Color: TRGB; Alpha: Single; Text: string; Age: Integer);
+
+//Draw Editor NoteLines
+procedure EditDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer);
+
+
+type
+ TRecR = record
+ Top: real;
+ Left: real;
+ Right: real;
+ Bottom: real;
+
+ Width: real;
+ WMid: real;
+ Height: real;
+ HMid: real;
+
+ Mid: real;
+ end;
+
+var
+ NotesW: real;
+ NotesH: real;
+ Starfr: integer;
+ StarfrG: integer;
+
+ //SingBar
+ TickOld: cardinal;
+ TickOld2:cardinal;
+
+const
+ Przedz = 32;
+
+implementation
+
+uses {$IFDEF Win32}
+ windows,
+ {$ELSE}
+ lclintf,
+ {$ENDIF}
+ OpenGL12,
+ UGraphic,
+ SysUtils,
+ UMusic,
+ URecord,
+ ULog,
+ UScreenSing,
+ UScreenSingModi,
+ ULyrics,
+ UMain,
+ TextGL,
+ UTexture,
+ UDrawTexture,
+ UIni,
+ Math,
+ UDLLManager;
+
+procedure SingDrawBackground;
+var
+ Rec: TRecR;
+ TexRec: TRecR;
+begin
+ if ScreenSing.Tex_Background.TexNum >= 1 then begin
+
+ glClearColor (1, 1, 1, 1);
+ glColor4f (1, 1, 1, 1);
+
+ if (Ini.MovieSize <= 1) then //HalfSize BG
+ begin
+ (* half screen + gradient *)
+ Rec.Top := 110; // 80
+ Rec.Bottom := Rec.Top + 20;
+ Rec.Left := 0;
+ Rec.Right := 800;
+
+ TexRec.Top := (Rec.Top / 600) * ScreenSing.Tex_Background.TexH;
+ TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH;
+ TexRec.Left := 0;
+ TexRec.Right := ScreenSing.Tex_Background.TexW;
+
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, ScreenSing.Tex_Background.TexNum);
+ glEnable(GL_BLEND);
+ glBegin(GL_QUADS);
+ (* gradient draw *)
+ (* top *)
+ glColor4f(1, 1, 1, 0);
+ glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top);
+ glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top);
+ glColor4f(1, 1, 1, 1);
+ glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom);
+ (* mid *)
+ Rec.Top := Rec.Bottom;
+ Rec.Bottom := 490 - 20; // 490 - 20
+ TexRec.Top := TexRec.Bottom;
+ TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH;
+ glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top);
+ (* bottom *)
+ Rec.Top := Rec.Bottom;
+ Rec.Bottom := 490; // 490
+ TexRec.Top := TexRec.Bottom;
+ TexRec.Bottom := (Rec.Bottom / 600) * ScreenSing.Tex_Background.TexH;
+ glTexCoord2f(TexRec.Right, TexRec.Top); glVertex2f(Rec.Right, Rec.Top);
+ glTexCoord2f(TexRec.Left, TexRec.Top); glVertex2f(Rec.Left, Rec.Top);
+ glColor4f(1, 1, 1, 0);
+ glTexCoord2f(TexRec.Left, TexRec.Bottom); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(TexRec.Right, TexRec.Bottom); glVertex2f(Rec.Right, Rec.Bottom);
+
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+ end
+ else //Full Size BG
+ begin
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, ScreenSing.Tex_Background.TexNum);
+ //glEnable(GL_BLEND);
+ glBegin(GL_QUADS);
+
+ glTexCoord2f(0, 0); glVertex2f(0, 0);
+ glTexCoord2f(0, ScreenSing.Tex_Background.TexH); glVertex2f(0, 600);
+ glTexCoord2f( ScreenSing.Tex_Background.TexW, ScreenSing.Tex_Background.TexH); glVertex2f(800, 600);
+ glTexCoord2f( ScreenSing.Tex_Background.TexW, 0); glVertex2f(800, 0);
+
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+ //glDisable(GL_BLEND);
+ end;
+ end;
+end;
+
+procedure SingDrawOscilloscope(X, Y, W, H: real; NrSound: integer);
+var
+ Pet: integer;
+begin;
+// Log.LogStatus('Oscilloscope', 'SingDraw');
+ glColor3f(Skin_OscR, Skin_OscG, Skin_OscB);
+ {if (ParamStr(1) = '-black') or (ParamStr(1) = '-fsblack') then
+ glColor3f(1, 1, 1); }
+
+ glBegin(GL_LINE_STRIP);
+ glVertex2f(X, -Sound[NrSound].BufferArray[1] / $10000 * H + Y + H/2);
+ for Pet := 2 to Sound[NrSound].n div 1 do begin
+ glVertex2f(X + (Pet-1) * W / (Sound[NrSound].n - 1),
+ -Sound[NrSound].BufferArray[Pet] / $10000 * H + Y + H/2);
+ end;
+ glEnd;
+end;
+
+procedure SingDrawNoteLines(Left, Top, Right: real; Space: integer);
+var
+ Pet: integer;
+begin
+ glEnable(GL_BLEND);
+ glColor4f(Skin_P1_LinesR, Skin_P1_LinesG, Skin_P1_LinesB, 0.4);
+ glBegin(GL_LINES);
+ for Pet := 0 to 9 do begin
+ glVertex2f(Left, Top + Pet * Space);
+ glVertex2f(Right, Top + Pet * Space);
+ end;
+ glEnd;
+ glDisable(GL_BLEND);
+end;
+
+procedure SingDrawBeatDelimeters(Left, Top, Right: real; NrCzesci: integer);
+var
+ Pet: integer;
+ TempR: real;
+begin
+ TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote);
+ glEnable(GL_BLEND);
+ glBegin(GL_LINES);
+ for Pet := Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote to Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec do begin
+ if (Pet mod Czesci[NrCzesci].Resolution) = Czesci[NrCzesci].NotesGAP then
+ glColor4f(0, 0, 0, 1)
+ else
+ glColor4f(0, 0, 0, 0.3);
+ glVertex2f(Left + TempR * (Pet - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote), Top);
+ glVertex2f(Left + TempR * (Pet - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote), Top + 135);
+ end;
+ glEnd;
+ glDisable(GL_BLEND);
+end;
+
+// draw blank Notebars
+procedure SingDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer);
+var
+ Rec: TRecR;
+ Pet: integer;
+ TempR: real;
+ R,G,B: real;
+
+ PlayerNumber: Integer;
+
+ GoldenStarPos : real;
+begin
+// We actually don't have a playernumber in this procedure, it should reside in NrCzesci - but it's always set to zero
+// So we exploit this behavior a bit - we give NrCzesci the playernumber, keep it in playernumber - and then we set NrCzesci to zero
+// This could also come quite in handy when we do the duet mode, cause just the notes for the player that has to sing should be drawn then
+// BUT this is not implemented yet, all notes are drawn! :D
+
+ PlayerNumber := NrCzesci + 1; // Player 1 is 0
+ NrCzesci := 0;
+
+// exploit done
+
+ glColor3f(1, 1, 1);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote);
+ with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt] do begin
+ for Pet := 0 to HighNut do begin
+ with Nuta[Pet] do begin
+ if not FreeStyle then begin
+
+
+ if Ini.EffectSing = 0 then
+ // If Golden note Effect of then Change not Color
+ begin
+ case Wartosc of
+ 1: glColor4f(1, 1, 1, 1); // We set alpha to 1, cause we can control the transparency through the png itself
+ 2: glColor4f(1, 1, 0.3, 1); // no stars, paint yellow -> glColor4f(1, 1, 0.3, 0.85); - we could
+ end; // case
+ end //Else all Notes same Color
+ else
+ glColor4f(1, 1, 1, 1); // We set alpha to 1, cause we can control the transparency through the png itself
+ // Czesci == teil, element == piece, element | koniec == ende, schluss
+ // lewa czesc - left part
+ Rec.Left := (Start-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left + 0.5 + 10*ScreenX;
+ Rec.Right := Rec.Left + NotesW;
+ Rec.Top := Top - (Ton-BaseNote)*Space/2 - NotesH;
+ Rec.Bottom := Rec.Top + 2 * NotesH;
+ glBindTexture(GL_TEXTURE_2D, Tex_plain_Left[PlayerNumber].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ //We keep the postion of the top left corner b4 it's overwritten
+ GoldenStarPos := Rec.Left;
+ //done
+
+ // srodkowa czesc - middle part
+ Rec.Left := Rec.Right;
+ Rec.Right := (Start+Dlugosc-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left - NotesW - 0.5 + 10*ScreenX; // Dlugosc == länge
+
+ glBindTexture(GL_TEXTURE_2D, Tex_plain_Mid[PlayerNumber].TexNum);
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(round((Rec.Right-Rec.Left)/32), 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(round((Rec.Right-Rec.Left)/32), 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // prawa czesc - right part
+ Rec.Left := Rec.Right;
+ Rec.Right := Rec.Right + NotesW;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_plain_Right[PlayerNumber].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // Golden Star Patch
+ if (Wartosc = 2) AND (Ini.EffectSing=1) then
+ begin
+ GoldenRec.SaveGoldenStarsRec(GoldenStarPos, Rec.Top, Rec.Right, Rec.Bottom);
+ end;
+
+ end; // if not FreeStyle
+ end; // with
+ end; // for
+ end; // with
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+end;
+
+
+// draw sung notes
+procedure SingDrawPlayerCzesc(X, Y, W: real; NrGracza: integer; Space: integer);
+var
+ TempR: real;
+ Rec: TRecR;
+ N: integer;
+ R: real;
+ G: real;
+ B: real;
+ A: real;
+ NotesH2: real;
+ begin
+// Log.LogStatus('Player notes', 'SingDraw');
+
+// if NrGracza = 0 then LoadColor(R, G, B, 'P1Light')
+// else LoadColor(R, G, B, 'P2Light');
+
+// R := 71/255;
+// G := 175/255;
+// B := 247/255;
+
+ glColor3f(1, 1, 1);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ if Player[NrGracza].IlNut > 0 then
+ begin
+ TempR := W / (Czesci[0].Czesc[Czesci[0].Akt].Koniec - Czesci[0].Czesc[Czesci[0].Akt].StartNote);
+ for N := 0 to Player[NrGracza].HighNut do
+ begin
+ with Player[NrGracza].Nuta[N] do
+ begin
+ // Left part of note
+ Rec.Left := X + (Start-Czesci[0].Czesc[Czesci[0].Akt].StartNote) * TempR + 0.5 + 10*ScreenX;
+ Rec.Right := Rec.Left + NotesW;
+
+ // Draw it in half size, if not hit
+ if Hit then
+ begin
+ NotesH2 := NotesH
+ end
+ else
+ begin
+ NotesH2 := int(NotesH * 0.65);
+ end;
+
+ Rec.Top := Y - (Ton-Czesci[0].Czesc[Czesci[0].Akt].BaseNote)*Space/2 - NotesH2;
+ Rec.Bottom := Rec.Top + 2 *NotesH2;
+
+ // draw the left part
+ glColor3f(1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, Tex_Left[NrGracza+1].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // Middle part of the note
+ Rec.Left := Rec.Right;
+ Rec.Right := X + (Start+Dlugosc-Czesci[0].Czesc[Czesci[0].Akt].StartNote) * TempR - NotesW - 0.5 + 10*ScreenX;
+
+ // (nowe) - dunno
+ if (Start+Dlugosc-1 = Czas.AktBeatD) then
+ Rec.Right := Rec.Right - (1-Frac(Czas.MidBeatD)) * TempR;
+ // the left note is more right than the right note itself, sounds weird - so we fix that xD
+ if Rec.Right <= Rec.Left then Rec.Right := Rec.Left;
+
+ // draw the middle part
+ glBindTexture(GL_TEXTURE_2D, Tex_Mid[NrGracza+1].TexNum);
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
+ glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(round((Rec.Right-Rec.Left)/32), 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(round((Rec.Right-Rec.Left)/32), 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+ glColor3f(1, 1, 1);
+
+ // the right part of the note
+ Rec.Left := Rec.Right;
+ Rec.Right := Rec.Right + NotesW;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_Right[NrGracza+1].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // Perfect note is stored
+ if Perfect and (Ini.EffectSing=1) then
+ begin
+ A := 1 - 2*(Czas.Teraz - GetTimeFromBeat(Start+Dlugosc));
+ if not (Start+Dlugosc-1 = Czas.AktBeatD) then
+
+ //Star animation counter
+ //inc(Starfr);
+ //Starfr := Starfr mod 128;
+ GoldenRec.SavePerfectNotePos(Rec.Left, Rec.Top);
+ end;
+ end; // with
+ end; // for
+ // eigentlich brauchen wir hier einen vergleich, um festzustellen, ob wir mit
+ // singen schon weiter wären, als bei Rec.Right, _auch, wenn nicht gesungen wird_
+
+ // passing on NrGracza... hope this is really something like the player-number, not only
+ // some kind of weird index into a colour-table
+
+ if (Ini.EffectSing=1) then
+ GoldenRec.GoldenNoteTwinkle(Rec.Top,Rec.Bottom,Rec.Right, NrGracza);
+ end; // if
+end;
+
+//draw Note glow
+procedure SingDrawPlayerBGCzesc(Left, Top, Right: real; NrCzesci, NrGracza: integer; Space: integer);
+var
+ Rec: TRecR;
+ Pet: integer;
+ TempR: real;
+ R,G,B: real;
+ X1, X2, X3, X4: real;
+ W, H: real;
+begin
+ if (Player[NrGracza].ScoreTotalI >= 0) then begin
+ glColor4f(1, 1, 1, sqrt((1+sin(Music.Position * 3))/4)/ 2 + 0.5 );
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote);
+ with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt] do begin
+ for Pet := 0 to HighNut do begin
+ with Nuta[Pet] do begin
+ if not FreeStyle then begin
+ // begin: 14, 20
+ // easy: 6, 11
+ W := NotesW * 2 + 2;
+ H := NotesH * 1.5 + 3.5;
+
+ X2 := (Start-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left + 0.5 + 10*ScreenX + 4; // wciecie
+ X1 := X2-W;
+
+ X3 := (Start+Dlugosc-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left - 0.5 + 10*ScreenX - 4; // wciecie
+ X4 := X3+W;
+
+ // left
+ Rec.Left := X1;
+ Rec.Right := X2;
+ Rec.Top := Top - (Ton-BaseNote)*Space/2 - H;
+ Rec.Bottom := Rec.Top + 2 * H;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_BG_Left[NrGracza+1].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+
+ // srodkowa czesc
+ Rec.Left := X2;
+ Rec.Right := X3;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_BG_Mid[NrGracza+1].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // prawa czesc
+ Rec.Left := X3;
+ Rec.Right := X4;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_BG_Right[NrGracza+1].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+ end; // if not FreeStyle
+ end; // with
+ end; // for
+ end; // with
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ end;
+end;
+
+procedure SingDraw;
+var
+ Pet: integer;
+ Pet2: integer;
+ TempR: real;
+ Rec: TRecR;
+ TexRec: TRecR;
+ NR: TRecR;
+ FS: real;
+ BarFrom: integer;
+ BarAlpha: real;
+ BarWspol: real;
+ TempCol: real;
+ Tekst: string;
+ LyricTemp: string;
+ PetCz: integer;
+
+ //SingBar Mod
+ A: Integer;
+ E: Integer;
+ I: Integer;
+ //end Singbar Mod
+
+begin
+ // positions
+ if Ini.SingWindow = 0 then begin
+ NR.Left := 120;
+ end else begin
+ NR.Left := 20;
+ end;
+ NR.Right := 780;
+
+ NR.Width := NR.Right - NR.Left;
+ NR.WMid := NR.Width / 2;
+ NR.Mid := NR.Left + NR.WMid;
+
+ // background //BG Fullsize Mod
+ //SingDrawBackground;
+
+ //TimeBar mod
+ SingDrawTimeBar();
+ //eoa TimeBar mod
+
+ // rysuje paski pod nutami
+ if PlayersPlay = 1 then
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
+ if (PlayersPlay = 2) or (PlayersPlay = 4) then begin
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P1_NotesB - 105, Nr.Right + 10*ScreenX, 15);
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
+ end;
+
+ if (PlayersPlay = 3) or (PlayersPlay = 6) then begin
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, 120, Nr.Right + 10*ScreenX, 12);
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, 245, Nr.Right + 10*ScreenX, 12);
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, 370, Nr.Right + 10*ScreenX, 12);
+ end;
+
+ // rysuje tekst - new Lyric engine
+ ScreenSing.LyricMain.Draw;
+ ScreenSing.LyricSub.Draw;
+
+ // rysuje pasek, podpowiadajacy poczatek spiwania w scenie
+ FS := 1.3;
+ BarFrom := Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start;
+ if BarFrom > 40 then BarFrom := 40;
+ if (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start > 8) and // dluga przerwa //16->12 for more help bars and then 12->8 for even more
+ (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat > 0) and // przed tekstem
+ (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat < 40) then begin // ale nie za wczesnie
+ BarWspol := (Czas.MidBeat - (Czesci[0].Czesc[Czesci[0].Akt].StartNote - BarFrom)) / BarFrom;
+ Rec.Left := NR.Left + BarWspol *
+// (NR.WMid - Czesci[0].Czesc[Czesci[0].Akt].LyricWidth / 2 * FS - 50);
+ (ScreenSing.LyricMain.ClientX - NR.Left - 50) + 10*ScreenX;
+ Rec.Right := Rec.Left + 50;
+ Rec.Top := Skin_LyricsT + 3;
+ Rec.Bottom := Rec.Top + 33;//SingScreen.LyricMain.Size * 3;
+{ // zapalanie
+ BarAlpha := (BarWspol*10) * 0.5;
+ if BarAlpha > 0.5 then BarAlpha := 0.5;
+
+ // gaszenie
+ if BarWspol > 0.95 then BarAlpha := 0.5 * (1 - (BarWspol - 0.95) * 20);}
+
+ //Change fuer Crazy Joker
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, Tex_Lyric_Help_Bar.TexNum);
+ glBegin(GL_QUADS);
+ glColor4f(1, 1, 1, 0);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glColor4f(1, 1, 1, 0.5);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+ glDisable(GL_BLEND);
+
+ end;
+
+ // oscilloscope
+ if Ini.Oscilloscope = 1 then begin
+ if PlayersPlay = 1 then
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
+
+ if PlayersPlay = 2 then begin
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
+ SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
+ end;
+
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
+ SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2);
+ SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3);
+ end;
+ end;
+
+ if PlayersPlay = 3 then begin
+ SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0);
+ SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
+ SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0);
+ SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
+ SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3);
+ SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4);
+ SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5);
+ end;
+ end;
+
+ end
+
+ //SingBar Mod
+ //modded again to make it moveable: it's working, so why try harder
+ else if Ini.Oscilloscope = 2 then
+ begin
+ A := GetTickCount div 33;
+ if A <> Tickold then begin
+ Tickold := A;
+ for E := 0 to (PlayersPlay - 1) do begin //Set new Pos + Alpha
+ I := Player[E].ScorePercentTarget - Player[E].ScorePercent;
+ if I > 0 then Inc(Player[E].ScorePercent)
+ else if I < 0 then Dec(Player[E].ScorePercent);
+ end; //for
+ end; //if
+
+ if PlayersPlay = 1 then begin
+ SingDrawSingbar(Theme.Sing.StaticP1SingBar.x, Theme.Sing.StaticP1SingBar.y, Theme.Sing.StaticP1SingBar.w, Theme.Sing.StaticP1SingBar.h , Player[0].ScorePercent);
+ end;
+
+ if PlayersPlay = 2 then begin
+ SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent);
+ SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent);
+ end;
+
+ if PlayersPlay = 3 then begin
+ SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent);
+ SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent);
+ SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent);
+ end;
+
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent);
+ SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[2].ScorePercent);
+ SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[3].ScorePercent);
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent);
+ SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent);
+ SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[3].ScorePercent);
+ SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[4].ScorePercent);
+ SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[5].ScorePercent);
+ end;
+ end;
+ end;
+ //end Singbar Mod
+
+ //PhrasenBonus - Line Bonus Mod
+ if Ini.LineBonus > 0 then begin
+ A := GetTickCount div 33;
+ if (A <> Tickold2) AND (Player[0].LineBonus_Visible) then begin
+ Tickold2 := A;
+ for E := 0 to (PlayersPlay - 1) do begin
+ //Change Alpha
+ Player[E].LineBonus_Alpha := Player[E].LineBonus_Alpha - 0.02;
+ if Player[E].LineBonus_Alpha <= 0 then
+ begin
+ Player[E].LineBonus_Age := 0;
+ Player[E].LineBonus_Visible := False
+ end
+ else
+ begin
+ inc(Player[E].LineBonus_Age, 1);
+ //Change Position
+ if (Player[E].LineBonus_PosX < Player[E].LineBonus_TargetX) then
+ Player[E].LineBonus_PosX := Player[E].LineBonus_PosX + (2 - Player[E].LineBonus_Alpha * 1.5)
+ else if (Player[E].LineBonus_PosX > Player[E].LineBonus_TargetX) then
+ Player[E].LineBonus_PosX := Player[E].LineBonus_PosX - (2 - Player[E].LineBonus_Alpha * 1.5);
+
+ if (Player[E].LineBonus_PosY < Player[E].LineBonus_TargetY) then
+ Player[E].LineBonus_PosY := Player[E].LineBonus_PosY + (2 - Player[E].LineBonus_Alpha * 1.5)
+ else if (Player[E].LineBonus_PosY > Player[E].LineBonus_TargetY) then
+ Player[E].LineBonus_PosY := Player[E].LineBonus_PosY - (2 - Player[E].LineBonus_Alpha * 1.5);
+
+ end; // shift position of the pop up (if not dead)
+ end; // loop - for all players
+ end; // if - linebonus
+
+
+ if PlayersPlay = 1 then begin
+ SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
+ end
+
+ else if PlayersPlay = 2 then begin
+ SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
+ SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
+ end
+
+ else if PlayersPlay = 3 then begin
+ SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
+ SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
+ SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age);
+ end
+
+ else if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
+ SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age);
+ SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age);
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
+ SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
+ SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age);
+ SingDrawLineBonus( Player[4].LineBonus_PosX, Player[4].LineBonus_PosY, Player[4].LineBonus_Color, Player[4].LineBonus_Alpha, Player[4].LineBonus_Text, Player[4].LineBonus_Age);
+ SingDrawLineBonus( Player[5].LineBonus_PosX, Player[5].LineBonus_PosY, Player[5].LineBonus_Color, Player[5].LineBonus_Alpha, Player[5].LineBonus_Text, Player[5].LineBonus_Age);
+ end;
+ end;
+ end;
+ //PhrasenBonus - Line Bonus Mod End
+
+// Set the note heights according to the difficulty level
+ case Ini.Difficulty of
+ 0:
+ begin
+ NotesH := 11; // 9
+ NotesW := 6; // 5
+ end;
+ 1:
+ begin
+ NotesH := 8; // 7
+ NotesW := 4; // 4
+ end;
+ 2:
+ begin
+ NotesH := 5;
+ NotesW := 3;
+ end;
+ end;
+
+// Draw the Notes
+ if PlayersPlay = 1 then begin
+ SingDrawPlayerBGCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 0, 15); // Background glow - colorized in playercolor
+ SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15); // Plain unsung notes - colorized in playercolor
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 15); // imho the sung notes
+ end;
+
+ if (PlayersPlay = 2) then begin
+ SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
+ SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
+
+ SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
+ SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 1, 15);
+
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
+ end;
+
+ if PlayersPlay = 3 then begin
+ NotesW := NotesW * 0.8;
+ NotesH := NotesH * 0.8;
+
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
+
+ SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
+ SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 1, 12);
+ SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 2, 12);
+
+ SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
+ SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
+ SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
+ end;
+
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
+ SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 2, 15);
+ SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 3, 15);
+ end;
+
+ if ScreenAct = 1 then begin
+ SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
+ SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 1, 15);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 2, 15);
+ SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 3, 15);
+ end;
+
+ if ScreenAct = 1 then begin
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 2, 15);
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 3, 15);
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ NotesW := NotesW * 0.8;
+ NotesH := NotesH * 0.8;
+
+ if ScreenAct = 1 then begin
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 3, 12);
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 4, 12);
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 5, 12);
+ end;
+
+ if ScreenAct = 1 then begin
+ SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
+ SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 1, 12);
+ SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 2, 12);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 3, 12);
+ SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 4, 12);
+ SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 5, 12);
+ end;
+
+ if ScreenAct = 1 then begin
+ SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
+ SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
+ SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 3, 12);
+ SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 4, 12);
+ SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 5, 12);
+ end;
+ end;
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+end;
+
+// q'n'd for using the game mode dll's
+procedure SingModiDraw (PlayerInfo: TPlayerInfo);
+var
+ Pet: integer;
+ Pet2: integer;
+ TempR: real;
+ Rec: TRecR;
+ TexRec: TRecR;
+ NR: TRecR;
+ FS: real;
+ BarFrom: integer;
+ BarAlpha: real;
+ BarWspol: real;
+ TempCol: real;
+ Tekst: string;
+ LyricTemp: string;
+ PetCz: integer;
+
+ //SingBar Mod
+ A: Integer;
+ E: Integer;
+ I: Integer;
+ //end Singbar Mod
+
+begin
+ // positions
+ if Ini.SingWindow = 0 then begin
+ NR.Left := 120;
+ end else begin
+ NR.Left := 20;
+ end;
+
+ NR.Right := 780;
+ NR.Width := NR.Right - NR.Left;
+ NR.WMid := NR.Width / 2;
+ NR.Mid := NR.Left + NR.WMid;
+
+ // time bar
+ SingDrawTimeBar();
+
+ if DLLMan.Selected.ShowNotes then
+ begin
+ if PlayersPlay = 1 then
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
+ if (PlayersPlay = 2) or (PlayersPlay = 4) then begin
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P1_NotesB - 105, Nr.Right + 10*ScreenX, 15);
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, Skin_P2_NotesB - 105, Nr.Right + 10*ScreenX, 15);
+ end;
+
+ if (PlayersPlay = 3) or (PlayersPlay = 6) then begin
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, 120, Nr.Right + 10*ScreenX, 12);
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, 245, Nr.Right + 10*ScreenX, 12);
+ SingDrawNoteLines(Nr.Left + 10*ScreenX, 370, Nr.Right + 10*ScreenX, 12);
+ end;
+ end;
+
+ // Lyric engine
+ ScreenSingModi.LyricMain.Draw;
+ ScreenSingModi.LyricSub.Draw;
+
+ // rysuje pasek, podpowiadajacy poczatek spiwania w scenie
+ FS := 1.3;
+ BarFrom := Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start;
+ if BarFrom > 40 then BarFrom := 40;
+ if (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czesci[0].Czesc[Czesci[0].Akt].Start > 8) and // dluga przerwa //16->12 for more help bars and then 12->8 for even more
+ (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat > 0) and // przed tekstem
+ (Czesci[0].Czesc[Czesci[0].Akt].StartNote - Czas.MidBeat < 40) then begin // ale nie za wczesnie
+ BarWspol := (Czas.MidBeat - (Czesci[0].Czesc[Czesci[0].Akt].StartNote - BarFrom)) / BarFrom;
+ Rec.Left := NR.Left + BarWspol * (ScreenSingModi.LyricMain.ClientX - NR.Left - 50) + 10*ScreenX;
+ Rec.Right := Rec.Left + 50;
+ Rec.Top := Skin_LyricsT + 3;
+ Rec.Bottom := Rec.Top + 33;//SingScreen.LyricMain.Size * 3;
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, Tex_Lyric_Help_Bar.TexNum);
+ glBegin(GL_QUADS);
+ glColor4f(1, 1, 1, 0);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glColor4f(1, 1, 1, 0.5);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+ glDisable(GL_BLEND);
+ end;
+
+ // oscilloscope | the thing that moves when you yell into your mic (imho)
+ if (((Ini.Oscilloscope = 1) AND (DLLMan.Selected.ShowRateBar_O)) AND (NOT DLLMan.Selected.ShowRateBar)) then begin
+ if PlayersPlay = 1 then
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
+
+ if PlayersPlay = 2 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
+ end;
+
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 0);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 1);
+ end;
+ if ScreenAct = 2 then begin
+ if PlayerInfo.Playerinfo[2].Enabled then
+ SingDrawOscilloscope(190 + 10*ScreenX, 55, 180, 40, 2);
+ if PlayerInfo.Playerinfo[3].Enabled then
+ SingDrawOscilloscope(425 + 10*ScreenX, 55, 180, 40, 3);
+ end;
+ end;
+
+ if PlayersPlay = 3 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawOscilloscope(75 + 10*ScreenX, 95, 100, 20, 0);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
+ if PlayerInfo.Playerinfo[2].Enabled then
+ SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 0);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 1);
+ if PlayerInfo.Playerinfo[2].Enabled then
+ SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 2);
+ end;
+ if ScreenAct = 2 then begin
+ if PlayerInfo.Playerinfo[3].Enabled then
+ SingDrawOscilloscope( 75 + 10*ScreenX, 95, 100, 20, 3);
+ if PlayerInfo.Playerinfo[4].Enabled then
+ SingDrawOscilloscope(370 + 10*ScreenX, 95, 100, 20, 4);
+ if PlayerInfo.Playerinfo[5].Enabled then
+ SingDrawOscilloscope(670 + 10*ScreenX, 95, 100, 20, 5);
+ end;
+ end;
+
+ end
+
+ //SingBar Mod
+ // seems like we don't want the flicker thing, we want the linebonus rating bar beneath the scores
+ else if ((Ini.Oscilloscope = 2) AND (DLLMan.Selected.ShowRateBar_O)) OR (DLLMan.Selected.ShowRateBar) then begin
+ A := GetTickCount div 33;
+ if A <> Tickold then begin
+ Tickold := A;
+ for E := 0 to (PlayersPlay - 1) do begin //Set new Pos + Alpha
+ I := Player[E].ScorePercentTarget - Player[E].ScorePercent;
+ if I > 0 then Inc(Player[E].ScorePercent)
+ else if I < 0 then Dec(Player[E].ScorePercent);
+ end; //for
+ end; //if
+
+ if PlayersPlay = 1 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP1SingBar.x, Theme.Sing.StaticP1SingBar.y, Theme.Sing.StaticP1SingBar.w, Theme.Sing.StaticP1SingBar.h , Player[0].ScorePercent);
+ end;
+
+ if PlayersPlay = 2 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent);
+ end;
+
+ if PlayersPlay = 3 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent);
+ if PlayerInfo.Playerinfo[2].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent);
+ end;
+
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[0].ScorePercent);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[1].ScorePercent);
+ end;
+ if ScreenAct = 2 then begin
+ if PlayerInfo.Playerinfo[2].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP1TwoPSingBar.x, Theme.Sing.StaticP1TwoPSingBar.y, Theme.Sing.StaticP1TwoPSingBar.w, Theme.Sing.StaticP1TwoPSingBar.h , Player[2].ScorePercent);
+ if PlayerInfo.Playerinfo[3].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP2RSingBar.x, Theme.Sing.StaticP2RSingBar.y, Theme.Sing.StaticP2RSingBar.w, Theme.Sing.StaticP2RSingBar.h , Player[3].ScorePercent);
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[0].ScorePercent);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[1].ScorePercent);
+ if PlayerInfo.Playerinfo[2].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[2].ScorePercent);
+ end;
+ if ScreenAct = 2 then begin
+ if PlayerInfo.Playerinfo[3].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP1ThreePSingBar.x, Theme.Sing.StaticP1ThreePSingBar.y, Theme.Sing.StaticP1ThreePSingBar.w, Theme.Sing.StaticP1ThreePSingBar.h , Player[3].ScorePercent);
+ if PlayerInfo.Playerinfo[4].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP2MSingBar.x, Theme.Sing.StaticP2MSingBar.y, Theme.Sing.StaticP2MSingBar.w, Theme.Sing.StaticP2MSingBar.h , Player[4].ScorePercent);
+ if PlayerInfo.Playerinfo[5].Enabled then
+ SingDrawSingbar(Theme.Sing.StaticP3SingBar.x, Theme.Sing.StaticP3SingBar.y, Theme.Sing.StaticP3SingBar.w, Theme.Sing.StaticP3SingBar.h , Player[5].ScorePercent);
+ end;
+ end;
+ end;
+ //end Singbar Mod
+
+ //PhrasenBonus - Line Bonus Mod
+ if ((Ini.LineBonus > 0) AND (DLLMan.Selected.EnLineBonus_O)) OR (DLLMan.Selected.EnLineBonus) then begin
+ A := GetTickCount div 33;
+ if (A <> Tickold2) AND (Player[0].LineBonus_Visible) then begin
+ Tickold2 := A;
+ for E := 0 to (PlayersPlay - 1) do begin
+ //Change Alpha
+ Player[E].LineBonus_Alpha := Player[E].LineBonus_Alpha - 0.02;
+
+ if Player[E].LineBonus_Alpha <= 0 then
+ begin
+ Player[E].LineBonus_Age := 0;
+ Player[E].LineBonus_Visible := False
+ end
+ else
+ begin
+ inc(Player[E].LineBonus_Age, 1);
+ //Change Position
+ if (Player[E].LineBonus_PosX < Player[E].LineBonus_TargetX) then // pop up has not yet reached it's position -> blend in
+ Player[E].LineBonus_PosX := Player[E].LineBonus_PosX + (2 - Player[E].LineBonus_Alpha * 1.5)
+ else if (Player[E].LineBonus_PosX > Player[E].LineBonus_TargetX) then // pop up has reached it's position -> blend out
+ Player[E].LineBonus_PosX := Player[E].LineBonus_PosX - (2 - Player[E].LineBonus_Alpha * 1.5);
+
+ if (Player[E].LineBonus_PosY < Player[E].LineBonus_TargetY) then
+ Player[E].LineBonus_PosY := Player[E].LineBonus_PosY + (2 - Player[E].LineBonus_Alpha * 1.5)
+ else if (Player[E].LineBonus_PosY > Player[E].LineBonus_TargetY) then
+ Player[E].LineBonus_PosY := Player[E].LineBonus_PosY - (2 - Player[E].LineBonus_Alpha * 1.5);
+
+ end; // pop up still visible, has not reached it's position - move it
+ end; // loop through all players
+ end; // if it's time to draw them
+
+ if PlayersPlay = 1 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
+ end
+
+ else if PlayersPlay = 2 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
+ end
+
+ else if PlayersPlay = 3 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
+ if PlayerInfo.Playerinfo[2].Enabled then
+ SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age);
+ end
+
+ else if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
+ end;
+ if ScreenAct = 2 then begin
+ if PlayerInfo.Playerinfo[2].Enabled then
+ SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age);
+ if PlayerInfo.Playerinfo[3].Enabled then
+ SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age);
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawLineBonus( Player[0].LineBonus_PosX, Player[0].LineBonus_PosY, Player[0].LineBonus_Color, Player[0].LineBonus_Alpha, Player[0].LineBonus_Text, Player[0].LineBonus_Age);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text, Player[1].LineBonus_Age);
+ if PlayerInfo.Playerinfo[2].Enabled then
+ SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text, Player[2].LineBonus_Age);
+ end;
+ if ScreenAct = 2 then begin
+ if PlayerInfo.Playerinfo[3].Enabled then
+ SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text, Player[3].LineBonus_Age);
+ if PlayerInfo.Playerinfo[4].Enabled then
+ SingDrawLineBonus( Player[4].LineBonus_PosX, Player[4].LineBonus_PosY, Player[4].LineBonus_Color, Player[4].LineBonus_Alpha, Player[4].LineBonus_Text, Player[4].LineBonus_Age);
+ if PlayerInfo.Playerinfo[5].Enabled then
+ SingDrawLineBonus( Player[5].LineBonus_PosX, Player[5].LineBonus_PosY, Player[5].LineBonus_Color, Player[5].LineBonus_Alpha, Player[5].LineBonus_Text, Player[5].LineBonus_Age);
+ end;
+ end;
+ end;
+//PhrasenBonus - Line Bonus Mod End
+
+// resize the notes according to the difficulty level
+ case Ini.Difficulty of
+ 0:
+ begin
+ NotesH := 11; // 9
+ NotesW := 6; // 5
+ end;
+ 1:
+ begin
+ NotesH := 8; // 7
+ NotesW := 4; // 4
+ end;
+ 2:
+ begin
+ NotesH := 5;
+ NotesW := 3;
+ end;
+ end;
+
+ if (DLLMAn.Selected.ShowNotes And DLLMan.Selected.LoadSong) then
+ begin
+ if (PlayersPlay = 1) And PlayerInfo.Playerinfo[0].Enabled then begin
+ SingDrawPlayerBGCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 0, 15);
+ SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 15);
+ end;
+
+ if (PlayersPlay = 2) then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ begin
+ SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
+ SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
+ end;
+ if PlayerInfo.Playerinfo[1].Enabled then
+ begin
+ SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
+ SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
+ end;
+
+ end;
+
+ if PlayersPlay = 3 then begin
+ NotesW := NotesW * 0.8;
+ NotesH := NotesH * 0.8;
+
+ if PlayerInfo.Playerinfo[0].Enabled then
+ begin
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
+ SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
+ SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
+ end;
+
+ if PlayerInfo.Playerinfo[1].Enabled then
+ begin
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
+ SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 0, 12);
+ SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
+ end;
+
+ if PlayerInfo.Playerinfo[2].Enabled then
+ begin
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
+ SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 0, 12);
+ SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
+ end;
+ end;
+
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 0, 15);
+ SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 1, 15);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Right - 20, 0, 2, 15);
+ SingDrawPlayerBGCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Right - 20, 0, 3, 15);
+ end;
+
+ SingDrawCzesc(NR.Left + 20, Skin_P1_NotesB, NR.Right - 20, 0, 15);
+ SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
+
+ if ScreenAct = 1 then begin
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 2, 15);
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 3, 15);
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ NotesW := NotesW * 0.8;
+ NotesH := NotesH * 0.8;
+
+ if ScreenAct = 1 then begin
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 0, 12);
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 1, 12);
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 2, 12);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 120+95, Nr.Right - 20, 0, 3, 12);
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 245+95, Nr.Right - 20, 0, 4, 12);
+ SingDrawPlayerBGCzesc(Nr.Left + 20, 370+95, Nr.Right - 20, 0, 5, 12);
+ end;
+
+ SingDrawCzesc(NR.Left + 20, 120+95, NR.Right - 20, 0, 12);
+ SingDrawCzesc(NR.Left + 20, 245+95, NR.Right - 20, 0, 12);
+ SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 0, 12);
+
+ if ScreenAct = 1 then begin
+ SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
+ SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
+ SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 3, 12);
+ SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 4, 12);
+ SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 5, 12);
+ end;
+ end;
+ end;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+end;
+
+
+//SingBar Mod
+procedure SingDrawSingbar(X, Y, W, H: real; Percent: integer);
+var
+ R: Real;
+ G: Real;
+ B: Real;
+ A: cardinal;
+ I: Integer;
+
+begin;
+
+ //SingBar Background
+ glColor4f(1, 1, 1, 0.8);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Back.TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(X, Y);
+ glTexCoord2f(0, 1); glVertex2f(X, Y+H);
+ glTexCoord2f(1, 1); glVertex2f(X+W, Y+H);
+ glTexCoord2f(1, 0); glVertex2f(X+W, Y);
+ glEnd;
+
+ //SingBar coloured Bar
+ Case Percent of
+ 0..22: begin
+ R := 1;
+ G := 0;
+ B := 0;
+ end;
+ 23..42: begin
+ R := 1;
+ G := ((Percent-23)/100)*5;
+ B := 0;
+ end;
+ 43..57: begin
+ R := 1;
+ G := 1;
+ B := 0;
+ end;
+ 58..77: begin
+ R := 1-(Percent - 58)/100*5;
+ G := 1;
+ B := 0;
+ end;
+ 78..99: begin
+ R := 0;
+ G := 1;
+ B := 0;
+ end;
+ End; //Case
+
+ glColor4f(R, G, B, 1);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Bar.TexNum);
+ //Size= Player[PlayerNum].ScorePercent of W
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(X, Y);
+ glTexCoord2f(0, 1); glVertex2f(X, Y+H);
+ glTexCoord2f(1, 1); glVertex2f(X+(W/100 * (Percent +1)), Y+H);
+ glTexCoord2f(1, 0); glVertex2f(X+(W/100 * (Percent +1)), Y);
+ glEnd;
+
+ //SingBar Front
+ glColor4f(1, 1, 1, 0.6);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, Tex_SingBar_Front.TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(X, Y);
+ glTexCoord2f(0, 1); glVertex2f(X, Y+H);
+ glTexCoord2f(1, 1); glVertex2f(X+W, Y+H);
+ glTexCoord2f(1, 0); glVertex2f(X+W, Y);
+ glEnd;
+end;
+//end Singbar Mod
+
+//PhrasenBonus - Line Bonus Pop Up
+procedure SingDrawLineBonus( const X, Y: Single; Color: TRGB; Alpha: Single; Text: string; Age: Integer);
+var
+Length, X2: Real; //Length of Text
+Size: Integer; //Size of Popup
+begin
+if Alpha <> 0 then
+begin
+
+//Set Font Propertys
+SetFontStyle(2); //Font: Outlined1
+if Age < 5 then SetFontSize(Age + 1) else SetFontSize(6);
+SetFontItalic(False);
+
+//Check Font Size
+Length := glTextWidth ( PChar(Text)) + 3; //Little Space for a Better Look ^^
+
+//Text
+SetFontPos (X + 50 - (Length / 2), Y + 12); //Position
+
+
+if Age < 5 then Size := Age * 10 else Size := 50;
+
+ //Draw Background
+ //glColor4f(Color.R, Color.G, Color.B, Alpha); //Set Color
+ glColor4f(1, 1, 1, Alpha);
+
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+
+ //New Method, Not Variable
+ glBindTexture(GL_TEXTURE_2D, Tex_SingLineBonusBack[2].TexNum);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(X + 50 - Size, Y + 25 - (Size/2));
+ glTexCoord2f(0, 1); glVertex2f(X + 50 - Size, Y + 25 + (Size/2));
+ glTexCoord2f(1, 1); glVertex2f(X + 50 + Size, Y + 25 + (Size/2));
+ glTexCoord2f(1, 0); glVertex2f(X + 50 + Size, Y + 25 - (Size/2));
+ glEnd;
+
+ glColor4f(1, 1, 1, Alpha); //Set Color
+ //Draw Text
+ glPrint (PChar(Text));
+end;
+end;
+//PhrasenBonus - Line Bonus Mod
+
+// Draw Note Bars for Editor
+//There are 11 Resons for a new Procdedure:
+// 1. It don't look good when you Draw the Golden Note Star Effect in the Editor
+// 2. You can see the Freestyle Notes in the Editor SemiTransparent
+// 3. Its easier and Faster then changing the old Procedure
+procedure EditDrawCzesc(Left, Top, Right: real; NrCzesci: integer; Space: integer);
+var
+ Rec: TRecR;
+ Pet: integer;
+ TempR: real;
+begin
+ glColor3f(1, 1, 1);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ TempR := (Right-Left) / (Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].Koniec - Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote);
+ with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt] do begin
+ for Pet := 0 to HighNut do begin
+ with Nuta[Pet] do begin
+
+ // Golden Note Patch
+ case Wartosc of
+ 0: glColor4f(1, 1, 1, 0.35);
+ 1: glColor4f(1, 1, 1, 0.85);
+ 2: glColor4f(1, 1, 0.3, 0.85);
+ end; // case
+
+
+
+ // lewa czesc - left part
+ Rec.Left := (Start-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left + 0.5 + 10*ScreenX;
+ Rec.Right := Rec.Left + NotesW;
+ Rec.Top := Top - (Ton-BaseNote)*Space/2 - NotesH;
+ Rec.Bottom := Rec.Top + 2 * NotesH;
+ glBindTexture(GL_TEXTURE_2D, Tex_Left[Color].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // srodkowa czesc - middle part
+ Rec.Left := Rec.Right;
+ Rec.Right := (Start+Dlugosc-Czesci[NrCzesci].Czesc[Czesci[NrCzesci].Akt].StartNote) * TempR + Left - NotesW - 0.5 + 10*ScreenX;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_Mid[Color].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // prawa czesc - right part
+ Rec.Left := Rec.Right;
+ Rec.Right := Rec.Right + NotesW;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_Right[Color].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(0, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ end; // with
+ end; // for
+ end; // with
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+end;
+
+procedure SingDrawTimeBar();
+var x,y: real;
+ width, height: real;
+begin
+ x := Theme.Sing.StaticTimeProgress.x;
+ y := Theme.Sing.StaticTimeProgress.y;
+ width:= Theme.Sing.StaticTimeProgress.w;
+ height:= Theme.Sing.StaticTimeProgress.h;
+
+ glColor4f(Theme.Sing.StaticTimeProgress.ColR,
+ Theme.Sing.StaticTimeProgress.ColG,
+ Theme.Sing.StaticTimeProgress.ColB, 1); //Set Color
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+
+ glBindTexture(GL_TEXTURE_2D, Tex_TimeProgress.TexNum);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(x,y);
+ glTexCoord2f((width*(Czas.Teraz/Czas.Razem))/8, 0); glVertex2f(x+width*(Czas.Teraz/Czas.Razem), y);
+ glTexCoord2f((width*(Czas.Teraz/Czas.Razem))/8, 1); glVertex2f(x+width*(Czas.Teraz/Czas.Razem), y+height);
+ glTexCoord2f(0, 1); glVertex2f(x, y+height);
+ glEnd;
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+ glcolor4f(1,1,1,1);
+end;
+
+end.
+
diff --git a/Game/Code/Classes/UGraphic.pas b/Game/Code/Classes/UGraphic.pas
index eb7dde8e..aaa4b3d7 100644
--- a/Game/Code/Classes/UGraphic.pas
+++ b/Game/Code/Classes/UGraphic.pas
@@ -1,607 +1,611 @@
-unit UGraphic;
-
-interface
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-uses
- SDL,
- OpenGL12,
- UTexture,
- TextGL,
- ULog,
- SysUtils,
- ULyrics,
- UScreenLoading,
- UScreenWelcome,
- UScreenMain,
- UScreenName,
- UScreenLevel,
- UScreenOptions,
- UScreenOptionsGame,
- UScreenOptionsGraphics,
- UScreenOptionsSound,
- UScreenOptionsLyrics,
- UScreenOptionsThemes,
- UScreenOptionsRecord,
- UScreenOptionsAdvanced,
- UScreenSong,
- UScreenSing,
- UScreenScore,
- UScreenTop5,
- UScreenEditSub,
- UScreenEdit,
- UScreenEditConvert,
- UScreenEditHeader,
- UScreenOpen,
- UThemes,
- USkins,
- UScreenSongMenu,
- UScreenSongJumpto,
- {Party Screens}
- UScreenSingModi,
- UScreenPartyNewRound,
- UScreenPartyScore,
- UScreenPartyOptions,
- UScreenPartyWin,
- UScreenPartyPlayer,
- {Stats Screens}
- UScreenStatMain,
- UScreenStatDetail,
- {CreditsScreen}
- UScreenCredits,
- {Popup for errors, etc.}
- UScreenPopup;
-
-type
- TRecR = record
- Top: real;
- Left: real;
- Right: real;
- Bottom: real;
- end;
-
-var
- Screen: PSDL_Surface;
-
- LoadingThread: PSDL_Thread;
- Mutex: PSDL_Mutex;
-
- RenderW: integer;
- RenderH: integer;
- ScreenW: integer;
- ScreenH: integer;
- Screens: integer;
- ScreenAct: integer;
- ScreenX: integer;
-
- ScreenLoading: TScreenLoading;
- ScreenWelcome: TScreenWelcome;
- ScreenMain: TScreenMain;
- ScreenName: TScreenName;
- ScreenLevel: TScreenLevel;
- ScreenSong: TScreenSong;
- ScreenSing: TScreenSing;
- ScreenScore: TScreenScore;
- ScreenTop5: TScreenTop5;
- ScreenOptions: TScreenOptions;
- ScreenOptionsGame: TScreenOptionsGame;
- ScreenOptionsGraphics: TScreenOptionsGraphics;
- ScreenOptionsSound: TScreenOptionsSound;
- ScreenOptionsLyrics: TScreenOptionsLyrics;
- ScreenOptionsThemes: TScreenOptionsThemes;
- ScreenOptionsRecord: TScreenOptionsRecord;
- ScreenOptionsAdvanced: TScreenOptionsAdvanced;
- ScreenEditSub: TScreenEditSub;
- ScreenEdit: TScreenEdit;
- ScreenEditConvert: TScreenEditConvert;
- ScreenEditHeader: TScreenEditHeader;
- ScreenOpen: TScreenOpen;
-
- ScreenSongMenu: TScreenSongMenu;
- ScreenSongJumpto: TScreenSongJumpto;
-
- //Party Screens
- ScreenSingModi: TScreenSingModi;
- ScreenPartyNewRound: TScreenPartyNewRound;
- ScreenPartyScore: TScreenPartyScore;
- ScreenPartyWin: TScreenPartyWin;
- ScreenPartyOptions: TScreenPartyOptions;
- ScreenPartyPlayer: TScreenPartyPlayer;
-
- //StatsScreens
- ScreenStatMain: TScreenStatMain;
- ScreenStatDetail: TScreenStatDetail;
-
- //CreditsScreen
- ScreenCredits: TScreenCredits;
-
- //popup mod
- ScreenPopupCheck: TScreenPopupCheck;
- ScreenPopupError: TScreenPopupError;
-
- //Notes
- Tex_Left: array[0..6] of TTexture; //rename to tex_note_left
- Tex_Mid: array[0..6] of TTexture; //rename to tex_note_mid
- Tex_Right: array[0..6] of TTexture; //rename to tex_note_right
-
- Tex_plain_Left: array[1..6] of TTexture; //rename to tex_notebg_left
- Tex_plain_Mid: array[1..6] of TTexture; //rename to tex_notebg_mid
- Tex_plain_Right: array[1..6] of TTexture; //rename to tex_notebg_right
-
- Tex_BG_Left: array[1..6] of TTexture; //rename to tex_noteglow_left
- Tex_BG_Mid: array[1..6] of TTexture; //rename to tex_noteglow_mid
- Tex_BG_Right: array[1..6] of TTexture; //rename to tex_noteglow_right
-
- Tex_Note_Star: TTexture;
- Tex_Note_Perfect_Star: TTexture;
-
-
- Tex_Ball: TTexture;
- Tex_Lyric_Help_Bar: TTexture;
- FullScreen: boolean;
-
- Tex_TimeProgress: TTexture;
-
- //Sing Bar Mod
- Tex_SingBar_Back: TTexture;
- Tex_SingBar_Bar: TTexture;
- Tex_SingBar_Front: TTexture;
- //end Singbar Mod
-
- //PhrasenBonus - Line Bonus Mod
- Tex_SingLineBonusBack: array[0..8] of TTexture;
- //End PhrasenBonus - Line Bonus Mod
-
-const
- Skin_BGColorR = 1;
- Skin_BGColorG = 1;
- Skin_BGColorB = 1;
-
- Skin_SpectrumR = 0;
- Skin_SpectrumG = 0;
- Skin_SpectrumB = 0;
-
- Skin_Spectograph1R = 0.6;
- Skin_Spectograph1G = 0.8;
- Skin_Spectograph1B = 1;
-
- Skin_Spectograph2R = 0;
- Skin_Spectograph2G = 0;
- Skin_Spectograph2B = 0.2;
-
- Skin_SzczytR = 0.8;
- Skin_SzczytG = 0;
- Skin_SzczytB = 0;
-
- Skin_SzczytLimitR = 0;
- Skin_SzczytLimitG = 0.8;
- Skin_SzczytLimitB = 0;
-
- Skin_FontR = 0;
- Skin_FontG = 0;
- Skin_FontB = 0;
-
- Skin_FontHighlightR = 0.3; // 0.3
- Skin_FontHighlightG = 0.3; // 0.3
- Skin_FontHighlightB = 1; // 1
-
- Skin_TimeR = 0.25; //0,0,0
- Skin_TimeG = 0.25;
- Skin_TimeB = 0.25;
-
- Skin_OscR = 0;
- Skin_OscG = 0;
- Skin_OscB = 0;
-
- Skin_LyricsT = 494; // 500 / 510 / 400
- Skin_SpectrumT = 470;
- Skin_SpectrumBot = 570;
- Skin_SpectrumH = 100;
-
- Skin_P1_LinesR = 0.5; // 0.6 0.6 1
- Skin_P1_LinesG = 0.5;
- Skin_P1_LinesB = 0.5;
-
- Skin_P2_LinesR = 0.5; // 1 0.6 0.6
- Skin_P2_LinesG = 0.5;
- Skin_P2_LinesB = 0.5;
-
- Skin_P1_NotesB = 250;
- Skin_P2_NotesB = 430; // 430 / 300
-
- Skin_P1_ScoreT = 50;
- Skin_P1_ScoreL = 20;
-
- Skin_P2_ScoreT = 50;
- Skin_P2_ScoreL = 640;
-
-procedure Initialize3D (Title: string);
-procedure Reinitialize3D;
-procedure SwapBuffers;
-
-procedure LoadTextures;
-procedure InitializeScreen;
-procedure LoadLoadingScreen;
-procedure LoadScreens;
-
-function LoadingThreadFunction: integer;
-
-
-implementation
-
-uses UMain,
- UIni,
- UDisplay,
- UCommandLine,
- {$IFNDEF FPC}
- Graphics,
- {$ENDIF}
- Classes,
- Windows;
-
-procedure LoadTextures;
-
-
-var
- P: integer;
- R, G, B: real;
- Col: integer;
-begin
- // zaladowanie tekstur
- Log.LogStatus('Loading Textures', 'LoadTextures');
- Tex_Left[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayLeft')), 'BMP', 'Transparent', 0); //brauch man die noch?
- Tex_Mid[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayMid')), 'BMP', 'Plain', 0); //brauch man die noch?
- Tex_Right[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayRight')), 'BMP', 'Transparent', 0); //brauch man die noch?
-
- // P1-6
- for P := 1 to 6 do begin
- LoadColor(R, G, B, 'P' + IntToStr(P) + 'Light');
- Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
- Tex_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayLeft')), 'PNG', 'Colorized', Col);
- Tex_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayMid')), 'PNG', 'Colorized', Col);
- Tex_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayRight')), 'PNG', 'Colorized', Col);
-
- Tex_plain_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainLeft')), 'PNG', 'Colorized', Col);
- Tex_plain_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainMid')), 'PNG', 'Colorized', Col);
- Tex_plain_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainRight')), 'PNG', 'Colorized', Col);
-
- Tex_BG_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGLeft')), 'PNG', 'Colorized', Col);
- Tex_BG_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGMid')), 'PNG', 'Colorized', Col);
- Tex_BG_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGRight')), 'PNG', 'Colorized', Col);
- end;
-
- Tex_Note_Perfect_Star := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePerfectStar')), 'JPG', 'Font Black', 0);
- Tex_Note_Star := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteStar')) , 'JPG', 'Alpha Black Colored', $FFFFFF);
- Tex_Ball := Texture.LoadTexture(pchar(Skin.GetTextureFileName('Ball')), 'BMP', 'Transparent', $FF00FF);
- Tex_Lyric_Help_Bar := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LyricHelpBar')), 'BMP', 'Transparent', $FF00FF);
-
-
- //TimeBar mod
- Tex_TimeProgress := Texture.LoadTexture(pchar(Skin.GetTextureFileName('TimeBar')));
- //eoa TimeBar mod
-
- //SingBar Mod
- Tex_SingBar_Back := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarBack')), 'JPG', 'Plain', 0);
- Tex_SingBar_Bar := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarBar')), 'JPG', 'Plain', 0);
- Tex_SingBar_Front := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarFront')), 'JPG', 'Font', 0);
- //end Singbar Mod
-
- //Line Bonus PopUp
- for P := 0 to 8 do
- begin
- Tex_SingLineBonusBack[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LineBonusBack')), 'PNG', 'Colorized', $FFFFFF);
- end;
- {//Set Texture to Font High
- Tex_SingLineBonusL.H := 32; Tex_SingLineBonusL.W := 8;
- Tex_SingLineBonusM.H := 32; //Tex_SingLineBonusM.TexW := Tex_SingLineBonusM.TexW/2;
- Tex_SingLineBonusR.H := 32; Tex_SingLineBonusR.W := 8; }
- //PhrasenBonus - Line Bonus Mod End
-
- // tworzenie czcionek
- Log.LogStatus('Building Fonts', 'LoadTextures');
- BuildFont;
-end;
-
-procedure Initialize3D (Title: string);
-var
-// Icon: TIcon;
- Res: TResourceStream;
- ISurface: PSDL_Surface;
- Pixel: PByteArray;
- I: Integer;
-begin
- Log.LogStatus('LoadOpenGL', 'Initialize3D');
- Log.BenchmarkStart(2);
-
- LoadOpenGL;
-
- Log.LogStatus('SDL_Init', 'Initialize3D');
- if ( SDL_Init(SDL_INIT_VIDEO or SDL_INIT_AUDIO)= -1 ) then begin
- Log.LogError('SDL_Init Failed', 'Initialize3D');
- exit;
- end;
-
- { //Load Icon
- Res := TResourceStream.CreateFromID(HInstance, 3, RT_ICON);
- Icon := TIcon.Create;
- Icon.LoadFromStream(Res);
- Res.Free;
- Icon.
- //Create icon Surface
- SDL_CreateRGBSurfaceFrom (
- SDL_SWSURFACE,
- Icon.Width,
- Icon.Height,
- 32,
- 128 or 64,
- 32 or 16,
- 8 or 4,
- 2 or 1);
- //SDL_BlitSurface(
-
-
- SDL_WM_SetIcon(SDL_LoadBMP('DEFAULT_WINDOW_ICON'), 0); //}
-
- SDL_WM_SetCaption(PChar(Title), nil);
-
- InitializeScreen;
-
- Log.BenchmarkEnd(2);
- Log.LogBenchmark('--> Setting Screen', 2);
-
- // ladowanie tekstur
- Log.BenchmarkStart(2);
- Texture := TTextureUnit.Create;
- Texture.Limit := 1024*1024;
-
- LoadTextures;
- Log.BenchmarkEnd(2);
- Log.LogBenchmark('--> Loading Textures', 2);
-
- Log.BenchmarkStart(2);
- Lyric := TLyric.Create;
- Log.BenchmarkEnd(2);
- Log.LogBenchmark('--> Loading Fonts', 2);
-
- Log.BenchmarkStart(2);
- Display := TDisplay.Create;
- SDL_EnableUnicode(1);
- Log.BenchmarkEnd(2); Log.LogBenchmark('====> Creating Display', 2);
-
- Log.LogStatus('Loading Screens', 'Initialize3D');
- Log.BenchmarkStart(3);
-
- LoadLoadingScreen;
- // now that we have something to display while loading,
- // start thread that loads the rest of ultrastar
-// Mutex := SDL_CreateMutex;
-// SDL_UnLockMutex(Mutex);
-
- // funktioniert so noch nicht, da der ladethread unverändert auf opengl zugreifen will
- // siehe dazu kommentar unten
- //LoadingThread := SDL_CreateThread(@LoadingThread, nil);
-
- // das hier würde dann im ladethread ausgeführt
- LoadScreens;
-
-
- // TODO!!!!!!1
- // hier käme jetzt eine schleife, die
- // * den ladescreen malt (ab und zu)
- // * den "fortschritt" des ladescreens steuert
- // * zwischendrin schaut, ob der ladethread texturen geladen hat (mutex prüfen) und
- // * die texturen in die opengl lädt, sowie
- // * dem ladethread signalisiert, dass der speicher für die textur
- // zum laden der nächsten textur weiterverwendet werden kann (über weiteren mutex)
- // * über einen 3. mutex so lange läuft, bis der ladethread signalisiert,
- // dass er alles geladen hat fertig ist
- //
- // dafür muss loadtexture so umgeschrieben werden, dass es, statt selbst irgendwelche
- // opengl funktionen aufzurufen, entsprechend mutexe verändert
- // der hauptthread muss auch irgendwoher erfahren, was an opengl funktionen auszuführen ist,
- // mit welchen parametern (texturtyp, entspr. texturobjekt, textur-zwischenspeicher-adresse, ...
-
-
- //wait for loading thread to finish
- // funktioniert so auch noch nicht
- //SDL_WaitThread(LoadingThread, I);
-// SDL_DestroyMutex(Mutex);
-
- Display.ActualScreen^.FadeTo(@ScreenMain);
-
- Log.BenchmarkEnd(2);
- Log.LogBenchmark('--> Loading Screens', 2);
-
- Log.LogStatus('Finish', 'Initialize3D');
-end;
-
-procedure SwapBuffers;
-begin
- SDL_GL_SwapBuffers;
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity;
- glOrtho(0, RenderW, RenderH, 0, -1, 100);
- glMatrixMode(GL_MODELVIEW);
-end;
-
-procedure Reinitialize3D;
-begin
-// InitializeScreen;
-// LoadTextures;
-// LoadScreens;
-end;
-
-procedure InitializeScreen;
-var
- S: string;
- I: integer;
- W, H: integer;
- Depth: Integer;
-begin
- if (Params.Screens <> -1) then
- Screens := Params.Screens + 1
- else
- Screens := Ini.Screens + 1;
-
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-
- // If there is a resolution in Parameters, use it, else use the Ini value
- I := Params.Resolution;
- if (I <> -1) then
- S := IResolution[I]
- else
- S := IResolution[Ini.Resolution];
-
- I := Pos('x', S);
- W := StrToInt(Copy(S, 1, I-1)) * Screens;
- H := StrToInt(Copy(S, I+1, 1000));
-
- {if ParamStr(1) = '-fsblack' then begin
- W := 800;
- H := 600;
- end;
- if ParamStr(1) = '-320x240' then begin
- W := 320;
- H := 240;
- end; }
-
- If (Params.Depth <> -1) then
- Depth := Params.Depth
- else
- Depth := Ini.Depth;
-
-
- Log.LogStatus('SDL_SetVideoMode', 'Initialize3D');
-// SDL_SetRefreshrate(85);
-// SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
- if (Ini.FullScreen = 0) and (Not Params.FullScreen) then
- screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL)
- else begin
- screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN);
- SDL_ShowCursor(0);
- end;
- if (screen = nil) then begin
- Log.LogError('SDL_SetVideoMode Failed', 'Initialize3D');
- exit;
- end;
-
- // clear screen once window is being shown
- glClearColor(1, 1, 1, 1);
- glClear(GL_COLOR_BUFFER_BIT);
- SwapBuffers;
-
- // zmienne
- RenderW := 800;
- RenderH := 600;
- ScreenW := W;
- ScreenH := H;
-end;
-
-procedure LoadLoadingScreen;
-begin
- ScreenLoading := TScreenLoading.Create;
- ScreenLoading.onShow;
- Display.ActualScreen := @ScreenLoading;
- swapbuffers;
- ScreenLoading.Draw;
- Display.Draw;
- SwapBuffers;
-end;
-
-procedure LoadScreens;
-begin
-{ ScreenLoading := TScreenLoading.Create;
- ScreenLoading.onShow;
- Display.ActualScreen := @ScreenLoading;
- ScreenLoading.Draw;
- Display.Draw;
- SwapBuffers;
-}
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Loading', 3); Log.BenchmarkStart(3);
-{ ScreenWelcome := TScreenWelcome.Create; //'BG', 4, 3);
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Welcome', 3); Log.BenchmarkStart(3);}
- ScreenMain := TScreenMain.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Main', 3); Log.BenchmarkStart(3);
- ScreenName := TScreenName.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Name', 3); Log.BenchmarkStart(3);
- ScreenLevel := TScreenLevel.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Level', 3); Log.BenchmarkStart(3);
- ScreenSong := TScreenSong.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song', 3); Log.BenchmarkStart(3);
- ScreenSongMenu := TScreenSongMenu.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song Menu', 3); Log.BenchmarkStart(3);
- ScreenSing := TScreenSing.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing', 3); Log.BenchmarkStart(3);
- ScreenScore := TScreenScore.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Score', 3); Log.BenchmarkStart(3);
- ScreenTop5 := TScreenTop5.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Top5', 3); Log.BenchmarkStart(3);
- ScreenOptions := TScreenOptions.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options', 3); Log.BenchmarkStart(3);
- ScreenOptionsGame := TScreenOptionsGame.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Game', 3); Log.BenchmarkStart(3);
- ScreenOptionsGraphics := TScreenOptionsGraphics.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Graphics', 3); Log.BenchmarkStart(3);
- ScreenOptionsSound := TScreenOptionsSound.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Sound', 3); Log.BenchmarkStart(3);
- ScreenOptionsLyrics := TScreenOptionsLyrics.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Lyrics', 3); Log.BenchmarkStart(3);
- ScreenOptionsThemes := TScreenOptionsThemes.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Themes', 3); Log.BenchmarkStart(3);
- ScreenOptionsRecord := TScreenOptionsRecord.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Record', 3); Log.BenchmarkStart(3);
- ScreenOptionsAdvanced := TScreenOptionsAdvanced.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Advanced', 3); Log.BenchmarkStart(3);
- ScreenEditSub := TScreenEditSub.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Sub', 3); Log.BenchmarkStart(3);
- ScreenEdit := TScreenEdit.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit', 3); Log.BenchmarkStart(3);
- ScreenEditConvert := TScreenEditConvert.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen EditConvert', 3); Log.BenchmarkStart(3);
-// ScreenEditHeader := TScreenEditHeader.Create(Skin.ScoreBG);
-// Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Header', 3); Log.BenchmarkStart(3);
- ScreenOpen := TScreenOpen.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Open', 3); Log.BenchmarkStart(3);
- ScreenSingModi := TScreenSingModi.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing with Modi support', 3); Log.BenchmarkStart(3);
- ScreenSongMenu := TScreenSongMenu.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongMenu', 3); Log.BenchmarkStart(3);
- ScreenSongJumpto := TScreenSongJumpto.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongJumpto', 3); Log.BenchmarkStart(3);
- ScreenPopupCheck := TScreenPopupCheck.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Check)', 3); Log.BenchmarkStart(3);
- ScreenPopupError := TScreenPopupError.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Error)', 3); Log.BenchmarkStart(3);
- ScreenPartyNewRound := TScreenPartyNewRound.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyNewRound', 3); Log.BenchmarkStart(3);
- ScreenPartyScore := TScreenPartyScore.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyScore', 3); Log.BenchmarkStart(3);
- ScreenPartyWin := TScreenPartyWin.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyWin', 3); Log.BenchmarkStart(3);
- ScreenPartyOptions := TScreenPartyOptions.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyOptions', 3); Log.BenchmarkStart(3);
- ScreenPartyPlayer := TScreenPartyPlayer.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyPlayer', 3); Log.BenchmarkStart(3);
- ScreenStatMain := TScreenStatMain.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Main', 3); Log.BenchmarkStart(3);
- ScreenStatDetail := TScreenStatDetail.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Detail', 3); Log.BenchmarkStart(3);
- ScreenCredits := TScreenCredits.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Credits', 3); Log.BenchmarkStart(3);
-
- end;
-
-function LoadingThreadFunction: integer;
-begin
- LoadScreens;
- Result:= 1;
-end;
-
-end.
+unit UGraphic;
+
+interface
+
+{$I switches.inc}
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+{$ENDIF}
+
+uses
+ SDL,
+ OpenGL12,
+ UTexture,
+ TextGL,
+ ULog,
+ SysUtils,
+ ULyrics,
+ UScreenLoading,
+ UScreenWelcome,
+ UScreenMain,
+ UScreenName,
+ UScreenLevel,
+ UScreenOptions,
+ UScreenOptionsGame,
+ UScreenOptionsGraphics,
+ UScreenOptionsSound,
+ UScreenOptionsLyrics,
+ UScreenOptionsThemes,
+ UScreenOptionsRecord,
+ UScreenOptionsAdvanced,
+ UScreenSong,
+ UScreenSing,
+ UScreenScore,
+ UScreenTop5,
+ UScreenEditSub,
+ UScreenEdit,
+ UScreenEditConvert,
+ UScreenEditHeader,
+ UScreenOpen,
+ UThemes,
+ USkins,
+ UScreenSongMenu,
+ UScreenSongJumpto,
+ {Party Screens}
+ UScreenSingModi,
+ UScreenPartyNewRound,
+ UScreenPartyScore,
+ UScreenPartyOptions,
+ UScreenPartyWin,
+ UScreenPartyPlayer,
+ {Stats Screens}
+ UScreenStatMain,
+ UScreenStatDetail,
+ {CreditsScreen}
+ UScreenCredits,
+ {Popup for errors, etc.}
+ UScreenPopup;
+
+type
+ TRecR = record
+ Top: real;
+ Left: real;
+ Right: real;
+ Bottom: real;
+ end;
+
+var
+ Screen: PSDL_Surface;
+
+ LoadingThread: PSDL_Thread;
+ Mutex: PSDL_Mutex;
+
+ RenderW: integer;
+ RenderH: integer;
+ ScreenW: integer;
+ ScreenH: integer;
+ Screens: integer;
+ ScreenAct: integer;
+ ScreenX: integer;
+
+ ScreenLoading: TScreenLoading;
+ ScreenWelcome: TScreenWelcome;
+ ScreenMain: TScreenMain;
+ ScreenName: TScreenName;
+ ScreenLevel: TScreenLevel;
+ ScreenSong: TScreenSong;
+ ScreenSing: TScreenSing;
+ ScreenScore: TScreenScore;
+ ScreenTop5: TScreenTop5;
+ ScreenOptions: TScreenOptions;
+ ScreenOptionsGame: TScreenOptionsGame;
+ ScreenOptionsGraphics: TScreenOptionsGraphics;
+ ScreenOptionsSound: TScreenOptionsSound;
+ ScreenOptionsLyrics: TScreenOptionsLyrics;
+ ScreenOptionsThemes: TScreenOptionsThemes;
+ ScreenOptionsRecord: TScreenOptionsRecord;
+ ScreenOptionsAdvanced: TScreenOptionsAdvanced;
+ ScreenEditSub: TScreenEditSub;
+ ScreenEdit: TScreenEdit;
+ ScreenEditConvert: TScreenEditConvert;
+ ScreenEditHeader: TScreenEditHeader;
+ ScreenOpen: TScreenOpen;
+
+ ScreenSongMenu: TScreenSongMenu;
+ ScreenSongJumpto: TScreenSongJumpto;
+
+ //Party Screens
+ ScreenSingModi: TScreenSingModi;
+ ScreenPartyNewRound: TScreenPartyNewRound;
+ ScreenPartyScore: TScreenPartyScore;
+ ScreenPartyWin: TScreenPartyWin;
+ ScreenPartyOptions: TScreenPartyOptions;
+ ScreenPartyPlayer: TScreenPartyPlayer;
+
+ //StatsScreens
+ ScreenStatMain: TScreenStatMain;
+ ScreenStatDetail: TScreenStatDetail;
+
+ //CreditsScreen
+ ScreenCredits: TScreenCredits;
+
+ //popup mod
+ ScreenPopupCheck: TScreenPopupCheck;
+ ScreenPopupError: TScreenPopupError;
+
+ //Notes
+ Tex_Left: array[0..6] of TTexture; //rename to tex_note_left
+ Tex_Mid: array[0..6] of TTexture; //rename to tex_note_mid
+ Tex_Right: array[0..6] of TTexture; //rename to tex_note_right
+
+ Tex_plain_Left: array[1..6] of TTexture; //rename to tex_notebg_left
+ Tex_plain_Mid: array[1..6] of TTexture; //rename to tex_notebg_mid
+ Tex_plain_Right: array[1..6] of TTexture; //rename to tex_notebg_right
+
+ Tex_BG_Left: array[1..6] of TTexture; //rename to tex_noteglow_left
+ Tex_BG_Mid: array[1..6] of TTexture; //rename to tex_noteglow_mid
+ Tex_BG_Right: array[1..6] of TTexture; //rename to tex_noteglow_right
+
+ Tex_Note_Star: TTexture;
+ Tex_Note_Perfect_Star: TTexture;
+
+
+ Tex_Ball: TTexture;
+ Tex_Lyric_Help_Bar: TTexture;
+ FullScreen: boolean;
+
+ Tex_TimeProgress: TTexture;
+
+ //Sing Bar Mod
+ Tex_SingBar_Back: TTexture;
+ Tex_SingBar_Bar: TTexture;
+ Tex_SingBar_Front: TTexture;
+ //end Singbar Mod
+
+ //PhrasenBonus - Line Bonus Mod
+ Tex_SingLineBonusBack: array[0..8] of TTexture;
+ //End PhrasenBonus - Line Bonus Mod
+
+const
+ Skin_BGColorR = 1;
+ Skin_BGColorG = 1;
+ Skin_BGColorB = 1;
+
+ Skin_SpectrumR = 0;
+ Skin_SpectrumG = 0;
+ Skin_SpectrumB = 0;
+
+ Skin_Spectograph1R = 0.6;
+ Skin_Spectograph1G = 0.8;
+ Skin_Spectograph1B = 1;
+
+ Skin_Spectograph2R = 0;
+ Skin_Spectograph2G = 0;
+ Skin_Spectograph2B = 0.2;
+
+ Skin_SzczytR = 0.8;
+ Skin_SzczytG = 0;
+ Skin_SzczytB = 0;
+
+ Skin_SzczytLimitR = 0;
+ Skin_SzczytLimitG = 0.8;
+ Skin_SzczytLimitB = 0;
+
+ Skin_FontR = 0;
+ Skin_FontG = 0;
+ Skin_FontB = 0;
+
+ Skin_FontHighlightR = 0.3; // 0.3
+ Skin_FontHighlightG = 0.3; // 0.3
+ Skin_FontHighlightB = 1; // 1
+
+ Skin_TimeR = 0.25; //0,0,0
+ Skin_TimeG = 0.25;
+ Skin_TimeB = 0.25;
+
+ Skin_OscR = 0;
+ Skin_OscG = 0;
+ Skin_OscB = 0;
+
+ Skin_LyricsT = 494; // 500 / 510 / 400
+ Skin_SpectrumT = 470;
+ Skin_SpectrumBot = 570;
+ Skin_SpectrumH = 100;
+
+ Skin_P1_LinesR = 0.5; // 0.6 0.6 1
+ Skin_P1_LinesG = 0.5;
+ Skin_P1_LinesB = 0.5;
+
+ Skin_P2_LinesR = 0.5; // 1 0.6 0.6
+ Skin_P2_LinesG = 0.5;
+ Skin_P2_LinesB = 0.5;
+
+ Skin_P1_NotesB = 250;
+ Skin_P2_NotesB = 430; // 430 / 300
+
+ Skin_P1_ScoreT = 50;
+ Skin_P1_ScoreL = 20;
+
+ Skin_P2_ScoreT = 50;
+ Skin_P2_ScoreL = 640;
+
+procedure Initialize3D (Title: string);
+procedure Reinitialize3D;
+procedure SwapBuffers;
+
+procedure LoadTextures;
+procedure InitializeScreen;
+procedure LoadLoadingScreen;
+procedure LoadScreens;
+
+function LoadingThreadFunction: integer;
+
+
+implementation
+
+uses UMain,
+ UIni,
+ UDisplay,
+ UCommandLine,
+ {$IFNDEF FPC}
+ Graphics,
+ {$ENDIF}
+ {$IFDEF win32}
+ windows,
+ {$ENDIF}
+ Classes;
+
+procedure LoadTextures;
+
+
+var
+ P: integer;
+ R, G, B: real;
+ Col: integer;
+begin
+ // zaladowanie tekstur
+ Log.LogStatus('Loading Textures', 'LoadTextures');
+ Tex_Left[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayLeft')), 'BMP', 'Transparent', 0); //brauch man die noch?
+ Tex_Mid[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayMid')), 'BMP', 'Plain', 0); //brauch man die noch?
+ Tex_Right[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayRight')), 'BMP', 'Transparent', 0); //brauch man die noch?
+
+ // P1-6
+ for P := 1 to 6 do begin
+ LoadColor(R, G, B, 'P' + IntToStr(P) + 'Light');
+ Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
+ Tex_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayLeft')), 'PNG', 'Colorized', Col);
+ Tex_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayMid')), 'PNG', 'Colorized', Col);
+ Tex_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayRight')), 'PNG', 'Colorized', Col);
+
+ Tex_plain_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainLeft')), 'PNG', 'Colorized', Col);
+ Tex_plain_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainMid')), 'PNG', 'Colorized', Col);
+ Tex_plain_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainRight')), 'PNG', 'Colorized', Col);
+
+ Tex_BG_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGLeft')), 'PNG', 'Colorized', Col);
+ Tex_BG_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGMid')), 'PNG', 'Colorized', Col);
+ Tex_BG_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGRight')), 'PNG', 'Colorized', Col);
+ end;
+
+ Tex_Note_Perfect_Star := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePerfectStar')), 'JPG', 'Font Black', 0);
+ Tex_Note_Star := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteStar')) , 'JPG', 'Alpha Black Colored', $FFFFFF);
+ Tex_Ball := Texture.LoadTexture(pchar(Skin.GetTextureFileName('Ball')), 'BMP', 'Transparent', $FF00FF);
+ Tex_Lyric_Help_Bar := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LyricHelpBar')), 'BMP', 'Transparent', $FF00FF);
+
+
+ //TimeBar mod
+ Tex_TimeProgress := Texture.LoadTexture(pchar(Skin.GetTextureFileName('TimeBar')));
+ //eoa TimeBar mod
+
+ //SingBar Mod
+ Tex_SingBar_Back := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarBack')), 'JPG', 'Plain', 0);
+ Tex_SingBar_Bar := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarBar')), 'JPG', 'Plain', 0);
+ Tex_SingBar_Front := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarFront')), 'JPG', 'Font', 0);
+ //end Singbar Mod
+
+ //Line Bonus PopUp
+ for P := 0 to 8 do
+ begin
+ Tex_SingLineBonusBack[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LineBonusBack')), 'PNG', 'Colorized', $FFFFFF);
+ end;
+ {//Set Texture to Font High
+ Tex_SingLineBonusL.H := 32; Tex_SingLineBonusL.W := 8;
+ Tex_SingLineBonusM.H := 32; //Tex_SingLineBonusM.TexW := Tex_SingLineBonusM.TexW/2;
+ Tex_SingLineBonusR.H := 32; Tex_SingLineBonusR.W := 8; }
+ //PhrasenBonus - Line Bonus Mod End
+
+ // tworzenie czcionek
+ Log.LogStatus('Building Fonts', 'LoadTextures');
+ BuildFont;
+end;
+
+procedure Initialize3D (Title: string);
+var
+// Icon: TIcon;
+ Res: TResourceStream;
+ ISurface: PSDL_Surface;
+ Pixel: PByteArray;
+ I: Integer;
+begin
+ Log.LogStatus('LoadOpenGL', 'Initialize3D');
+ Log.BenchmarkStart(2);
+
+ LoadOpenGL;
+
+ Log.LogStatus('SDL_Init', 'Initialize3D');
+ if ( SDL_Init(SDL_INIT_VIDEO or SDL_INIT_AUDIO)= -1 ) then begin
+ Log.LogError('SDL_Init Failed', 'Initialize3D');
+ exit;
+ end;
+
+ { //Load Icon
+ Res := TResourceStream.CreateFromID(HInstance, 3, RT_ICON);
+ Icon := TIcon.Create;
+ Icon.LoadFromStream(Res);
+ Res.Free;
+ Icon.
+ //Create icon Surface
+ SDL_CreateRGBSurfaceFrom (
+ SDL_SWSURFACE,
+ Icon.Width,
+ Icon.Height,
+ 32,
+ 128 or 64,
+ 32 or 16,
+ 8 or 4,
+ 2 or 1);
+ //SDL_BlitSurface(
+
+
+ SDL_WM_SetIcon(SDL_LoadBMP('DEFAULT_WINDOW_ICON'), 0); //}
+
+ SDL_WM_SetCaption(PChar(Title), nil);
+
+ InitializeScreen;
+
+ Log.BenchmarkEnd(2);
+ Log.LogBenchmark('--> Setting Screen', 2);
+
+ // ladowanie tekstur
+ Log.BenchmarkStart(2);
+ Texture := TTextureUnit.Create;
+ Texture.Limit := 1024*1024;
+
+ LoadTextures;
+ Log.BenchmarkEnd(2);
+ Log.LogBenchmark('--> Loading Textures', 2);
+
+ Log.BenchmarkStart(2);
+ Lyric := TLyric.Create;
+ Log.BenchmarkEnd(2);
+ Log.LogBenchmark('--> Loading Fonts', 2);
+
+ Log.BenchmarkStart(2);
+ Display := TDisplay.Create;
+ SDL_EnableUnicode(1);
+ Log.BenchmarkEnd(2); Log.LogBenchmark('====> Creating Display', 2);
+
+ Log.LogStatus('Loading Screens', 'Initialize3D');
+ Log.BenchmarkStart(3);
+
+ LoadLoadingScreen;
+ // now that we have something to display while loading,
+ // start thread that loads the rest of ultrastar
+// Mutex := SDL_CreateMutex;
+// SDL_UnLockMutex(Mutex);
+
+ // funktioniert so noch nicht, da der ladethread unverändert auf opengl zugreifen will
+ // siehe dazu kommentar unten
+ //LoadingThread := SDL_CreateThread(@LoadingThread, nil);
+
+ // das hier würde dann im ladethread ausgeführt
+ LoadScreens;
+
+
+ // TODO!!!!!!1
+ // hier käme jetzt eine schleife, die
+ // * den ladescreen malt (ab und zu)
+ // * den "fortschritt" des ladescreens steuert
+ // * zwischendrin schaut, ob der ladethread texturen geladen hat (mutex prüfen) und
+ // * die texturen in die opengl lädt, sowie
+ // * dem ladethread signalisiert, dass der speicher für die textur
+ // zum laden der nächsten textur weiterverwendet werden kann (über weiteren mutex)
+ // * über einen 3. mutex so lange läuft, bis der ladethread signalisiert,
+ // dass er alles geladen hat fertig ist
+ //
+ // dafür muss loadtexture so umgeschrieben werden, dass es, statt selbst irgendwelche
+ // opengl funktionen aufzurufen, entsprechend mutexe verändert
+ // der hauptthread muss auch irgendwoher erfahren, was an opengl funktionen auszuführen ist,
+ // mit welchen parametern (texturtyp, entspr. texturobjekt, textur-zwischenspeicher-adresse, ...
+
+
+ //wait for loading thread to finish
+ // funktioniert so auch noch nicht
+ //SDL_WaitThread(LoadingThread, I);
+// SDL_DestroyMutex(Mutex);
+
+ Display.ActualScreen^.FadeTo(@ScreenMain);
+
+ Log.BenchmarkEnd(2);
+ Log.LogBenchmark('--> Loading Screens', 2);
+
+ Log.LogStatus('Finish', 'Initialize3D');
+end;
+
+procedure SwapBuffers;
+begin
+ SDL_GL_SwapBuffers;
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity;
+ glOrtho(0, RenderW, RenderH, 0, -1, 100);
+ glMatrixMode(GL_MODELVIEW);
+end;
+
+procedure Reinitialize3D;
+begin
+// InitializeScreen;
+// LoadTextures;
+// LoadScreens;
+end;
+
+procedure InitializeScreen;
+var
+ S: string;
+ I: integer;
+ W, H: integer;
+ Depth: Integer;
+begin
+ if (Params.Screens <> -1) then
+ Screens := Params.Screens + 1
+ else
+ Screens := Ini.Screens + 1;
+
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+
+ // If there is a resolution in Parameters, use it, else use the Ini value
+ I := Params.Resolution;
+ if (I <> -1) then
+ S := IResolution[I]
+ else
+ S := IResolution[Ini.Resolution];
+
+ I := Pos('x', S);
+ W := StrToInt(Copy(S, 1, I-1)) * Screens;
+ H := StrToInt(Copy(S, I+1, 1000));
+
+ {if ParamStr(1) = '-fsblack' then begin
+ W := 800;
+ H := 600;
+ end;
+ if ParamStr(1) = '-320x240' then begin
+ W := 320;
+ H := 240;
+ end; }
+
+ If (Params.Depth <> -1) then
+ Depth := Params.Depth
+ else
+ Depth := Ini.Depth;
+
+
+ Log.LogStatus('SDL_SetVideoMode', 'Initialize3D');
+// SDL_SetRefreshrate(85);
+// SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+ if (Ini.FullScreen = 0) and (Not Params.FullScreen) then
+ screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL)
+ else begin
+ screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN);
+ SDL_ShowCursor(0);
+ end;
+ if (screen = nil) then begin
+ Log.LogError('SDL_SetVideoMode Failed', 'Initialize3D');
+ exit;
+ end;
+
+ // clear screen once window is being shown
+ glClearColor(1, 1, 1, 1);
+ glClear(GL_COLOR_BUFFER_BIT);
+ SwapBuffers;
+
+ // zmienne
+ RenderW := 800;
+ RenderH := 600;
+ ScreenW := W;
+ ScreenH := H;
+end;
+
+procedure LoadLoadingScreen;
+begin
+ ScreenLoading := TScreenLoading.Create;
+ ScreenLoading.onShow;
+ Display.ActualScreen := @ScreenLoading;
+ swapbuffers;
+ ScreenLoading.Draw;
+ Display.Draw;
+ SwapBuffers;
+end;
+
+procedure LoadScreens;
+begin
+{ ScreenLoading := TScreenLoading.Create;
+ ScreenLoading.onShow;
+ Display.ActualScreen := @ScreenLoading;
+ ScreenLoading.Draw;
+ Display.Draw;
+ SwapBuffers;
+}
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Loading', 3); Log.BenchmarkStart(3);
+{ ScreenWelcome := TScreenWelcome.Create; //'BG', 4, 3);
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Welcome', 3); Log.BenchmarkStart(3);}
+ ScreenMain := TScreenMain.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Main', 3); Log.BenchmarkStart(3);
+ ScreenName := TScreenName.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Name', 3); Log.BenchmarkStart(3);
+ ScreenLevel := TScreenLevel.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Level', 3); Log.BenchmarkStart(3);
+ ScreenSong := TScreenSong.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song', 3); Log.BenchmarkStart(3);
+ ScreenSongMenu := TScreenSongMenu.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song Menu', 3); Log.BenchmarkStart(3);
+ ScreenSing := TScreenSing.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing', 3); Log.BenchmarkStart(3);
+ ScreenScore := TScreenScore.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Score', 3); Log.BenchmarkStart(3);
+ ScreenTop5 := TScreenTop5.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Top5', 3); Log.BenchmarkStart(3);
+ ScreenOptions := TScreenOptions.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options', 3); Log.BenchmarkStart(3);
+ ScreenOptionsGame := TScreenOptionsGame.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Game', 3); Log.BenchmarkStart(3);
+ ScreenOptionsGraphics := TScreenOptionsGraphics.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Graphics', 3); Log.BenchmarkStart(3);
+ ScreenOptionsSound := TScreenOptionsSound.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Sound', 3); Log.BenchmarkStart(3);
+ ScreenOptionsLyrics := TScreenOptionsLyrics.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Lyrics', 3); Log.BenchmarkStart(3);
+ ScreenOptionsThemes := TScreenOptionsThemes.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Themes', 3); Log.BenchmarkStart(3);
+ ScreenOptionsRecord := TScreenOptionsRecord.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Record', 3); Log.BenchmarkStart(3);
+ ScreenOptionsAdvanced := TScreenOptionsAdvanced.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Advanced', 3); Log.BenchmarkStart(3);
+ ScreenEditSub := TScreenEditSub.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Sub', 3); Log.BenchmarkStart(3);
+ ScreenEdit := TScreenEdit.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit', 3); Log.BenchmarkStart(3);
+ ScreenEditConvert := TScreenEditConvert.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen EditConvert', 3); Log.BenchmarkStart(3);
+// ScreenEditHeader := TScreenEditHeader.Create(Skin.ScoreBG);
+// Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Header', 3); Log.BenchmarkStart(3);
+ ScreenOpen := TScreenOpen.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Open', 3); Log.BenchmarkStart(3);
+ ScreenSingModi := TScreenSingModi.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing with Modi support', 3); Log.BenchmarkStart(3);
+ ScreenSongMenu := TScreenSongMenu.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongMenu', 3); Log.BenchmarkStart(3);
+ ScreenSongJumpto := TScreenSongJumpto.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongJumpto', 3); Log.BenchmarkStart(3);
+ ScreenPopupCheck := TScreenPopupCheck.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Check)', 3); Log.BenchmarkStart(3);
+ ScreenPopupError := TScreenPopupError.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Error)', 3); Log.BenchmarkStart(3);
+ ScreenPartyNewRound := TScreenPartyNewRound.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyNewRound', 3); Log.BenchmarkStart(3);
+ ScreenPartyScore := TScreenPartyScore.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyScore', 3); Log.BenchmarkStart(3);
+ ScreenPartyWin := TScreenPartyWin.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyWin', 3); Log.BenchmarkStart(3);
+ ScreenPartyOptions := TScreenPartyOptions.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyOptions', 3); Log.BenchmarkStart(3);
+ ScreenPartyPlayer := TScreenPartyPlayer.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyPlayer', 3); Log.BenchmarkStart(3);
+ ScreenStatMain := TScreenStatMain.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Main', 3); Log.BenchmarkStart(3);
+ ScreenStatDetail := TScreenStatDetail.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Detail', 3); Log.BenchmarkStart(3);
+ ScreenCredits := TScreenCredits.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Credits', 3); Log.BenchmarkStart(3);
+
+ end;
+
+function LoadingThreadFunction: integer;
+begin
+ LoadScreens;
+ Result:= 1;
+end;
+
+end.
diff --git a/Game/Code/Classes/UGraphicClasses.pas b/Game/Code/Classes/UGraphicClasses.pas
index 761ec058..c04a0ad8 100644
--- a/Game/Code/Classes/UGraphicClasses.pas
+++ b/Game/Code/Classes/UGraphicClasses.pas
@@ -1,667 +1,678 @@
-// notes:
-unit UGraphicClasses;
-
-interface
-uses UTexture;
-
-const DelayBetweenFrames : Cardinal = 60;
-type
-
- TParticleType=(GoldenNote, PerfectNote, NoteHitTwinkle, PerfectLineTwinkle, ColoredStar, Flare);
-
- TColour3f = Record
- r, g, b: Real;
- end;
-
- TParticle = Class
- X, Y : Real; //Position
- Screen : Integer;
- W, H : Cardinal; //dimensions of particle
- Col : array of TColour3f; // Colour(s) of particle
- Scale : array of Real; // Scaling factors of particle layers
- Frame : Byte; //act. Frame
- Tex : Cardinal; //Tex num from Textur Manager
- Live : Byte; //How many Cycles before Kill
- RecIndex : Integer; //To which rectangle this particle belongs (only GoldenNote)
- StarType : TParticleType; // GoldenNote | PerfectNote | NoteHitTwinkle | PerfectLineTwinkle
- Alpha : Real; // used for fading...
- mX, mY : Real; // movement-vector for PerfectLineTwinkle
- SizeMod : Real; // experimental size modifier
- SurviveSentenceChange : Boolean;
-
- Constructor Create(cX,cY: Real; cScreen: Integer; cLive: Byte; cFrame : integer; cRecArrayIndex : Integer; cStarType : TParticleType; Player: Cardinal);
- Destructor Destroy(); override;
- procedure Draw;
- procedure LiveOn;
- end;
-
- RectanglePositions = Record
- xTop, yTop, xBottom, yBottom : Real;
- TotalStarCount : Integer;
- CurrentStarCount : Integer;
- Screen : Integer;
- end;
-
- PerfectNotePositions = Record
- xPos, yPos : Real;
- Screen : Integer;
- end;
-
- TEffectManager = Class
- Particle : array of TParticle;
- LastTime : Cardinal;
- RecArray : Array of RectanglePositions;
- TwinkleArray : Array[0..5] of Real; // store x-position of last twinkle for every player
- PerfNoteArray : Array of PerfectNotePositions;
-
- FlareTex: TTexture;
-
- constructor Create;
- destructor Destroy; override;
- procedure Draw;
- function Spawn(X, Y: Real;
- Screen: Integer;
- Live: Byte;
- StartFrame: Integer;
- RecArrayIndex: Integer; // this is only used with GoldenNotes
- StarType: TParticleType;
- Player: Cardinal // for PerfectLineTwinkle
- ): Cardinal;
- procedure SpawnRec();
- procedure Kill(index: Cardinal);
- procedure KillAll();
- procedure SentenceChange();
- procedure SaveGoldenStarsRec(Xtop, Ytop, Xbottom, Ybottom: Real);
- procedure SavePerfectNotePos(Xtop, Ytop: Real);
- procedure GoldenNoteTwinkle(Top,Bottom,Right: Real; Player: Integer);
- procedure SpawnPerfectLineTwinkle();
- end;
-
-var GoldenRec : TEffectManager;
-
-implementation
-
-uses sysutils,
- Windows,
- OpenGl12,
- UIni,
- UMain,
- UThemes,
- USkins,
- UGraphic,
- UDrawTexture,
- UCommon,
- math;
-
-//TParticle
-Constructor TParticle.Create(cX,cY: Real; cScreen: Integer; cLive: Byte; cFrame : integer; cRecArrayIndex : Integer; cStarType : TParticleType; Player: Cardinal);
-begin
- inherited Create;
- // in this constructor we set all initial values for our particle
- X := cX;
- Y := cY;
- Screen := cScreen;
- Live := cLive;
- Frame:= cFrame;
- RecIndex := cRecArrayIndex;
- StarType := cStarType;
- Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
- SetLength(Scale,1);
- Scale[0] := 1;
- SurviveSentenceChange := False;
- SizeMod := 1;
- case cStarType of
- GoldenNote:
- begin
- Tex := Tex_Note_Star.TexNum;
- W := 20;
- H := 20;
- SetLength(Scale,4);
- Scale[1]:=0.8;
- Scale[2]:=0.4;
- Scale[3]:=0.3;
- SetLength(Col,4);
- Col[0].r := 1;
- Col[0].g := 0.7;
- Col[0].b := 0.1;
-
- Col[1].r := 1;
- Col[1].g := 1;
- Col[1].b := 0.4;
-
- Col[2].r := 1;
- Col[2].g := 1;
- Col[2].b := 1;
-
- Col[3].r := 1;
- Col[3].g := 1;
- Col[3].b := 1;
- end;
- PerfectNote:
- begin
- Tex := Tex_Note_Perfect_Star.TexNum;
- W := 30;
- H := 30;
- SetLength(Col,1);
- Col[0].r := 1;
- Col[0].g := 1;
- Col[0].b := 0.95;
- end;
- NoteHitTwinkle:
- begin
- Tex := Tex_Note_Star.TexNum;
- Alpha := (Live/16); // linear fade-out
- W := 15;
- H := 15;
- Setlength(Col,1);
- Col[0].r := 1;
- Col[0].g := 1;
- Col[0].b := RandomRange(10*Live,100)/90; //0.9;
- end;
- PerfectLineTwinkle:
- begin
- Tex := Tex_Note_Star.TexNum;
- W := RandomRange(10,20);
- H := W;
- SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
- SurviveSentenceChange:=True;
- // assign colours according to player given
- SetLength(Scale,3);
- Scale[1]:=0.3;
- Scale[2]:=0.2;
- SetLength(Col,3);
- case Player of
- 0: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P1Light');
- 1: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P2Light');
- 2: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P3Light');
- 3: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P4Light');
- 4: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P5Light');
- 5: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P6Light');
- else LoadColor(Col[0].r,Col[0].g,Col[0].b,'P1Light');
- end;
- Col[1].r := 1;
- Col[1].g := 1;
- Col[1].b := 0.4;
- Col[2].r:=Col[0].r+0.5;
- Col[2].g:=Col[0].g+0.5;
- Col[2].b:=Col[0].b+0.5;
- mX := RandomRange(-5,5);
- mY := RandomRange(-5,5);
- end;
- ColoredStar:
- begin
- Tex := Tex_Note_Star.TexNum;
- W := RandomRange(10,20);
- H := W;
- SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
- SurviveSentenceChange:=True;
- // assign colours according to player given
- SetLength(Scale,1);
- SetLength(Col,1);
- Col[0].b := (Player and $ff)/255;
- Col[0].g := ((Player shr 8) and $ff)/255;
- Col[0].r := ((Player shr 16) and $ff)/255;
- mX := 0;
- mY := 0;
- end;
- Flare:
- begin
- Tex := Tex_Note_Star.TexNum;
- W := 7;
- H := 7;
- SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
- mX := RandomRange(-5,5);
- mY := RandomRange(-5,5);
- SetLength(Scale,4);
- Scale[1]:=0.8;
- Scale[2]:=0.4;
- Scale[3]:=0.3;
- SetLength(Col,4);
- Col[0].r := 1;
- Col[0].g := 0.7;
- Col[0].b := 0.1;
-
- Col[1].r := 1;
- Col[1].g := 1;
- Col[1].b := 0.4;
-
- Col[2].r := 1;
- Col[2].g := 1;
- Col[2].b := 1;
-
- Col[3].r := 1;
- Col[3].g := 1;
- Col[3].b := 1;
-
- end;
- else // just some random default values
- begin
- Tex := Tex_Note_Star.TexNum;
- Alpha := 1;
- W := 20;
- H := 20;
- SetLength(Col,1);
- Col[0].r := 1;
- Col[0].g := 1;
- Col[0].b := 1;
- end;
- end;
-end;
-
-Destructor TParticle.Destroy();
-begin
- SetLength(Scale,0);
- SetLength(Col,0);
- inherited;
-end;
-
-procedure TParticle.LiveOn;
-begin
- //Live = 0 => Live forever <blindy> ?? die werden doch aber im Manager bei Draw getötet, wenns 0 is
- if (Live > 0) then
- Dec(Live);
-
- // animate frames
- Frame := ( Frame + 1 ) mod 16;
-
- // make our particles do funny stuff (besides being animated)
- // changes of any particle-values throughout its life are done here
- case StarType of
- GoldenNote:
- begin
- Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
- end;
- PerfectNote:
- begin
- Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
- end;
- NoteHitTwinkle:
- begin
- Alpha := (Live/10); // linear fade-out
- end;
- PerfectLineTwinkle:
- begin
- Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
- SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
- // move around
- X := X + mX;
- Y := Y + mY;
- end;
- ColoredStar:
- begin
- Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
- end;
- Flare:
- begin
- Alpha := (-cos((Frame+1)/16*1.7*pi+0.3*pi)+1); // neat fade-in-and-out
- SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
- // move around
- X := X + mX;
- Y := Y + mY;
- mY:=mY+1.8;
-// mX:=mX/2;
- end;
- end;
-end;
-
-procedure TParticle.Draw;
-var L: Cardinal;
-begin
- if ScreenAct = Screen then
- // this draws (multiple) texture(s) of our particle
- for L:=0 to High(Col) do
- begin
- glColor4f(Col[L].r, Col[L].g, Col[L].b, Alpha);
-
- glBindTexture(GL_TEXTURE_2D, Tex);
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- begin
- glBegin(GL_QUADS);
- glTexCoord2f((1/16) * Frame, 0); glVertex2f(X-W*Scale[L]*SizeMod, Y-H*Scale[L]*SizeMod);
- glTexCoord2f((1/16) * Frame + (1/16), 0); glVertex2f(X-W*Scale[L]*SizeMod, Y+H*Scale[L]*SizeMod);
- glTexCoord2f((1/16) * Frame + (1/16), 1); glVertex2f(X+W*Scale[L]*SizeMod, Y+H*Scale[L]*SizeMod);
- glTexCoord2f((1/16) * Frame, 1); glVertex2f(X+W*Scale[L]*SizeMod, Y-H*Scale[L]*SizeMod);
- glEnd;
- end;
- end;
- glcolor4f(1,1,1,1);
-end;
-// end of TParticle
-
-// TEffectManager
-
-constructor TEffectManager.Create;
-var c: Cardinal;
-begin
- inherited;
- LastTime := GetTickCount;
- for c:=0 to 5 do
- begin
- TwinkleArray[c] := 0;
- end;
-end;
-
-destructor TEffectManager.Destroy;
-begin
- Killall;
- inherited;
-end;
-
-
-procedure TEffectManager.Draw;
-var
- I: Integer;
- CurrentTime: Cardinal;
-//const
-// DelayBetweenFrames : Cardinal = 100;
-begin
-
- CurrentTime := GetTickCount;
- //Manage particle life
- if (CurrentTime - LastTime) > DelayBetweenFrames then
- begin
- LastTime := CurrentTime;
- for I := 0 to high(Particle) do
- Particle[I].LiveOn;
- end;
-
- I := 0;
- //Kill dead particles
- while (I <= High(Particle)) do
- begin
- if (Particle[I].Live <= 0) then
- begin
- kill(I);
- end
- else
- begin
- inc(I);
- end;
- end;
-
- //Draw
- for I := 0 to high(Particle) do
- begin
- Particle[I].Draw;
- end;
-end;
-
-// this method creates just one particle
-function TEffectManager.Spawn(X, Y: Real; Screen: Integer; Live: Byte; StartFrame : Integer; RecArrayIndex : Integer; StarType : TParticleType; Player: Cardinal): Cardinal;
-begin
- Result := Length(Particle);
- SetLength(Particle, (Result + 1));
- Particle[Result] := TParticle.Create(X, Y, Screen, Live, StartFrame, RecArrayIndex, StarType, Player);
-end;
-
-// manage Sparkling of GoldenNote Bars
-procedure TEffectManager.SpawnRec();
-Var
- Xkatze, Ykatze : Real;
- RandomFrame : Integer;
- P : Integer; // P as seen on TV as Positionman
-begin
-//Spawn a random amount of stars within the given coordinates
-//RandomRange(0,14) <- this one starts at a random frame, 16 is our last frame - would be senseless to start a particle with 16, cause it would be dead at the next frame
-for P:= 0 to high(RecArray) do
- begin
- while (RecArray[P].TotalStarCount > RecArray[P].CurrentStarCount) do
- begin
- Xkatze := RandomRange(Ceil(RecArray[P].xTop), Ceil(RecArray[P].xBottom));
- Ykatze := RandomRange(Ceil(RecArray[P].yTop), Ceil(RecArray[P].yBottom));
- RandomFrame := RandomRange(0,14);
- // Spawn a GoldenNote Particle
- Spawn(Xkatze, Ykatze, RecArray[P].Screen, 16 - RandomFrame, RandomFrame, P, GoldenNote, 0);
- inc(RecArray[P].CurrentStarCount);
- end;
- end;
- draw;
-end;
-
-// kill one particle (with given index in our particle array)
-procedure TEffectManager.Kill(Index: Cardinal);
-var
- LastParticleIndex : Integer;
-begin
-// delete particle indexed by Index,
-// overwrite it's place in our particle-array with the particle stored at the last array index,
-// shorten array
- LastParticleIndex := high(Particle);
- if not(LastParticleIndex = -1) then // is there still a particle to delete?
- begin
- if not(Particle[Index].RecIndex = -1) then // if it is a GoldenNote particle...
- dec(RecArray[Particle[Index].RecIndex].CurrentStarCount); // take care of its associated GoldenRec
- // now get rid of that particle
- Particle[Index].Destroy;
- Particle[Index] := Particle[LastParticleIndex];
- SetLength(Particle, LastParticleIndex);
- end;
-end;
-
-// clean up all particles and management structures
-procedure TEffectManager.KillAll();
-var c: Cardinal;
-begin
-//It's the kill all kennies rotuine
- while Length(Particle) > 0 do // kill all existing particles
- Kill(0);
- SetLength(RecArray,0); // remove GoldenRec positions
- SetLength(PerfNoteArray,0); // remove PerfectNote positions
- for c:=0 to 5 do
- begin
- TwinkleArray[c] := 0; // reset GoldenNoteHit memory
- end;
-end;
-
-procedure TEffectManager.SentenceChange();
-var c: Cardinal;
-begin
- c:=0;
- while c <= High(Particle) do
- begin
- if Particle[c].SurviveSentenceChange then
- inc(c)
- else
- Kill(c);
- end;
- SetLength(RecArray,0); // remove GoldenRec positions
- SetLength(PerfNoteArray,0); // remove PerfectNote positions
- for c:=0 to 5 do
- begin
- TwinkleArray[c] := 0; // reset GoldenNoteHit memory
- end;
-end;
-
-procedure TeffectManager.GoldenNoteTwinkle(Top,Bottom,Right: Real; Player: Integer);
-//Twinkle stars while golden note hit
-// this is called from UDraw.pas, SingDrawPlayerCzesc
-var
- C, P, XKatze, YKatze, LKatze: Integer;
- H: Real;
-begin
- // make sure we spawn only one time at one position
- if (TwinkleArray[Player] < Right) then
- For P := 0 to high(RecArray) do // Are we inside a GoldenNoteRectangle?
- begin
- H := (Top+Bottom)/2; // helper...
- with RecArray[P] do
- if ((xBottom >= Right) and (xTop <= Right) and
- (yTop <= H) and (yBottom >= H))
- and (Screen = ScreenAct) then
- begin
- TwinkleArray[Player] := Right; // remember twinkle position for this player
- for C := 1 to 10 do
- begin
- Ykatze := RandomRange(ceil(Top) , ceil(Bottom));
- XKatze := RandomRange(-7,3);
- LKatze := RandomRange(7,13);
- Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
- end;
- for C := 1 to 3 do
- begin
- Ykatze := RandomRange(ceil(Top)-6 , ceil(Top));
- XKatze := RandomRange(-5,1);
- LKatze := RandomRange(4,7);
- Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
- end;
- for C := 1 to 3 do
- begin
- Ykatze := RandomRange(ceil(Bottom), ceil(Bottom)+6);
- XKatze := RandomRange(-5,1);
- LKatze := RandomRange(4,7);
- Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
- end;
- for C := 1 to 3 do
- begin
- Ykatze := RandomRange(ceil(Top)-10 , ceil(Top)-6);
- XKatze := RandomRange(-5,1);
- LKatze := RandomRange(1,4);
- Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
- end;
- for C := 1 to 3 do
- begin
- Ykatze := RandomRange(ceil(Bottom)+6 , ceil(Bottom)+10);
- XKatze := RandomRange(-5,1);
- LKatze := RandomRange(1,4);
- Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
- end;
-
- exit; // found a matching GoldenRec, did spawning stuff... done
- end;
- end;
-end;
-
-procedure TEffectManager.SaveGoldenStarsRec(Xtop, Ytop, Xbottom, Ybottom: Real);
-var
- P : Integer; // P like used in Positions
- NewIndex : Integer;
-begin
- For P := 0 to high(RecArray) do // Do we already have that "new" position?
- begin
- if (ceil(RecArray[P].xTop) = ceil(Xtop)) and
- (ceil(RecArray[P].yTop) = ceil(Ytop)) and
- (ScreenAct = RecArray[p].Screen) then
- exit; // it's already in the array, so we don't have to create a new one
- end;
-
- // we got a new position, add the new positions to our array
- NewIndex := Length(RecArray);
- SetLength(RecArray, NewIndex + 1);
- RecArray[NewIndex].xTop := Xtop;
- RecArray[NewIndex].yTop := Ytop;
- RecArray[NewIndex].xBottom := Xbottom;
- RecArray[NewIndex].yBottom := Ybottom;
- RecArray[NewIndex].TotalStarCount := ceil(Xbottom - Xtop) div 12 + 3;
- RecArray[NewIndex].CurrentStarCount := 0;
- RecArray[NewIndex].Screen := ScreenAct;
-end;
-
-procedure TEffectManager.SavePerfectNotePos(Xtop, Ytop: Real);
-var
- P : Integer; // P like used in Positions
- NewIndex : Integer;
- RandomFrame : Integer;
- Xkatze, Ykatze : Integer;
-begin
- For P := 0 to high(PerfNoteArray) do // Do we already have that "new" position?
- begin
- with PerfNoteArray[P] do
- if (ceil(xPos) = ceil(Xtop)) and (ceil(yPos) = ceil(Ytop)) and
- (Screen = ScreenAct) then
- exit; // it's already in the array, so we don't have to create a new one
- end; //for
-
- // we got a new position, add the new positions to our array
- NewIndex := Length(PerfNoteArray);
- SetLength(PerfNoteArray, NewIndex + 1);
- PerfNoteArray[NewIndex].xPos := Xtop;
- PerfNoteArray[NewIndex].yPos := Ytop;
- PerfNoteArray[NewIndex].Screen := ScreenAct;
-
- for P:= 0 to 2 do
- begin
- Xkatze := RandomRange(ceil(Xtop) - 5 , ceil(Xtop) + 10);
- Ykatze := RandomRange(ceil(Ytop) - 5 , ceil(Ytop) + 10);
- RandomFrame := RandomRange(0,14);
- Spawn(Xkatze, Ykatze, ScreenAct, 16 - RandomFrame, RandomFrame, -1, PerfectNote, 0);
- end; //for
-
-end;
-
-procedure TEffectManager.SpawnPerfectLineTwinkle();
-var
- P,I,Life: Cardinal;
- Left, Right, Top, Bottom: Cardinal;
- cScreen: Integer;
-begin
-// calculation of coordinates done with hardcoded values like in UDraw.pas
-// might need to be adjusted if drawing of SingScreen is modified
-// coordinates may still be a bit weird and need adjustment
- if Ini.SingWindow = 0 then begin
- Left := 130;
- end else begin
- Left := 30;
- end;
- Right := 770;
- // spawn effect for every player with a perfect line
- for P:=0 to PlayersPlay-1 do
- if Player[P].LastSentencePerfect then
- begin
- // calculate area where notes of this player are drawn
- case PlayersPlay of
- 1: begin
- Bottom:=Skin_P2_NotesB+10;
- Top:=Bottom-105;
- cScreen:=1;
- end;
- 2,4: begin
- case P of
- 0,2: begin
- Bottom:=Skin_P1_NotesB+10;
- Top:=Bottom-105;
- end;
- else begin
- Bottom:=Skin_P2_NotesB+10;
- Top:=Bottom-105;
- end;
- end;
- case P of
- 0,1: cScreen:=1;
- else cScreen:=2;
- end;
- end;
- 3,6: begin
- case P of
- 0,3: begin
- Top:=130;
- Bottom:=Top+85;
- end;
- 1,4: begin
- Top:=255;
- Bottom:=Top+85;
- end;
- 2,5: begin
- Top:=380;
- Bottom:=Top+85;
- end;
- end;
- case P of
- 0,1,2: cScreen:=1;
- else cScreen:=2;
- end;
- end;
- end;
- // spawn Sparkling Stars inside calculated coordinates
- for I:= 0 to 80 do
- begin
- Life:=RandomRange(8,16);
- Spawn(RandomRange(Left,Right), RandomRange(Top,Bottom), cScreen, Life, 16-Life, -1, PerfectLineTwinkle, P);
- end;
- end;
-end;
-
-end.
-
+// notes:
+unit UGraphicClasses;
+
+interface
+
+{$I switches.inc}
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+{$ENDIF}
+
+uses UTexture;
+
+const DelayBetweenFrames : Cardinal = 60;
+type
+
+ TParticleType=(GoldenNote, PerfectNote, NoteHitTwinkle, PerfectLineTwinkle, ColoredStar, Flare);
+
+ TColour3f = Record
+ r, g, b: Real;
+ end;
+
+ TParticle = Class
+ X, Y : Real; //Position
+ Screen : Integer;
+ W, H : Cardinal; //dimensions of particle
+ Col : array of TColour3f; // Colour(s) of particle
+ Scale : array of Real; // Scaling factors of particle layers
+ Frame : Byte; //act. Frame
+ Tex : Cardinal; //Tex num from Textur Manager
+ Live : Byte; //How many Cycles before Kill
+ RecIndex : Integer; //To which rectangle this particle belongs (only GoldenNote)
+ StarType : TParticleType; // GoldenNote | PerfectNote | NoteHitTwinkle | PerfectLineTwinkle
+ Alpha : Real; // used for fading...
+ mX, mY : Real; // movement-vector for PerfectLineTwinkle
+ SizeMod : Real; // experimental size modifier
+ SurviveSentenceChange : Boolean;
+
+ Constructor Create(cX,cY: Real; cScreen: Integer; cLive: Byte; cFrame : integer; cRecArrayIndex : Integer; cStarType : TParticleType; Player: Cardinal);
+ Destructor Destroy(); override;
+ procedure Draw;
+ procedure LiveOn;
+ end;
+
+ RectanglePositions = Record
+ xTop, yTop, xBottom, yBottom : Real;
+ TotalStarCount : Integer;
+ CurrentStarCount : Integer;
+ Screen : Integer;
+ end;
+
+ PerfectNotePositions = Record
+ xPos, yPos : Real;
+ Screen : Integer;
+ end;
+
+ TEffectManager = Class
+ Particle : array of TParticle;
+ LastTime : Cardinal;
+ RecArray : Array of RectanglePositions;
+ TwinkleArray : Array[0..5] of Real; // store x-position of last twinkle for every player
+ PerfNoteArray : Array of PerfectNotePositions;
+
+ FlareTex: TTexture;
+
+ constructor Create;
+ destructor Destroy; override;
+ procedure Draw;
+ function Spawn(X, Y: Real;
+ Screen: Integer;
+ Live: Byte;
+ StartFrame: Integer;
+ RecArrayIndex: Integer; // this is only used with GoldenNotes
+ StarType: TParticleType;
+ Player: Cardinal // for PerfectLineTwinkle
+ ): Cardinal;
+ procedure SpawnRec();
+ procedure Kill(index: Cardinal);
+ procedure KillAll();
+ procedure SentenceChange();
+ procedure SaveGoldenStarsRec(Xtop, Ytop, Xbottom, Ybottom: Real);
+ procedure SavePerfectNotePos(Xtop, Ytop: Real);
+ procedure GoldenNoteTwinkle(Top,Bottom,Right: Real; Player: Integer);
+ procedure SpawnPerfectLineTwinkle();
+ end;
+
+var GoldenRec : TEffectManager;
+
+implementation
+
+uses sysutils,
+ {$IFDEF win32}
+ windows,
+ {$ELSE}
+ lclintf,
+ {$ENDIF}
+ OpenGl12,
+ UIni,
+ UMain,
+ UThemes,
+ USkins,
+ UGraphic,
+ UDrawTexture,
+ UCommon,
+ math;
+
+//TParticle
+Constructor TParticle.Create(cX,cY: Real; cScreen: Integer; cLive: Byte; cFrame : integer; cRecArrayIndex : Integer; cStarType : TParticleType; Player: Cardinal);
+begin
+ inherited Create;
+ // in this constructor we set all initial values for our particle
+ X := cX;
+ Y := cY;
+ Screen := cScreen;
+ Live := cLive;
+ Frame:= cFrame;
+ RecIndex := cRecArrayIndex;
+ StarType := cStarType;
+ Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
+ SetLength(Scale,1);
+ Scale[0] := 1;
+ SurviveSentenceChange := False;
+ SizeMod := 1;
+ case cStarType of
+ GoldenNote:
+ begin
+ Tex := Tex_Note_Star.TexNum;
+ W := 20;
+ H := 20;
+ SetLength(Scale,4);
+ Scale[1]:=0.8;
+ Scale[2]:=0.4;
+ Scale[3]:=0.3;
+ SetLength(Col,4);
+ Col[0].r := 1;
+ Col[0].g := 0.7;
+ Col[0].b := 0.1;
+
+ Col[1].r := 1;
+ Col[1].g := 1;
+ Col[1].b := 0.4;
+
+ Col[2].r := 1;
+ Col[2].g := 1;
+ Col[2].b := 1;
+
+ Col[3].r := 1;
+ Col[3].g := 1;
+ Col[3].b := 1;
+ end;
+ PerfectNote:
+ begin
+ Tex := Tex_Note_Perfect_Star.TexNum;
+ W := 30;
+ H := 30;
+ SetLength(Col,1);
+ Col[0].r := 1;
+ Col[0].g := 1;
+ Col[0].b := 0.95;
+ end;
+ NoteHitTwinkle:
+ begin
+ Tex := Tex_Note_Star.TexNum;
+ Alpha := (Live/16); // linear fade-out
+ W := 15;
+ H := 15;
+ Setlength(Col,1);
+ Col[0].r := 1;
+ Col[0].g := 1;
+ Col[0].b := RandomRange(10*Live,100)/90; //0.9;
+ end;
+ PerfectLineTwinkle:
+ begin
+ Tex := Tex_Note_Star.TexNum;
+ W := RandomRange(10,20);
+ H := W;
+ SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
+ SurviveSentenceChange:=True;
+ // assign colours according to player given
+ SetLength(Scale,3);
+ Scale[1]:=0.3;
+ Scale[2]:=0.2;
+ SetLength(Col,3);
+ case Player of
+ 0: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P1Light');
+ 1: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P2Light');
+ 2: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P3Light');
+ 3: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P4Light');
+ 4: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P5Light');
+ 5: LoadColor(Col[0].r,Col[0].g,Col[0].b,'P6Light');
+ else LoadColor(Col[0].r,Col[0].g,Col[0].b,'P1Light');
+ end;
+ Col[1].r := 1;
+ Col[1].g := 1;
+ Col[1].b := 0.4;
+ Col[2].r:=Col[0].r+0.5;
+ Col[2].g:=Col[0].g+0.5;
+ Col[2].b:=Col[0].b+0.5;
+ mX := RandomRange(-5,5);
+ mY := RandomRange(-5,5);
+ end;
+ ColoredStar:
+ begin
+ Tex := Tex_Note_Star.TexNum;
+ W := RandomRange(10,20);
+ H := W;
+ SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
+ SurviveSentenceChange:=True;
+ // assign colours according to player given
+ SetLength(Scale,1);
+ SetLength(Col,1);
+ Col[0].b := (Player and $ff)/255;
+ Col[0].g := ((Player shr 8) and $ff)/255;
+ Col[0].r := ((Player shr 16) and $ff)/255;
+ mX := 0;
+ mY := 0;
+ end;
+ Flare:
+ begin
+ Tex := Tex_Note_Star.TexNum;
+ W := 7;
+ H := 7;
+ SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
+ mX := RandomRange(-5,5);
+ mY := RandomRange(-5,5);
+ SetLength(Scale,4);
+ Scale[1]:=0.8;
+ Scale[2]:=0.4;
+ Scale[3]:=0.3;
+ SetLength(Col,4);
+ Col[0].r := 1;
+ Col[0].g := 0.7;
+ Col[0].b := 0.1;
+
+ Col[1].r := 1;
+ Col[1].g := 1;
+ Col[1].b := 0.4;
+
+ Col[2].r := 1;
+ Col[2].g := 1;
+ Col[2].b := 1;
+
+ Col[3].r := 1;
+ Col[3].g := 1;
+ Col[3].b := 1;
+
+ end;
+ else // just some random default values
+ begin
+ Tex := Tex_Note_Star.TexNum;
+ Alpha := 1;
+ W := 20;
+ H := 20;
+ SetLength(Col,1);
+ Col[0].r := 1;
+ Col[0].g := 1;
+ Col[0].b := 1;
+ end;
+ end;
+end;
+
+Destructor TParticle.Destroy();
+begin
+ SetLength(Scale,0);
+ SetLength(Col,0);
+ inherited;
+end;
+
+procedure TParticle.LiveOn;
+begin
+ //Live = 0 => Live forever <blindy> ?? die werden doch aber im Manager bei Draw getötet, wenns 0 is
+ if (Live > 0) then
+ Dec(Live);
+
+ // animate frames
+ Frame := ( Frame + 1 ) mod 16;
+
+ // make our particles do funny stuff (besides being animated)
+ // changes of any particle-values throughout its life are done here
+ case StarType of
+ GoldenNote:
+ begin
+ Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
+ end;
+ PerfectNote:
+ begin
+ Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
+ end;
+ NoteHitTwinkle:
+ begin
+ Alpha := (Live/10); // linear fade-out
+ end;
+ PerfectLineTwinkle:
+ begin
+ Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
+ SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
+ // move around
+ X := X + mX;
+ Y := Y + mY;
+ end;
+ ColoredStar:
+ begin
+ Alpha := (-cos((Frame+1)*2*pi/16)+1); // neat fade-in-and-out
+ end;
+ Flare:
+ begin
+ Alpha := (-cos((Frame+1)/16*1.7*pi+0.3*pi)+1); // neat fade-in-and-out
+ SizeMod := (-cos((Frame+1)*5*2*pi/16)*0.5+1.1);
+ // move around
+ X := X + mX;
+ Y := Y + mY;
+ mY:=mY+1.8;
+// mX:=mX/2;
+ end;
+ end;
+end;
+
+procedure TParticle.Draw;
+var L: Cardinal;
+begin
+ if ScreenAct = Screen then
+ // this draws (multiple) texture(s) of our particle
+ for L:=0 to High(Col) do
+ begin
+ glColor4f(Col[L].r, Col[L].g, Col[L].b, Alpha);
+
+ glBindTexture(GL_TEXTURE_2D, Tex);
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ begin
+ glBegin(GL_QUADS);
+ glTexCoord2f((1/16) * Frame, 0); glVertex2f(X-W*Scale[L]*SizeMod, Y-H*Scale[L]*SizeMod);
+ glTexCoord2f((1/16) * Frame + (1/16), 0); glVertex2f(X-W*Scale[L]*SizeMod, Y+H*Scale[L]*SizeMod);
+ glTexCoord2f((1/16) * Frame + (1/16), 1); glVertex2f(X+W*Scale[L]*SizeMod, Y+H*Scale[L]*SizeMod);
+ glTexCoord2f((1/16) * Frame, 1); glVertex2f(X+W*Scale[L]*SizeMod, Y-H*Scale[L]*SizeMod);
+ glEnd;
+ end;
+ end;
+ glcolor4f(1,1,1,1);
+end;
+// end of TParticle
+
+// TEffectManager
+
+constructor TEffectManager.Create;
+var c: Cardinal;
+begin
+ inherited;
+ LastTime := GetTickCount;
+ for c:=0 to 5 do
+ begin
+ TwinkleArray[c] := 0;
+ end;
+end;
+
+destructor TEffectManager.Destroy;
+begin
+ Killall;
+ inherited;
+end;
+
+
+procedure TEffectManager.Draw;
+var
+ I: Integer;
+ CurrentTime: Cardinal;
+//const
+// DelayBetweenFrames : Cardinal = 100;
+begin
+
+ CurrentTime := GetTickCount;
+ //Manage particle life
+ if (CurrentTime - LastTime) > DelayBetweenFrames then
+ begin
+ LastTime := CurrentTime;
+ for I := 0 to high(Particle) do
+ Particle[I].LiveOn;
+ end;
+
+ I := 0;
+ //Kill dead particles
+ while (I <= High(Particle)) do
+ begin
+ if (Particle[I].Live <= 0) then
+ begin
+ kill(I);
+ end
+ else
+ begin
+ inc(I);
+ end;
+ end;
+
+ //Draw
+ for I := 0 to high(Particle) do
+ begin
+ Particle[I].Draw;
+ end;
+end;
+
+// this method creates just one particle
+function TEffectManager.Spawn(X, Y: Real; Screen: Integer; Live: Byte; StartFrame : Integer; RecArrayIndex : Integer; StarType : TParticleType; Player: Cardinal): Cardinal;
+begin
+ Result := Length(Particle);
+ SetLength(Particle, (Result + 1));
+ Particle[Result] := TParticle.Create(X, Y, Screen, Live, StartFrame, RecArrayIndex, StarType, Player);
+end;
+
+// manage Sparkling of GoldenNote Bars
+procedure TEffectManager.SpawnRec();
+Var
+ Xkatze, Ykatze : Real;
+ RandomFrame : Integer;
+ P : Integer; // P as seen on TV as Positionman
+begin
+//Spawn a random amount of stars within the given coordinates
+//RandomRange(0,14) <- this one starts at a random frame, 16 is our last frame - would be senseless to start a particle with 16, cause it would be dead at the next frame
+for P:= 0 to high(RecArray) do
+ begin
+ while (RecArray[P].TotalStarCount > RecArray[P].CurrentStarCount) do
+ begin
+ Xkatze := RandomRange(Ceil(RecArray[P].xTop), Ceil(RecArray[P].xBottom));
+ Ykatze := RandomRange(Ceil(RecArray[P].yTop), Ceil(RecArray[P].yBottom));
+ RandomFrame := RandomRange(0,14);
+ // Spawn a GoldenNote Particle
+ Spawn(Xkatze, Ykatze, RecArray[P].Screen, 16 - RandomFrame, RandomFrame, P, GoldenNote, 0);
+ inc(RecArray[P].CurrentStarCount);
+ end;
+ end;
+ draw;
+end;
+
+// kill one particle (with given index in our particle array)
+procedure TEffectManager.Kill(Index: Cardinal);
+var
+ LastParticleIndex : Integer;
+begin
+// delete particle indexed by Index,
+// overwrite it's place in our particle-array with the particle stored at the last array index,
+// shorten array
+ LastParticleIndex := high(Particle);
+ if not(LastParticleIndex = -1) then // is there still a particle to delete?
+ begin
+ if not(Particle[Index].RecIndex = -1) then // if it is a GoldenNote particle...
+ dec(RecArray[Particle[Index].RecIndex].CurrentStarCount); // take care of its associated GoldenRec
+ // now get rid of that particle
+ Particle[Index].Destroy;
+ Particle[Index] := Particle[LastParticleIndex];
+ SetLength(Particle, LastParticleIndex);
+ end;
+end;
+
+// clean up all particles and management structures
+procedure TEffectManager.KillAll();
+var c: Cardinal;
+begin
+//It's the kill all kennies rotuine
+ while Length(Particle) > 0 do // kill all existing particles
+ Kill(0);
+ SetLength(RecArray,0); // remove GoldenRec positions
+ SetLength(PerfNoteArray,0); // remove PerfectNote positions
+ for c:=0 to 5 do
+ begin
+ TwinkleArray[c] := 0; // reset GoldenNoteHit memory
+ end;
+end;
+
+procedure TEffectManager.SentenceChange();
+var c: Cardinal;
+begin
+ c:=0;
+ while c <= High(Particle) do
+ begin
+ if Particle[c].SurviveSentenceChange then
+ inc(c)
+ else
+ Kill(c);
+ end;
+ SetLength(RecArray,0); // remove GoldenRec positions
+ SetLength(PerfNoteArray,0); // remove PerfectNote positions
+ for c:=0 to 5 do
+ begin
+ TwinkleArray[c] := 0; // reset GoldenNoteHit memory
+ end;
+end;
+
+procedure TeffectManager.GoldenNoteTwinkle(Top,Bottom,Right: Real; Player: Integer);
+//Twinkle stars while golden note hit
+// this is called from UDraw.pas, SingDrawPlayerCzesc
+var
+ C, P, XKatze, YKatze, LKatze: Integer;
+ H: Real;
+begin
+ // make sure we spawn only one time at one position
+ if (TwinkleArray[Player] < Right) then
+ For P := 0 to high(RecArray) do // Are we inside a GoldenNoteRectangle?
+ begin
+ H := (Top+Bottom)/2; // helper...
+ with RecArray[P] do
+ if ((xBottom >= Right) and (xTop <= Right) and
+ (yTop <= H) and (yBottom >= H))
+ and (Screen = ScreenAct) then
+ begin
+ TwinkleArray[Player] := Right; // remember twinkle position for this player
+ for C := 1 to 10 do
+ begin
+ Ykatze := RandomRange(ceil(Top) , ceil(Bottom));
+ XKatze := RandomRange(-7,3);
+ LKatze := RandomRange(7,13);
+ Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
+ end;
+ for C := 1 to 3 do
+ begin
+ Ykatze := RandomRange(ceil(Top)-6 , ceil(Top));
+ XKatze := RandomRange(-5,1);
+ LKatze := RandomRange(4,7);
+ Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
+ end;
+ for C := 1 to 3 do
+ begin
+ Ykatze := RandomRange(ceil(Bottom), ceil(Bottom)+6);
+ XKatze := RandomRange(-5,1);
+ LKatze := RandomRange(4,7);
+ Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
+ end;
+ for C := 1 to 3 do
+ begin
+ Ykatze := RandomRange(ceil(Top)-10 , ceil(Top)-6);
+ XKatze := RandomRange(-5,1);
+ LKatze := RandomRange(1,4);
+ Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
+ end;
+ for C := 1 to 3 do
+ begin
+ Ykatze := RandomRange(ceil(Bottom)+6 , ceil(Bottom)+10);
+ XKatze := RandomRange(-5,1);
+ LKatze := RandomRange(1,4);
+ Spawn(Ceil(Right)+XKatze, YKatze, ScreenAct, LKatze, 0, -1, NoteHitTwinkle, 0);
+ end;
+
+ exit; // found a matching GoldenRec, did spawning stuff... done
+ end;
+ end;
+end;
+
+procedure TEffectManager.SaveGoldenStarsRec(Xtop, Ytop, Xbottom, Ybottom: Real);
+var
+ P : Integer; // P like used in Positions
+ NewIndex : Integer;
+begin
+ For P := 0 to high(RecArray) do // Do we already have that "new" position?
+ begin
+ if (ceil(RecArray[P].xTop) = ceil(Xtop)) and
+ (ceil(RecArray[P].yTop) = ceil(Ytop)) and
+ (ScreenAct = RecArray[p].Screen) then
+ exit; // it's already in the array, so we don't have to create a new one
+ end;
+
+ // we got a new position, add the new positions to our array
+ NewIndex := Length(RecArray);
+ SetLength(RecArray, NewIndex + 1);
+ RecArray[NewIndex].xTop := Xtop;
+ RecArray[NewIndex].yTop := Ytop;
+ RecArray[NewIndex].xBottom := Xbottom;
+ RecArray[NewIndex].yBottom := Ybottom;
+ RecArray[NewIndex].TotalStarCount := ceil(Xbottom - Xtop) div 12 + 3;
+ RecArray[NewIndex].CurrentStarCount := 0;
+ RecArray[NewIndex].Screen := ScreenAct;
+end;
+
+procedure TEffectManager.SavePerfectNotePos(Xtop, Ytop: Real);
+var
+ P : Integer; // P like used in Positions
+ NewIndex : Integer;
+ RandomFrame : Integer;
+ Xkatze, Ykatze : Integer;
+begin
+ For P := 0 to high(PerfNoteArray) do // Do we already have that "new" position?
+ begin
+ with PerfNoteArray[P] do
+ if (ceil(xPos) = ceil(Xtop)) and (ceil(yPos) = ceil(Ytop)) and
+ (Screen = ScreenAct) then
+ exit; // it's already in the array, so we don't have to create a new one
+ end; //for
+
+ // we got a new position, add the new positions to our array
+ NewIndex := Length(PerfNoteArray);
+ SetLength(PerfNoteArray, NewIndex + 1);
+ PerfNoteArray[NewIndex].xPos := Xtop;
+ PerfNoteArray[NewIndex].yPos := Ytop;
+ PerfNoteArray[NewIndex].Screen := ScreenAct;
+
+ for P:= 0 to 2 do
+ begin
+ Xkatze := RandomRange(ceil(Xtop) - 5 , ceil(Xtop) + 10);
+ Ykatze := RandomRange(ceil(Ytop) - 5 , ceil(Ytop) + 10);
+ RandomFrame := RandomRange(0,14);
+ Spawn(Xkatze, Ykatze, ScreenAct, 16 - RandomFrame, RandomFrame, -1, PerfectNote, 0);
+ end; //for
+
+end;
+
+procedure TEffectManager.SpawnPerfectLineTwinkle();
+var
+ P,I,Life: Cardinal;
+ Left, Right, Top, Bottom: Cardinal;
+ cScreen: Integer;
+begin
+// calculation of coordinates done with hardcoded values like in UDraw.pas
+// might need to be adjusted if drawing of SingScreen is modified
+// coordinates may still be a bit weird and need adjustment
+ if Ini.SingWindow = 0 then begin
+ Left := 130;
+ end else begin
+ Left := 30;
+ end;
+ Right := 770;
+ // spawn effect for every player with a perfect line
+ for P:=0 to PlayersPlay-1 do
+ if Player[P].LastSentencePerfect then
+ begin
+ // calculate area where notes of this player are drawn
+ case PlayersPlay of
+ 1: begin
+ Bottom:=Skin_P2_NotesB+10;
+ Top:=Bottom-105;
+ cScreen:=1;
+ end;
+ 2,4: begin
+ case P of
+ 0,2: begin
+ Bottom:=Skin_P1_NotesB+10;
+ Top:=Bottom-105;
+ end;
+ else begin
+ Bottom:=Skin_P2_NotesB+10;
+ Top:=Bottom-105;
+ end;
+ end;
+ case P of
+ 0,1: cScreen:=1;
+ else cScreen:=2;
+ end;
+ end;
+ 3,6: begin
+ case P of
+ 0,3: begin
+ Top:=130;
+ Bottom:=Top+85;
+ end;
+ 1,4: begin
+ Top:=255;
+ Bottom:=Top+85;
+ end;
+ 2,5: begin
+ Top:=380;
+ Bottom:=Top+85;
+ end;
+ end;
+ case P of
+ 0,1,2: cScreen:=1;
+ else cScreen:=2;
+ end;
+ end;
+ end;
+ // spawn Sparkling Stars inside calculated coordinates
+ for I:= 0 to 80 do
+ begin
+ Life:=RandomRange(8,16);
+ Spawn(RandomRange(Left,Right), RandomRange(Top,Bottom), cScreen, Life, 16-Life, -1, PerfectLineTwinkle, P);
+ end;
+ end;
+end;
+
+end.
+
diff --git a/Game/Code/Classes/UJoystick.pas b/Game/Code/Classes/UJoystick.pas
index b0c7b8cc..6b4ea63f 100644
--- a/Game/Code/Classes/UJoystick.pas
+++ b/Game/Code/Classes/UJoystick.pas
@@ -1,273 +1,282 @@
-unit UJoystick;
-
-interface
-
-uses SDL;
-
-type
- TJoyButton = record
- State: integer;
- Enabled: boolean;
- Type_: byte;
- Sym: cardinal;
- end;
-
- TJoyHatState = record
- State: Boolean;
- LastTick: Cardinal;
- Enabled: boolean;
- Type_: byte;
- Sym: cardinal;
- end;
-
- TJoyUnit = record
- Button: array[0..15] of TJoyButton;
- HatState: Array[0..3] of TJoyHatState;
- end;
-
- TJoy = class
- constructor Create;
- procedure Update;
- end;
-
-var
- Joy: TJoy;
- JoyUnit: TJoyUnit;
- SDL_Joy: PSDL_Joystick;
- JoyEvent: TSDL_Event;
-
-implementation
-
-uses SysUtils, Windows, ULog;
-
-constructor TJoy.Create;
-var
- B, N: integer;
-begin
- //Old Corvus5 Method
- {// joystick support
- SDL_JoystickEventState(SDL_IGNORE);
- SDL_InitSubSystem(SDL_INIT_JOYSTICK);
- if SDL_NumJoysticks <> 1 then beep;
-
- SDL_Joy := SDL_JoystickOpen(0);
- if SDL_Joy = nil then beep;
-
- if SDL_JoystickNumButtons(SDL_Joy) <> 16 then beep;
-
-// SDL_JoystickEventState(SDL_ENABLE);
- // Events don't work - thay hang the whole application with SDL_JoystickEventState(SDL_ENABLE)
-
- // clear states
- for B := 0 to 15 do
- JoyUnit.Button[B].State := 1;
-
- // mapping
- JoyUnit.Button[1].Enabled := true;
- JoyUnit.Button[1].Type_ := SDL_KEYDOWN;
- JoyUnit.Button[1].Sym := SDLK_RETURN;
- JoyUnit.Button[2].Enabled := true;
- JoyUnit.Button[2].Type_ := SDL_KEYDOWN;
- JoyUnit.Button[2].Sym := SDLK_ESCAPE;
-
- JoyUnit.Button[12].Enabled := true;
- JoyUnit.Button[12].Type_ := SDL_KEYDOWN;
- JoyUnit.Button[12].Sym := SDLK_LEFT;
- JoyUnit.Button[13].Enabled := true;
- JoyUnit.Button[13].Type_ := SDL_KEYDOWN;
- JoyUnit.Button[13].Sym := SDLK_DOWN;
- JoyUnit.Button[14].Enabled := true;
- JoyUnit.Button[14].Type_ := SDL_KEYDOWN;
- JoyUnit.Button[14].Sym := SDLK_RIGHT;
- JoyUnit.Button[15].Enabled := true;
- JoyUnit.Button[15].Type_ := SDL_KEYDOWN;
- JoyUnit.Button[15].Sym := SDLK_UP;
- }
- //New Sarutas method
- SDL_JoystickEventState(SDL_IGNORE);
- SDL_InitSubSystem(SDL_INIT_JOYSTICK);
- if SDL_NumJoysticks < 1 then
- begin
- Log.LogError('No Joystick found');
- exit;
- end;
-
-
- SDL_Joy := SDL_JoystickOpen(0);
- if SDL_Joy = nil then
- begin
- Log.LogError('Could not Init Joystick');
- exit;
- end;
- N := SDL_JoystickNumButtons(SDL_Joy);
- //if N < 6 then beep;
-
- for B := 0 to 5 do begin
- JoyUnit.Button[B].Enabled := true;
- JoyUnit.Button[B].State := 1;
- JoyUnit.Button[B].Type_ := SDL_KEYDOWN;
- end;
-
- JoyUnit.Button[0].Sym := SDLK_Return;
- JoyUnit.Button[1].Sym := SDLK_Escape;
- JoyUnit.Button[2].Sym := SDLK_M;
- JoyUnit.Button[3].Sym := SDLK_R;
-
- JoyUnit.Button[4].Sym := SDLK_RETURN;
- JoyUnit.Button[5].Sym := SDLK_ESCAPE;
-
- //Set HatState
- for B := 0 to 3 do begin
- JoyUnit.HatState[B].Enabled := true;
- JoyUnit.HatState[B].State := False;
- JoyUnit.HatState[B].Type_ := SDL_KEYDOWN;
- end;
-
- JoyUnit.HatState[0].Sym := SDLK_UP;
- JoyUnit.HatState[1].Sym := SDLK_RIGHT;
- JoyUnit.HatState[2].Sym := SDLK_DOWN;
- JoyUnit.HatState[3].Sym := SDLK_LEFT;
-end;
-
-procedure TJoy.Update;
-var
- B: integer;
- State: UInt8;
- Tick: Cardinal;
- Axes: Smallint;
-begin
- SDL_JoystickUpdate;
-
- //Manage Buttons
- for B := 0 to 15 do begin
- if (JoyUnit.Button[B].Enabled) and (JoyUnit.Button[B].State <> SDL_JoystickGetButton(SDL_Joy, B)) and (JoyUnit.Button[B].State = 0) then begin
- JoyEvent.type_ := JoyUnit.Button[B].Type_;
- JoyEvent.key.keysym.sym := JoyUnit.Button[B].Sym;
- SDL_PushEvent(@JoyEvent);
- end;
- end;
-
-
- for B := 0 to 15 do begin
- JoyUnit.Button[B].State := SDL_JoystickGetButton(SDL_Joy, B);
- end;
-
- //Get Tick
- Tick := Gettickcount;
-
- //Get CoolieHat
- if (SDL_JoystickNumHats(SDL_Joy)>=1) then
- State := SDL_JoystickGetHat(SDL_Joy, 0)
- else
- State := 0;
-
- //Get Axis
- if (SDL_JoystickNumAxes(SDL_Joy)>=2) then
- begin
- //Down - Up (X- Axis)
- Axes := SDL_JoystickGetAxis(SDL_Joy, 1);
- If Axes >= 15000 then
- State := State or SDL_HAT_Down
- Else If Axes <= -15000 then
- State := State or SDL_HAT_UP;
-
- //Left - Right (Y- Axis)
- Axes := SDL_JoystickGetAxis(SDL_Joy, 0);
- If Axes >= 15000 then
- State := State or SDL_HAT_Right
- Else If Axes <= -15000 then
- State := State or SDL_HAT_Left;
- end;
-
- //Manage Hat and joystick Events
- if (SDL_JoystickNumHats(SDL_Joy)>=1) OR (SDL_JoystickNumAxes(SDL_Joy)>=2) then
- begin
-
- //Up Button
- If (JoyUnit.HatState[0].Enabled) and ((SDL_HAT_UP AND State) = SDL_HAT_UP) then
- begin //IF Button is newly Pressed or if he is Pressed longer than 500 msecs
- if (JoyUnit.HatState[0].State = False) OR (JoyUnit.HatState[0].Lasttick < Tick) then
- begin
- //Set Tick and State
- if JoyUnit.HatState[0].State then
- JoyUnit.HatState[0].Lasttick := Tick + 200
- else
- JoyUnit.HatState[0].Lasttick := Tick + 500;
-
- JoyUnit.HatState[0].State := True;
-
- JoyEvent.type_ := JoyUnit.HatState[0].Type_;
- JoyEvent.key.keysym.sym := JoyUnit.HatState[0].Sym;
- SDL_PushEvent(@JoyEvent);
- end;
- end
- else
- JoyUnit.HatState[0].State := False;
-
- //Right Button
- If (JoyUnit.HatState[1].Enabled) and ((SDL_HAT_RIGHT AND State) = SDL_HAT_RIGHT) then
- begin //IF Button is newly Pressed or if he is Pressed longer than 500 msecs
- if (JoyUnit.HatState[1].State = False) OR (JoyUnit.HatState[1].Lasttick < Tick) then
- begin
- //Set Tick and State
- if JoyUnit.HatState[1].State then
- JoyUnit.HatState[1].Lasttick := Tick + 200
- else
- JoyUnit.HatState[1].Lasttick := Tick + 500;
-
- JoyUnit.HatState[1].State := True;
-
- JoyEvent.type_ := JoyUnit.HatState[1].Type_;
- JoyEvent.key.keysym.sym := JoyUnit.HatState[1].Sym;
- SDL_PushEvent(@JoyEvent);
- end;
- end
- else
- JoyUnit.HatState[1].State := False;
-
- //Down button
- If (JoyUnit.HatState[2].Enabled) and ((SDL_HAT_DOWN AND State) = SDL_HAT_DOWN) then
- begin //IF Button is newly Pressed or if he is Pressed longer than 230 msecs
- if (JoyUnit.HatState[2].State = False) OR (JoyUnit.HatState[2].Lasttick < Tick) then
- begin
- //Set Tick and State
- if JoyUnit.HatState[2].State then
- JoyUnit.HatState[2].Lasttick := Tick + 200
- else
- JoyUnit.HatState[2].Lasttick := Tick + 500;
-
- JoyUnit.HatState[2].State := True;
-
- JoyEvent.type_ := JoyUnit.HatState[2].Type_;
- JoyEvent.key.keysym.sym := JoyUnit.HatState[2].Sym;
- SDL_PushEvent(@JoyEvent);
- end;
- end
- else
- JoyUnit.HatState[2].State := False;
-
- //Left Button
- If (JoyUnit.HatState[3].Enabled) and ((SDL_HAT_LEFT AND State) = SDL_HAT_LEFT) then
- begin //IF Button is newly Pressed or if he is Pressed longer than 230 msecs
- if (JoyUnit.HatState[3].State = False) OR (JoyUnit.HatState[3].Lasttick < Tick) then
- begin
- //Set Tick and State
- if JoyUnit.HatState[3].State then
- JoyUnit.HatState[3].Lasttick := Tick + 200
- else
- JoyUnit.HatState[3].Lasttick := Tick + 500;
-
- JoyUnit.HatState[3].State := True;
-
- JoyEvent.type_ := JoyUnit.HatState[3].Type_;
- JoyEvent.key.keysym.sym := JoyUnit.HatState[3].Sym;
- SDL_PushEvent(@JoyEvent);
- end;
- end
- else
- JoyUnit.HatState[3].State := False;
- end;
-
-end;
-
-end.
+unit UJoystick;
+
+interface
+
+{$I switches.inc}
+
+
+uses SDL;
+
+type
+ TJoyButton = record
+ State: integer;
+ Enabled: boolean;
+ Type_: byte;
+ Sym: cardinal;
+ end;
+
+ TJoyHatState = record
+ State: Boolean;
+ LastTick: Cardinal;
+ Enabled: boolean;
+ Type_: byte;
+ Sym: cardinal;
+ end;
+
+ TJoyUnit = record
+ Button: array[0..15] of TJoyButton;
+ HatState: Array[0..3] of TJoyHatState;
+ end;
+
+ TJoy = class
+ constructor Create;
+ procedure Update;
+ end;
+
+var
+ Joy: TJoy;
+ JoyUnit: TJoyUnit;
+ SDL_Joy: PSDL_Joystick;
+ JoyEvent: TSDL_Event;
+
+implementation
+
+uses SysUtils,
+ {$IFDEF win32}
+ windows,
+ {$ELSE}
+ LCLIntf,
+ {$ENDIF}
+ ULog;
+
+constructor TJoy.Create;
+var
+ B, N: integer;
+begin
+ //Old Corvus5 Method
+ {// joystick support
+ SDL_JoystickEventState(SDL_IGNORE);
+ SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+ if SDL_NumJoysticks <> 1 then beep;
+
+ SDL_Joy := SDL_JoystickOpen(0);
+ if SDL_Joy = nil then beep;
+
+ if SDL_JoystickNumButtons(SDL_Joy) <> 16 then beep;
+
+// SDL_JoystickEventState(SDL_ENABLE);
+ // Events don't work - thay hang the whole application with SDL_JoystickEventState(SDL_ENABLE)
+
+ // clear states
+ for B := 0 to 15 do
+ JoyUnit.Button[B].State := 1;
+
+ // mapping
+ JoyUnit.Button[1].Enabled := true;
+ JoyUnit.Button[1].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[1].Sym := SDLK_RETURN;
+ JoyUnit.Button[2].Enabled := true;
+ JoyUnit.Button[2].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[2].Sym := SDLK_ESCAPE;
+
+ JoyUnit.Button[12].Enabled := true;
+ JoyUnit.Button[12].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[12].Sym := SDLK_LEFT;
+ JoyUnit.Button[13].Enabled := true;
+ JoyUnit.Button[13].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[13].Sym := SDLK_DOWN;
+ JoyUnit.Button[14].Enabled := true;
+ JoyUnit.Button[14].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[14].Sym := SDLK_RIGHT;
+ JoyUnit.Button[15].Enabled := true;
+ JoyUnit.Button[15].Type_ := SDL_KEYDOWN;
+ JoyUnit.Button[15].Sym := SDLK_UP;
+ }
+ //New Sarutas method
+ SDL_JoystickEventState(SDL_IGNORE);
+ SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+ if SDL_NumJoysticks < 1 then
+ begin
+ Log.LogError('No Joystick found');
+ exit;
+ end;
+
+
+ SDL_Joy := SDL_JoystickOpen(0);
+ if SDL_Joy = nil then
+ begin
+ Log.LogError('Could not Init Joystick');
+ exit;
+ end;
+ N := SDL_JoystickNumButtons(SDL_Joy);
+ //if N < 6 then beep;
+
+ for B := 0 to 5 do begin
+ JoyUnit.Button[B].Enabled := true;
+ JoyUnit.Button[B].State := 1;
+ JoyUnit.Button[B].Type_ := SDL_KEYDOWN;
+ end;
+
+ JoyUnit.Button[0].Sym := SDLK_Return;
+ JoyUnit.Button[1].Sym := SDLK_Escape;
+ JoyUnit.Button[2].Sym := SDLK_M;
+ JoyUnit.Button[3].Sym := SDLK_R;
+
+ JoyUnit.Button[4].Sym := SDLK_RETURN;
+ JoyUnit.Button[5].Sym := SDLK_ESCAPE;
+
+ //Set HatState
+ for B := 0 to 3 do begin
+ JoyUnit.HatState[B].Enabled := true;
+ JoyUnit.HatState[B].State := False;
+ JoyUnit.HatState[B].Type_ := SDL_KEYDOWN;
+ end;
+
+ JoyUnit.HatState[0].Sym := SDLK_UP;
+ JoyUnit.HatState[1].Sym := SDLK_RIGHT;
+ JoyUnit.HatState[2].Sym := SDLK_DOWN;
+ JoyUnit.HatState[3].Sym := SDLK_LEFT;
+end;
+
+procedure TJoy.Update;
+var
+ B: integer;
+ State: UInt8;
+ Tick: Cardinal;
+ Axes: Smallint;
+begin
+ SDL_JoystickUpdate;
+
+ //Manage Buttons
+ for B := 0 to 15 do begin
+ if (JoyUnit.Button[B].Enabled) and (JoyUnit.Button[B].State <> SDL_JoystickGetButton(SDL_Joy, B)) and (JoyUnit.Button[B].State = 0) then begin
+ JoyEvent.type_ := JoyUnit.Button[B].Type_;
+ JoyEvent.key.keysym.sym := JoyUnit.Button[B].Sym;
+ SDL_PushEvent(@JoyEvent);
+ end;
+ end;
+
+
+ for B := 0 to 15 do begin
+ JoyUnit.Button[B].State := SDL_JoystickGetButton(SDL_Joy, B);
+ end;
+
+ //Get Tick
+ Tick := Gettickcount;
+
+ //Get CoolieHat
+ if (SDL_JoystickNumHats(SDL_Joy)>=1) then
+ State := SDL_JoystickGetHat(SDL_Joy, 0)
+ else
+ State := 0;
+
+ //Get Axis
+ if (SDL_JoystickNumAxes(SDL_Joy)>=2) then
+ begin
+ //Down - Up (X- Axis)
+ Axes := SDL_JoystickGetAxis(SDL_Joy, 1);
+ If Axes >= 15000 then
+ State := State or SDL_HAT_Down
+ Else If Axes <= -15000 then
+ State := State or SDL_HAT_UP;
+
+ //Left - Right (Y- Axis)
+ Axes := SDL_JoystickGetAxis(SDL_Joy, 0);
+ If Axes >= 15000 then
+ State := State or SDL_HAT_Right
+ Else If Axes <= -15000 then
+ State := State or SDL_HAT_Left;
+ end;
+
+ //Manage Hat and joystick Events
+ if (SDL_JoystickNumHats(SDL_Joy)>=1) OR (SDL_JoystickNumAxes(SDL_Joy)>=2) then
+ begin
+
+ //Up Button
+ If (JoyUnit.HatState[0].Enabled) and ((SDL_HAT_UP AND State) = SDL_HAT_UP) then
+ begin //IF Button is newly Pressed or if he is Pressed longer than 500 msecs
+ if (JoyUnit.HatState[0].State = False) OR (JoyUnit.HatState[0].Lasttick < Tick) then
+ begin
+ //Set Tick and State
+ if JoyUnit.HatState[0].State then
+ JoyUnit.HatState[0].Lasttick := Tick + 200
+ else
+ JoyUnit.HatState[0].Lasttick := Tick + 500;
+
+ JoyUnit.HatState[0].State := True;
+
+ JoyEvent.type_ := JoyUnit.HatState[0].Type_;
+ JoyEvent.key.keysym.sym := JoyUnit.HatState[0].Sym;
+ SDL_PushEvent(@JoyEvent);
+ end;
+ end
+ else
+ JoyUnit.HatState[0].State := False;
+
+ //Right Button
+ If (JoyUnit.HatState[1].Enabled) and ((SDL_HAT_RIGHT AND State) = SDL_HAT_RIGHT) then
+ begin //IF Button is newly Pressed or if he is Pressed longer than 500 msecs
+ if (JoyUnit.HatState[1].State = False) OR (JoyUnit.HatState[1].Lasttick < Tick) then
+ begin
+ //Set Tick and State
+ if JoyUnit.HatState[1].State then
+ JoyUnit.HatState[1].Lasttick := Tick + 200
+ else
+ JoyUnit.HatState[1].Lasttick := Tick + 500;
+
+ JoyUnit.HatState[1].State := True;
+
+ JoyEvent.type_ := JoyUnit.HatState[1].Type_;
+ JoyEvent.key.keysym.sym := JoyUnit.HatState[1].Sym;
+ SDL_PushEvent(@JoyEvent);
+ end;
+ end
+ else
+ JoyUnit.HatState[1].State := False;
+
+ //Down button
+ If (JoyUnit.HatState[2].Enabled) and ((SDL_HAT_DOWN AND State) = SDL_HAT_DOWN) then
+ begin //IF Button is newly Pressed or if he is Pressed longer than 230 msecs
+ if (JoyUnit.HatState[2].State = False) OR (JoyUnit.HatState[2].Lasttick < Tick) then
+ begin
+ //Set Tick and State
+ if JoyUnit.HatState[2].State then
+ JoyUnit.HatState[2].Lasttick := Tick + 200
+ else
+ JoyUnit.HatState[2].Lasttick := Tick + 500;
+
+ JoyUnit.HatState[2].State := True;
+
+ JoyEvent.type_ := JoyUnit.HatState[2].Type_;
+ JoyEvent.key.keysym.sym := JoyUnit.HatState[2].Sym;
+ SDL_PushEvent(@JoyEvent);
+ end;
+ end
+ else
+ JoyUnit.HatState[2].State := False;
+
+ //Left Button
+ If (JoyUnit.HatState[3].Enabled) and ((SDL_HAT_LEFT AND State) = SDL_HAT_LEFT) then
+ begin //IF Button is newly Pressed or if he is Pressed longer than 230 msecs
+ if (JoyUnit.HatState[3].State = False) OR (JoyUnit.HatState[3].Lasttick < Tick) then
+ begin
+ //Set Tick and State
+ if JoyUnit.HatState[3].State then
+ JoyUnit.HatState[3].Lasttick := Tick + 200
+ else
+ JoyUnit.HatState[3].Lasttick := Tick + 500;
+
+ JoyUnit.HatState[3].State := True;
+
+ JoyEvent.type_ := JoyUnit.HatState[3].Type_;
+ JoyEvent.key.keysym.sym := JoyUnit.HatState[3].Sym;
+ SDL_PushEvent(@JoyEvent);
+ end;
+ end
+ else
+ JoyUnit.HatState[3].State := False;
+ end;
+
+end;
+
+end.
diff --git a/Game/Code/Classes/ULanguage.pas b/Game/Code/Classes/ULanguage.pas
index f693694b..679f6405 100644
--- a/Game/Code/Classes/ULanguage.pas
+++ b/Game/Code/Classes/ULanguage.pas
@@ -1,234 +1,236 @@
-unit ULanguage;
-
-interface
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-
-type
- TLanguageEntry = record
- ID: string;
- Text: string;
- end;
-
- TLanguageList = record
- Name: string;
- {FileName: string; }
- end;
-
- TLanguage = class
- public
- Entry: array of TLanguageEntry; //Entrys of Chosen Language
- SEntry: array of TLanguageEntry; //Entrys of Standard Language
- CEntry: array of TLanguageEntry; //Constant Entrys e.g. Version
- Implode_Glue1, Implode_Glue2: String;
- public
- List: array of TLanguageList;
-
- constructor Create;
- procedure LoadList;
- function Translate(Text: String): String;
- procedure ChangeLanguage(Language: String);
- procedure AddConst(ID, Text: String);
- procedure ChangeConst(ID, Text: String);
- function Implode(Pieces: Array of String): String;
- end;
-
-var
- Language: TLanguage;
-
-implementation
-
-uses UMain,
- // UFiles,
- UIni,
- IniFiles,
- Classes,
- SysUtils,
- Windows,
- ULog;
-
-//----------
-//Create - Construct Class then LoadList + Standard Language + Set Standard Implode Glues
-//----------
-constructor TLanguage.Create;
-var
- I, J: Integer;
-begin
- LoadList;
-
- //Set Implode Glues for Backward Compatibility
- Implode_Glue1 := ', ';
- Implode_Glue2 := ' and ';
-
- if (Length(List) = 0) then //No Language Files Loaded -> Abort Loading
- Log.CriticalError('Could not load any Language File');
-
- //Standard Language (If a Language File is Incomplete)
- //Then use English Language
- for I := 0 to high(List) do //Search for English Language
- begin
- //English Language Found -> Load
- if Uppercase(List[I].Name) = 'ENGLISH' then
- begin
- ChangeLanguage('English');
-
- SetLength(SEntry, Length(Entry));
- for J := low(Entry) to high(Entry) do
- SEntry[J] := Entry[J];
-
- SetLength(Entry, 0);
-
- Break;
- end;
-
- if (I = high(List)) then
- Log.LogError('English Languagefile missing! No standard Translation loaded');
- end;
- //Standard Language END
-
-end;
-
-//----------
-//LoadList - Parse the Language Dir searching Translations
-//----------
-procedure TLanguage.LoadList;
-var
- SR: TSearchRec; // for parsing directory
-begin
- SetLength(List, 0);
- SetLength(ILanguage, 0);
-
- if FindFirst(LanguagesPath + '*.ini', 0, SR) = 0 then begin
- repeat
- SetLength(List, Length(List)+1);
- SetLength(ILanguage, Length(ILanguage)+1);
- SR.Name := ChangeFileExt(SR.Name, '');
-
- List[High(List)].Name := SR.Name;
- ILanguage[High(ILanguage)] := SR.Name;
-
- until FindNext(SR) <> 0;
- SysUtils.FindClose(SR);
- end; // if FindFirst
-end;
-
-//----------
-//ChangeLanguage - Load the specified LanguageFile
-//----------
-procedure TLanguage.ChangeLanguage(Language: String);
-var
- IniFile: TIniFile;
- E: integer; // entry
- S: TStringList;
-begin
- SetLength(Entry, 0);
- IniFile := TIniFile.Create(LanguagesPath + Language + '.ini');
- S := TStringList.Create;
-
- IniFile.ReadSectionValues('Text', S);
- SetLength(Entry, S.Count);
- for E := 0 to high(Entry) do
- begin
- if S.Names[E] = 'IMPLODE_GLUE1' then
- Implode_Glue1 := S.ValueFromIndex[E]+ ' '
- else if S.Names[E] = 'IMPLODE_GLUE2' then
- Implode_Glue2 := ' ' + S.ValueFromIndex[E] + ' ';
-
- Entry[E].ID := S.Names[E];
- Entry[E].Text := S.ValueFromIndex[E];
- end;
-
- S.Free;
- IniFile.Free;
-end;
-
-//----------
-//Translate - Translate the Text
-//----------
-Function TLanguage.Translate(Text: String): String;
-var
- E: integer; // entry
-begin
- Result := Text;
- Text := Uppercase(Result);
-
- //Const Mod
- for E := 0 to high(CEntry) do
- if Text = CEntry[E].ID then
- begin
- Result := CEntry[E].Text;
- exit;
- end;
- //Const Mod End
-
- for E := 0 to high(Entry) do
- if Text = Entry[E].ID then
- begin
- Result := Entry[E].Text;
- exit;
- end;
-
- //Standard Language (If a Language File is Incomplete)
- //Then use Standard Language
- for E := low(SEntry) to high(SEntry) do
- if Text = SEntry[E].ID then
- begin
- Result := SEntry[E].Text;
- Break;
- end;
- //Standard Language END
-end;
-
-//----------
-//AddConst - Add a Constant ID that will be Translated but not Loaded from the LanguageFile
-//----------
-procedure TLanguage.AddConst (ID, Text: String);
-begin
- SetLength (CEntry, Length(CEntry) + 1);
- CEntry[high(CEntry)].ID := ID;
- CEntry[high(CEntry)].Text := Text;
-end;
-
-//----------
-//ChangeConst - Change a Constant Value by ID
-//----------
-procedure TLanguage.ChangeConst(ID, Text: String);
-var
- I: Integer;
-begin
- for I := 0 to high(CEntry) do
- begin
- if CEntry[I].ID = ID then
- begin
- CEntry[I].Text := Text;
- Break;
- end;
- end;
-end;
-
-//----------
-//Implode - Connect an Array of Strings with ' and ' or ', ' to one String
-//----------
-function TLanguage.Implode(Pieces: Array of String): String;
-var
- I: Integer;
-begin
- Result := '';
- //Go through Pieces
- for I := low(Pieces) to high(Pieces) do
- begin
- //Add Value
- Result := Result + Pieces[I];
-
- //Add Glue
- if (I < high(Pieces) - 1) then
- Result := Result + Implode_Glue1
- else if (I < high(Pieces)) then
- Result := Result + Implode_Glue2;
- end;
-end;
-
-end.
+unit ULanguage;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+{$ENDIF}
+
+
+type
+ TLanguageEntry = record
+ ID: string;
+ Text: string;
+ end;
+
+ TLanguageList = record
+ Name: string;
+ {FileName: string; }
+ end;
+
+ TLanguage = class
+ public
+ Entry: array of TLanguageEntry; //Entrys of Chosen Language
+ SEntry: array of TLanguageEntry; //Entrys of Standard Language
+ CEntry: array of TLanguageEntry; //Constant Entrys e.g. Version
+ Implode_Glue1, Implode_Glue2: String;
+ public
+ List: array of TLanguageList;
+
+ constructor Create;
+ procedure LoadList;
+ function Translate(Text: String): String;
+ procedure ChangeLanguage(Language: String);
+ procedure AddConst(ID, Text: String);
+ procedure ChangeConst(ID, Text: String);
+ function Implode(Pieces: Array of String): String;
+ end;
+
+var
+ Language: TLanguage;
+
+implementation
+
+uses UMain,
+ // UFiles,
+ UIni,
+ IniFiles,
+ Classes,
+ SysUtils,
+ {$IFDEF win32}
+ windows,
+ {$ENDIF}
+ ULog;
+
+//----------
+//Create - Construct Class then LoadList + Standard Language + Set Standard Implode Glues
+//----------
+constructor TLanguage.Create;
+var
+ I, J: Integer;
+begin
+ LoadList;
+
+ //Set Implode Glues for Backward Compatibility
+ Implode_Glue1 := ', ';
+ Implode_Glue2 := ' and ';
+
+ if (Length(List) = 0) then //No Language Files Loaded -> Abort Loading
+ Log.CriticalError('Could not load any Language File');
+
+ //Standard Language (If a Language File is Incomplete)
+ //Then use English Language
+ for I := 0 to high(List) do //Search for English Language
+ begin
+ //English Language Found -> Load
+ if Uppercase(List[I].Name) = 'ENGLISH' then
+ begin
+ ChangeLanguage('English');
+
+ SetLength(SEntry, Length(Entry));
+ for J := low(Entry) to high(Entry) do
+ SEntry[J] := Entry[J];
+
+ SetLength(Entry, 0);
+
+ Break;
+ end;
+
+ if (I = high(List)) then
+ Log.LogError('English Languagefile missing! No standard Translation loaded');
+ end;
+ //Standard Language END
+
+end;
+
+//----------
+//LoadList - Parse the Language Dir searching Translations
+//----------
+procedure TLanguage.LoadList;
+var
+ SR: TSearchRec; // for parsing directory
+begin
+ SetLength(List, 0);
+ SetLength(ILanguage, 0);
+
+ if FindFirst(LanguagesPath + '*.ini', 0, SR) = 0 then begin
+ repeat
+ SetLength(List, Length(List)+1);
+ SetLength(ILanguage, Length(ILanguage)+1);
+ SR.Name := ChangeFileExt(SR.Name, '');
+
+ List[High(List)].Name := SR.Name;
+ ILanguage[High(ILanguage)] := SR.Name;
+
+ until FindNext(SR) <> 0;
+ SysUtils.FindClose(SR);
+ end; // if FindFirst
+end;
+
+//----------
+//ChangeLanguage - Load the specified LanguageFile
+//----------
+procedure TLanguage.ChangeLanguage(Language: String);
+var
+ IniFile: TIniFile;
+ E: integer; // entry
+ S: TStringList;
+begin
+ SetLength(Entry, 0);
+ IniFile := TIniFile.Create(LanguagesPath + Language + '.ini');
+ S := TStringList.Create;
+
+ IniFile.ReadSectionValues('Text', S);
+ SetLength(Entry, S.Count);
+ for E := 0 to high(Entry) do
+ begin
+ if S.Names[E] = 'IMPLODE_GLUE1' then
+ Implode_Glue1 := S.ValueFromIndex[E]+ ' '
+ else if S.Names[E] = 'IMPLODE_GLUE2' then
+ Implode_Glue2 := ' ' + S.ValueFromIndex[E] + ' ';
+
+ Entry[E].ID := S.Names[E];
+ Entry[E].Text := S.ValueFromIndex[E];
+ end;
+
+ S.Free;
+ IniFile.Free;
+end;
+
+//----------
+//Translate - Translate the Text
+//----------
+Function TLanguage.Translate(Text: String): String;
+var
+ E: integer; // entry
+begin
+ Result := Text;
+ Text := Uppercase(Result);
+
+ //Const Mod
+ for E := 0 to high(CEntry) do
+ if Text = CEntry[E].ID then
+ begin
+ Result := CEntry[E].Text;
+ exit;
+ end;
+ //Const Mod End
+
+ for E := 0 to high(Entry) do
+ if Text = Entry[E].ID then
+ begin
+ Result := Entry[E].Text;
+ exit;
+ end;
+
+ //Standard Language (If a Language File is Incomplete)
+ //Then use Standard Language
+ for E := low(SEntry) to high(SEntry) do
+ if Text = SEntry[E].ID then
+ begin
+ Result := SEntry[E].Text;
+ Break;
+ end;
+ //Standard Language END
+end;
+
+//----------
+//AddConst - Add a Constant ID that will be Translated but not Loaded from the LanguageFile
+//----------
+procedure TLanguage.AddConst (ID, Text: String);
+begin
+ SetLength (CEntry, Length(CEntry) + 1);
+ CEntry[high(CEntry)].ID := ID;
+ CEntry[high(CEntry)].Text := Text;
+end;
+
+//----------
+//ChangeConst - Change a Constant Value by ID
+//----------
+procedure TLanguage.ChangeConst(ID, Text: String);
+var
+ I: Integer;
+begin
+ for I := 0 to high(CEntry) do
+ begin
+ if CEntry[I].ID = ID then
+ begin
+ CEntry[I].Text := Text;
+ Break;
+ end;
+ end;
+end;
+
+//----------
+//Implode - Connect an Array of Strings with ' and ' or ', ' to one String
+//----------
+function TLanguage.Implode(Pieces: Array of String): String;
+var
+ I: Integer;
+begin
+ Result := '';
+ //Go through Pieces
+ for I := low(Pieces) to high(Pieces) do
+ begin
+ //Add Value
+ Result := Result + Pieces[I];
+
+ //Add Glue
+ if (I < high(Pieces) - 1) then
+ Result := Result + Implode_Glue1
+ else if (I < high(Pieces)) then
+ Result := Result + Implode_Glue2;
+ end;
+end;
+
+end.
diff --git a/Game/Code/Classes/ULight.pas b/Game/Code/Classes/ULight.pas
index 74681a85..99edc88c 100644
--- a/Game/Code/Classes/ULight.pas
+++ b/Game/Code/Classes/ULight.pas
@@ -1,149 +1,162 @@
-unit ULight;
-interface
-{$I switches.inc}
-
-type
- TLight = class
- private
- Enabled: boolean;
- Light: array[0..7] of boolean;
- LightTime: array[0..7] of real; // time to stop, need to call update to change state
- LastTime: real;
- public
- constructor Create;
- procedure Enable;
- procedure SetState(State: integer);
- procedure AutoSetState;
- procedure TurnOn;
- procedure TurnOff;
- procedure LightOne(Number: integer; Time: real);
- procedure Refresh;
- end;
-
-var
- Light: TLight;
-
-const
- Data = $378; // default port address
- Status = Data + 1;
- Control = Data + 2;
-
-implementation
-
-uses
- SysUtils,
- {$IFDEF UseSerialPort}
- zlportio,
- {$ENDIF}
- UTime;
-
-{$IFDEF FPC}
- function GetTime: TDateTime;
- {$IFDEF MSWINDOWS}
- var
- SystemTime: TSystemTime;
- begin
- GetLocalTime(SystemTime);
- with SystemTime do
- Result := EncodeTime(wHour, wMinute, wSecond, wMilliSeconds);
- end;
- {$ENDIF}
- {$IFDEF LINUX}
- var
- T: TTime_T;
- TV: TTimeVal;
- UT: TUnixTime;
- begin
- gettimeofday(TV, nil);
- T := TV.tv_sec;
- localtime_r(@T, UT);
- Result := EncodeTime(UT.tm_hour, UT.tm_min, UT.tm_sec, TV.tv_usec div 1000);
- end;
- {$ENDIF}
-{$ENDIF}
-
-
-constructor TLight.Create;
-begin
- Enabled := false;
-end;
-
-procedure TLight.Enable;
-begin
- Enabled := true;
- LastTime := GetTime;
-end;
-
-procedure TLight.SetState(State: integer);
-begin
- {$IFDEF UseSerialPort}
- if Enabled then
- PortWriteB($378, State);
- {$ENDIF}
-end;
-
-procedure TLight.AutoSetState;
-var
- State: integer;
-begin
- if Enabled then begin
- State := 0;
- if Light[0] then State := State + 2;
- if Light[1] then State := State + 1;
- // etc
- SetState(State);
- end;
-end;
-
-procedure TLight.TurnOn;
-begin
- if Enabled then
- SetState(3);
-end;
-
-procedure TLight.TurnOff;
-begin
- if Enabled then
- SetState(0);
-end;
-
-procedure TLight.LightOne(Number: integer; Time: real);
-begin
- if Enabled then begin
- if Light[Number] = false then begin
- Light[Number] := true;
- AutoSetState;
- end;
-
- LightTime[Number] := GetTime + Time/1000; // [s]
- end;
-end;
-
-procedure TLight.Refresh;
-var
- Time: real;
-// TimeSkip: real;
- L: integer;
-begin
- if Enabled then begin
- Time := GetTime;
-// TimeSkip := Time - LastTime;
- for L := 0 to 7 do begin
- if Light[L] = true then begin
- if LightTime[L] > Time then begin
- // jest jeszcze zapas - bez zmian
- //LightTime[L] := LightTime[L] - TimeSkip;
- end else begin
- // czas minal
- Light[L] := false;
- end;
- end;
- end;
- LastTime := Time;
- AutoSetState;
- end;
-end;
-
-end.
-
-
+unit ULight;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+type
+ TLight = class
+ private
+ Enabled: boolean;
+ Light: array[0..7] of boolean;
+ LightTime: array[0..7] of real; // time to stop, need to call update to change state
+ LastTime: real;
+ public
+ constructor Create;
+ procedure Enable;
+ procedure SetState(State: integer);
+ procedure AutoSetState;
+ procedure TurnOn;
+ procedure TurnOff;
+ procedure LightOne(Number: integer; Time: real);
+ procedure Refresh;
+ end;
+
+var
+ Light: TLight;
+
+const
+ Data = $378; // default port address
+ Status = Data + 1;
+ Control = Data + 2;
+
+implementation
+
+uses
+ SysUtils,
+ {$IFDEF UseSerialPort}
+ zlportio,
+ {$ENDIF}
+ {$IFNDEF win32}
+ libc,
+ {$ENDIF}
+ UTime;
+
+{$IFDEF FPC}
+
+ function GetTime: TDateTime;
+ {$IFDEF win32}
+ var
+ SystemTime: TSystemTime;
+ begin
+ GetLocalTime(SystemTime);
+ with SystemTime do
+ Result := EncodeTime(wHour, wMinute, wSecond, wMilliSeconds);
+ end;
+ {$ELSE}
+ Type
+ Time_t = longint;
+ TTime_T = Time_t;
+ var
+ T : TTime_T;
+ TV: TTimeVal;
+ UT: TUnixTime;
+ begin
+ gettimeofday(TV, nil);
+ T := TV.tv_sec;
+ localtime_r(@T, @UT);
+ Result := EncodeTime(UT.tm_hour, UT.tm_min, UT.tm_sec, TV.tv_usec div 1000);
+ end;
+ {$ENDIF}
+
+{$ENDIF}
+
+
+constructor TLight.Create;
+begin
+ Enabled := false;
+end;
+
+procedure TLight.Enable;
+begin
+ Enabled := true;
+ LastTime := GetTime;
+end;
+
+procedure TLight.SetState(State: integer);
+begin
+ {$IFDEF UseSerialPort}
+ if Enabled then
+ PortWriteB($378, State);
+ {$ENDIF}
+end;
+
+procedure TLight.AutoSetState;
+var
+ State: integer;
+begin
+ if Enabled then begin
+ State := 0;
+ if Light[0] then State := State + 2;
+ if Light[1] then State := State + 1;
+ // etc
+ SetState(State);
+ end;
+end;
+
+procedure TLight.TurnOn;
+begin
+ if Enabled then
+ SetState(3);
+end;
+
+procedure TLight.TurnOff;
+begin
+ if Enabled then
+ SetState(0);
+end;
+
+procedure TLight.LightOne(Number: integer; Time: real);
+begin
+ if Enabled then begin
+ if Light[Number] = false then begin
+ Light[Number] := true;
+ AutoSetState;
+ end;
+
+ LightTime[Number] := GetTime + Time/1000; // [s]
+ end;
+end;
+
+procedure TLight.Refresh;
+var
+ Time: real;
+// TimeSkip: real;
+ L: integer;
+begin
+ if Enabled then begin
+ Time := GetTime;
+// TimeSkip := Time - LastTime;
+ for L := 0 to 7 do begin
+ if Light[L] = true then begin
+ if LightTime[L] > Time then begin
+ // jest jeszcze zapas - bez zmian
+ //LightTime[L] := LightTime[L] - TimeSkip;
+ end else begin
+ // czas minal
+ Light[L] := false;
+ end;
+ end;
+ end;
+ LastTime := Time;
+ AutoSetState;
+ end;
+end;
+
+end.
+
+
diff --git a/Game/Code/Classes/ULog.pas b/Game/Code/Classes/ULog.pas
index d03ad8ed..7c93c6e9 100644
--- a/Game/Code/Classes/ULog.pas
+++ b/Game/Code/Classes/ULog.pas
@@ -1,243 +1,253 @@
-unit ULog;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-uses Classes;
-
-type
- TLog = class
- BenchmarkTimeStart: array[0..7] of real;
- BenchmarkTimeLength: array[0..7] of real;//TDateTime;
-
- FileBenchmark: TextFile;
- FileBenchmarkO: boolean; // opened
- FileError: TextFile;
- FileErrorO: boolean; // opened
-
- Title: String; //Application Title
-
- //Should Log Files be written
- Enabled: Boolean;
-
- // destuctor
- destructor Free;
-
- // benchmark
- procedure BenchmarkStart(Number: integer);
- procedure BenchmarkEnd(Number: integer);
- procedure LogBenchmark(Text: string; Number: integer);
-
- // error
- procedure LogError(Text: string); overload;
-
- //Critical Error (Halt + MessageBox)
- procedure CriticalError(Text: string);
-
- // voice
- procedure LogVoice(SoundNr: integer);
-
- // compability
- procedure LogStatus(Log1, Log2: string);
- procedure LogError(Log1, Log2: string); overload;
- end;
-
-var
- Log: TLog;
-
-implementation
-
-uses
- Windows,
- SysUtils,
- DateUtils,
-// UFiles,
- UMain,
- URecord,
- UTime,
-// UIni, // JB - Seems to not be needed.
- UCommandLine;
-
-destructor TLog.Free;
-begin
- if FileBenchmarkO then CloseFile(FileBenchmark);
-// if FileAnalyzeO then CloseFile(FileAnalyze);
- if FileErrorO then CloseFile(FileError);
-end;
-
-procedure TLog.BenchmarkStart(Number: integer);
-begin
- BenchmarkTimeStart[Number] := USTime.GetTime; //Time;
-end;
-
-procedure TLog.BenchmarkEnd(Number: integer);
-begin
- BenchmarkTimeLength[Number] := USTime.GetTime {Time} - BenchmarkTimeStart[Number];
-end;
-
-procedure TLog.LogBenchmark(Text: string; Number: integer);
-var
- Minutes: integer;
- Seconds: integer;
- Miliseconds: integer;
-
- MinutesS: string;
- SecondsS: string;
- MilisecondsS: string;
-
- ValueText: string;
-begin
- if Enabled AND (Params.Benchmark) then begin
- if not FileBenchmarkO then begin
- FileBenchmarkO := true;
- AssignFile(FileBenchmark, LogPath + 'Benchmark.log');
- {$I-}
- Rewrite(FileBenchmark);
- if IOResult = 0 then FileBenchmarkO := true;
- {$I+}
-
- //If File is opened write Date to Benchmark File
- If (FileBenchmarkO) then
- begin
- WriteLn(FileBenchmark, Title + ' Benchmark File');
- WriteLn(FileBenchmark, 'Date: ' + DatetoStr(Now) + ' Time: ' + TimetoStr(Now));
- WriteLn(FileBenchmark, '-------------------');
-
- Flush(FileBenchmark);
- end;
- end;
-
- if FileBenchmarkO then begin
- Miliseconds := Trunc(Frac(BenchmarkTimeLength[Number]) * 1000);
- Seconds := Trunc(BenchmarkTimeLength[Number]) mod 60;
- Minutes := Trunc((BenchmarkTimeLength[Number] - Seconds) / 60);
-// ValueText := FloatToStr(BenchmarkTimeLength[Number]);
-
-{ ValueText := FloatToStr(
- SecondOf(BenchmarkTimeLength[Number]) + MilliSecondOf(BenchmarkTimeLength[Number])/1000
- );
- if MinuteOf(BenchmarkTimeLength[Number]) >= 1 then
- ValueText := IntToStr(MinuteOf(BenchmarkTimeLength[Number])) + ':' + ValueText;
- WriteLn(FileBenchmark, Text + ': ' + ValueText + ' seconds');}
-
- if (Minutes = 0) and (Seconds = 0) then begin
- MilisecondsS := IntToStr(Miliseconds);
- ValueText := MilisecondsS + ' miliseconds';
- end;
-
- if (Minutes = 0) and (Seconds >= 1) then begin
- MilisecondsS := IntToStr(Miliseconds);
- while Length(MilisecondsS) < 3 do MilisecondsS := '0' + MilisecondsS;
-
- SecondsS := IntToStr(Seconds);
-
- ValueText := SecondsS + ',' + MilisecondsS + ' seconds';
- end;
-
- if Minutes >= 1 then begin
- MilisecondsS := IntToStr(Miliseconds);
- while Length(MilisecondsS) < 3 do MilisecondsS := '0' + MilisecondsS;
-
- SecondsS := IntToStr(Seconds);
- while Length(SecondsS) < 2 do SecondsS := '0' + SecondsS;
-
- MinutesS := IntToStr(Minutes);
-
- ValueText := MinutesS + ':' + SecondsS + ',' + MilisecondsS + ' minutes';
- end;
-
- WriteLn(FileBenchmark, Text + ': ' + ValueText);
- Flush(FileBenchmark);
- end;
- end;
-end;
-
-procedure TLog.LogError(Text: string);
-begin
- if Enabled AND (not FileErrorO) then begin
- FileErrorO := true;
- AssignFile(FileError, LogPath + 'Error.log');
- {$I-}
- Rewrite(FileError);
- if IOResult = 0 then FileErrorO := true;
- {$I+}
-
- //If File is opened write Date to Error File
- If (FileErrorO) then
- begin
- WriteLn(FileError, Title + ' Error Log');
- WriteLn(FileError, 'Date: ' + DatetoStr(Now) + ' Time: ' + TimetoStr(Now));
- WriteLn(FileError, '-------------------');
-
- Flush(FileError);
- end;
- end;
-
- if FileErrorO then begin
- try
- WriteLn(FileError, Text);
- Flush(FileError);
- except
- FileErrorO := false;
- end;
- end;
-end;
-
-procedure TLog.LogVoice(SoundNr: integer);
-var
- FileVoice: File;
- FS: TFileStream;
- FileName: string;
- Num: integer;
- BL: integer;
-begin
- for Num := 1 to 9999 do begin
- FileName := IntToStr(Num);
- while Length(FileName) < 4 do FileName := '0' + FileName;
- FileName := LogPath + 'Voice' + FileName + '.raw';
- if not FileExists(FileName) then break
- end;
-
-
- FS := TFileStream.Create(FileName, fmCreate);
-
- for BL := 0 to High(Sound[SoundNr].BufferLong) do begin
- Sound[SoundNr].BufferLong[BL].Seek(0, soBeginning);
- FS.CopyFrom(Sound[SoundNr].BufferLong[BL], Sound[SoundNr].BufferLong[BL].Size);
- end;
-
- FS.Free;
-end;
-
-procedure TLog.LogStatus(Log1, Log2: string);
-begin
- //Just for Debugging
- //Comment for Release
- //LogAnalyze (Log2 + ': ' + Log1);
-
- LogError(Log2 + ': ' + Log1);
-end;
-
-procedure TLog.LogError(Log1, Log2: string);
-begin
-//asd
-end;
-
-procedure TLog.CriticalError(Text: string);
-begin
- //Write Error to Logfile:
- LogError (Text);
-
- //Show Errormessage
- Messagebox(0, PChar(Text), PChar(Title), MB_ICONERROR or MB_OK);
-
- //Exit Application
- Halt;
-end;
-
-end.
-
-
+unit ULog;
+
+interface
+
+{$I switches.inc}
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+uses Classes;
+
+type
+ TLog = class
+ BenchmarkTimeStart: array[0..7] of real;
+ BenchmarkTimeLength: array[0..7] of real;//TDateTime;
+
+ FileBenchmark: TextFile;
+ FileBenchmarkO: boolean; // opened
+ FileError: TextFile;
+ FileErrorO: boolean; // opened
+
+ Title: String; //Application Title
+
+ //Should Log Files be written
+ Enabled: Boolean;
+
+ // destuctor
+ destructor Free;
+
+ // benchmark
+ procedure BenchmarkStart(Number: integer);
+ procedure BenchmarkEnd(Number: integer);
+ procedure LogBenchmark(Text: string; Number: integer);
+
+ // error
+ procedure LogError(Text: string); overload;
+
+ //Critical Error (Halt + MessageBox)
+ procedure CriticalError(Text: string);
+
+ // voice
+ procedure LogVoice(SoundNr: integer);
+
+ // compability
+ procedure LogStatus(Log1, Log2: string);
+ procedure LogError(Log1, Log2: string); overload;
+ end;
+
+var
+ Log: TLog;
+
+implementation
+
+uses
+ {$IFDEF win32}
+ windows,
+ {$ENDIF}
+ SysUtils,
+ DateUtils,
+// UFiles,
+ UMain,
+ URecord,
+ UTime,
+// UIni, // JB - Seems to not be needed.
+ UCommandLine;
+
+destructor TLog.Free;
+begin
+ if FileBenchmarkO then CloseFile(FileBenchmark);
+// if FileAnalyzeO then CloseFile(FileAnalyze);
+ if FileErrorO then CloseFile(FileError);
+end;
+
+procedure TLog.BenchmarkStart(Number: integer);
+begin
+ BenchmarkTimeStart[Number] := USTime.GetTime; //Time;
+end;
+
+procedure TLog.BenchmarkEnd(Number: integer);
+begin
+ BenchmarkTimeLength[Number] := USTime.GetTime {Time} - BenchmarkTimeStart[Number];
+end;
+
+procedure TLog.LogBenchmark(Text: string; Number: integer);
+var
+ Minutes: integer;
+ Seconds: integer;
+ Miliseconds: integer;
+
+ MinutesS: string;
+ SecondsS: string;
+ MilisecondsS: string;
+
+ ValueText: string;
+begin
+ if Enabled AND (Params.Benchmark) then begin
+ if not FileBenchmarkO then begin
+ FileBenchmarkO := true;
+ AssignFile(FileBenchmark, LogPath + 'Benchmark.log');
+ {$I-}
+ Rewrite(FileBenchmark);
+ if IOResult = 0 then FileBenchmarkO := true;
+ {$I+}
+
+ //If File is opened write Date to Benchmark File
+ If (FileBenchmarkO) then
+ begin
+ WriteLn(FileBenchmark, Title + ' Benchmark File');
+ WriteLn(FileBenchmark, 'Date: ' + DatetoStr(Now) + ' Time: ' + TimetoStr(Now));
+ WriteLn(FileBenchmark, '-------------------');
+
+ Flush(FileBenchmark);
+ end;
+ end;
+
+ if FileBenchmarkO then begin
+ Miliseconds := Trunc(Frac(BenchmarkTimeLength[Number]) * 1000);
+ Seconds := Trunc(BenchmarkTimeLength[Number]) mod 60;
+ Minutes := Trunc((BenchmarkTimeLength[Number] - Seconds) / 60);
+// ValueText := FloatToStr(BenchmarkTimeLength[Number]);
+
+{ ValueText := FloatToStr(
+ SecondOf(BenchmarkTimeLength[Number]) + MilliSecondOf(BenchmarkTimeLength[Number])/1000
+ );
+ if MinuteOf(BenchmarkTimeLength[Number]) >= 1 then
+ ValueText := IntToStr(MinuteOf(BenchmarkTimeLength[Number])) + ':' + ValueText;
+ WriteLn(FileBenchmark, Text + ': ' + ValueText + ' seconds');}
+
+ if (Minutes = 0) and (Seconds = 0) then begin
+ MilisecondsS := IntToStr(Miliseconds);
+ ValueText := MilisecondsS + ' miliseconds';
+ end;
+
+ if (Minutes = 0) and (Seconds >= 1) then begin
+ MilisecondsS := IntToStr(Miliseconds);
+ while Length(MilisecondsS) < 3 do MilisecondsS := '0' + MilisecondsS;
+
+ SecondsS := IntToStr(Seconds);
+
+ ValueText := SecondsS + ',' + MilisecondsS + ' seconds';
+ end;
+
+ if Minutes >= 1 then begin
+ MilisecondsS := IntToStr(Miliseconds);
+ while Length(MilisecondsS) < 3 do MilisecondsS := '0' + MilisecondsS;
+
+ SecondsS := IntToStr(Seconds);
+ while Length(SecondsS) < 2 do SecondsS := '0' + SecondsS;
+
+ MinutesS := IntToStr(Minutes);
+
+ ValueText := MinutesS + ':' + SecondsS + ',' + MilisecondsS + ' minutes';
+ end;
+
+ WriteLn(FileBenchmark, Text + ': ' + ValueText);
+ Flush(FileBenchmark);
+ end;
+ end;
+end;
+
+procedure TLog.LogError(Text: string);
+begin
+ if Enabled AND (not FileErrorO) then begin
+ FileErrorO := true;
+ AssignFile(FileError, LogPath + 'Error.log');
+ {$I-}
+ Rewrite(FileError);
+ if IOResult = 0 then FileErrorO := true;
+ {$I+}
+
+ //If File is opened write Date to Error File
+ If (FileErrorO) then
+ begin
+ WriteLn(FileError, Title + ' Error Log');
+ WriteLn(FileError, 'Date: ' + DatetoStr(Now) + ' Time: ' + TimetoStr(Now));
+ WriteLn(FileError, '-------------------');
+
+ Flush(FileError);
+ end;
+ end;
+
+ if FileErrorO then begin
+ try
+ WriteLn(FileError, Text);
+ Flush(FileError);
+ except
+ FileErrorO := false;
+ end;
+ end;
+end;
+
+procedure TLog.LogVoice(SoundNr: integer);
+var
+ FileVoice: File;
+ FS: TFileStream;
+ FileName: string;
+ Num: integer;
+ BL: integer;
+begin
+ for Num := 1 to 9999 do begin
+ FileName := IntToStr(Num);
+ while Length(FileName) < 4 do FileName := '0' + FileName;
+ FileName := LogPath + 'Voice' + FileName + '.raw';
+ if not FileExists(FileName) then break
+ end;
+
+
+ FS := TFileStream.Create(FileName, fmCreate);
+
+ for BL := 0 to High(Sound[SoundNr].BufferLong) do begin
+ Sound[SoundNr].BufferLong[BL].Seek(0, soBeginning);
+ FS.CopyFrom(Sound[SoundNr].BufferLong[BL], Sound[SoundNr].BufferLong[BL].Size);
+ end;
+
+ FS.Free;
+end;
+
+procedure TLog.LogStatus(Log1, Log2: string);
+begin
+ //Just for Debugging
+ //Comment for Release
+ //LogAnalyze (Log2 + ': ' + Log1);
+
+ LogError(Log2 + ': ' + Log1);
+end;
+
+procedure TLog.LogError(Log1, Log2: string);
+begin
+//asd
+end;
+
+procedure TLog.CriticalError(Text: string);
+begin
+ //Write Error to Logfile:
+ LogError (Text);
+
+ {$IFDEF win32}
+ //Show Errormessage
+ Messagebox(0, PChar(Text), PChar(Title), MB_ICONERROR or MB_OK);
+ {$ELSE}
+ // TODO - JB_Linux handle critical error so user can see message.
+ writeln( 'Critical ERROR :' );
+ writeln( Text );
+ {$ENDIF}
+
+ //Exit Application
+ Halt;
+end;
+
+end.
+
+
diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas
index 646724df..f06345ec 100644
--- a/Game/Code/Classes/UMain.pas
+++ b/Game/Code/Classes/UMain.pas
@@ -1,781 +1,792 @@
-unit UMain;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses SDL, UGraphic, UMusic, URecord, UTime, SysUtils, UDisplay, UIni, ULog, ULyrics, UScreenSing,
- OpenGL12,
-
- {$IFDEF UseSerialPort}
- zlportio {you can disable it and all PortWriteB calls},
- {$ENDIF}
-
- ULCD, ULight, UThemes{, UScreenPopup};
-
-type
- TPlayer = record
- Name: string;
-
- Score: real;
- ScoreLine: real;
- ScoreGolden: real;
-
- ScoreI: integer;
- ScoreLineI: integer;
- ScoreGoldenI: integer;
- ScoreTotalI: integer;
-
-
-
- //SingBar Mod
- ScoreLast: Real;//Last Line Score
- ScorePercent: integer;//Aktual Fillstate of the SingBar
- ScorePercentTarget: integer;//Target Fillstate of the SingBar
- //end Singbar Mod
-
- //PhrasenBonus - Line Bonus Mod
- LineBonus_PosX: Single;
- LineBonus_PosY: Single;
- LineBonus_Alpha: Single;
- LineBonus_Visible: boolean;
- LineBonus_Text: string;
- LineBonus_Color: TRGB;
- LineBonus_Age: Integer;
- LineBonus_Rating: Integer;
- //Variable vor Positioning -> Set on ScreenShow, different when Playercount Changes
- LineBonus_TargetX: integer;
- LineBonus_TargetY: integer;
- LineBonus_StartX: integer;
- LineBonus_StartY: integer;
- //PhrasenBonus - Line Bonus Mod End
-
- //PerfectLineTwinkle Mod (effect)
- LastSentencePerfect: Boolean;
- //PerfectLineTwinkle Mod end
-
-
-// Meter: real;
-
- HighNut: integer;
- IlNut: integer;
- Nuta: array of record
- Start: integer;
- Dlugosc: integer;
- Detekt: real; // dokladne miejsce, w ktorym wykryto ta nute
- Ton: real;
- Perfect: boolean; // true if the note matches the original one, lit the star
-
-
-
- // Half size Notes Patch
- Hit: boolean; // true if the note Hits the Line
- //end Half size Notes Patch
-
-
-
- end;
- end;
-
-
-var
- //Absolute Paths
- GamePath: string;
- SoundPath: string;
- SongPath: string;
- LogPath: string;
- ThemePath: string;
- ScreenshotsPath: string;
- CoversPath: string;
- LanguagesPath: string;
- PluginPath: string;
- PlayListPath: string;
-
- OGL: Boolean;
- Done: Boolean;
- Event: TSDL_event;
- FileName: string;
- Restart: boolean;
-
- // gracz i jego nuty
- Player: array of TPlayer;
- PlayersPlay: integer;
-
-procedure InitializePaths;
-
-procedure MainLoop;
-procedure CheckEvents;
-procedure Sing(Sender: TScreenSing);
-procedure NewSentence(Sender: TScreenSing);
-procedure NewBeat(Sender: TScreenSing); // executed when on then new beat
-procedure NewBeatC(Sender: TScreenSing); // executed when on then new beat for click
-procedure NewBeatD(Sender: TScreenSing); // executed when on then new beat for detection
-//procedure NewHalf; // executed when in the half between beats
-procedure NewNote(Sender: TScreenSing); // detect note
-function GetMidBeat(Time: real): real;
-function GetTimeFromBeat(Beat: integer): real;
-procedure ClearScores(PlayerNum: integer);
-
-implementation
-uses USongs, UJoystick, math, UCommandLine;
-
-procedure MainLoop;
-var
- Delay: integer;
-begin
- SDL_EnableKeyRepeat(125, 125);
- While not Done do
- Begin
- // joypad
- if (Ini.Joypad = 1) OR (Params.Joypad) then
- Joy.Update;
-
- // keyboard events
- CheckEvents;
-
- // display
- done := not Display.Draw;
- SwapBuffers;
-
- // light
- Light.Refresh;
-
- // delay
- CountMidTime;
-// if 1000*TimeMid > 100 then beep;
- Delay := Floor(1000 / 100 - 1000 * TimeMid);
- if Delay >= 1 then
- SDL_Delay(Delay); // dynamic, maximum is 100 fps
- CountSkipTime;
-
- // reinitialization of graphics
- if Restart then begin
- Reinitialize3D;
- Restart := false;
- end;
-
- End;
- UnloadOpenGL;
-End;
-
-Procedure CheckEvents;
-//var
-// p: pointer;
-Begin
- if not Assigned(Display.NextScreen) then
- While SDL_PollEvent( @event ) = 1 Do
- Begin
-// beep;
- Case Event.type_ Of
- SDL_QUITEV: begin
- Display.Fade := 0;
- Display.NextScreenWithCheck := nil;
- Display.CheckOK := True;
- end;
-{ SDL_MOUSEBUTTONDOWN:
- With Event.button Do
- Begin
- If State = SDL_BUTTON_LEFT Then
- Begin
- //
- End;
- End; // With}
- SDL_KEYDOWN:
- begin
- //ScreenShot hack. If Print is pressed-> Make screenshot and Save to Screenshots Path
- if (Event.key.keysym.sym = SDLK_SYSREQ) then
- Display.ScreenShot
-
- // popup hack... if there is a visible popup then let it handle input instead of underlying screen
- // shoud be done in a way to be sure the topmost popup has preference (maybe error, then check)
- else if (ScreenPopupError <> NIL) and (ScreenPopupError.Visible) then
- done := not ScreenPopupError.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True)
- else if (ScreenPopupCheck <> NIL) AND (ScreenPopupCheck.Visible) then
- done := not ScreenPopupCheck.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True)
- // end of popup hack
-
- else
- begin
- // check for Screen want to Exit
- done := Not Display.ActualScreen^.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True);
-
- //If Screen wants to Exit
- if done then
- begin
- //If Question Option is enabled then Show Exit Popup
- if (Ini.AskbeforeDel = 1) then
- begin
- Display.ActualScreen^.CheckFadeTo(NIL,'MSG_QUIT_USDX');
- end
- else //When asking for exit is disabled then simply exit
- begin
- Display.Fade := 0;
- Display.NextScreenWithCheck := nil;
- Display.CheckOK := True;
- end;
- end;
-
- end; // if (Not Display.ActualScreen^.ParseInput(Event.key.keysym.scancode, True)) then
- end;
-// SDL_JOYAXISMOTION:
-// begin
-// beep
-// end;
- SDL_JOYBUTTONDOWN:
- begin
- beep
- end;
- End; // Case Event.type_
- End; // While
-End; // CheckEvents
-
-function GetTimeForBeats(BPM, Beats: real): real;
-begin
- Result := 60 / BPM * Beats;
-end;
-
-function GetBeats(BPM, msTime: real): real;
-begin
- Result := BPM * msTime / 60;
-end;
-
-procedure GetMidBeatSub(BPMNum: integer; var Time: real; var CurBeat: real);
-var
- NewTime: real;
-begin
- if High(AktSong.BPM) = BPMNum then begin
- // last BPM
- CurBeat := AktSong.BPM[BPMNum].StartBeat + GetBeats(AktSong.BPM[BPMNum].BPM, Time);
- Time := 0;
- end else begin
- // not last BPM
- // count how much time is it for start of the new BPM and store it in NewTime
- NewTime := GetTimeForBeats(AktSong.BPM[BPMNum].BPM, AktSong.BPM[BPMNum+1].StartBeat - AktSong.BPM[BPMNum].StartBeat);
-
- // compare it to remaining time
- if (Time - NewTime) > 0 then begin
- // there is still remaining time
- CurBeat := AktSong.BPM[BPMNum].StartBeat;
- Time := Time - NewTime;
- end else begin
- // there is no remaining time
- CurBeat := AktSong.BPM[BPMNum].StartBeat + GetBeats(AktSong.BPM[BPMNum].BPM, Time);
- Time := 0;
- end; // if
- end; // if
-end;
-
-function GetMidBeat(Time: real): real;
-var
- CurBeat: real;
- CurBPM: integer;
-// TopBeat: real;
-// TempBeat: real;
-// TempTime: real;
-begin
- Result := 0;
- if Length(AktSong.BPM) = 1 then Result := Time * AktSong.BPM[0].BPM / 60;
-
- (* 2 BPMs *)
-{ if Length(AktSong.BPM) > 1 then begin
- (* new system *)
- CurBeat := 0;
- TopBeat := GetBeats(AktSong.BPM[0].BPM, Time);
- if TopBeat > AktSong.BPM[1].StartBeat then begin
- // analyze second BPM
- Time := Time - GetTimeForBeats(AktSong.BPM[0].BPM, AktSong.BPM[1].StartBeat - CurBeat);
- CurBeat := AktSong.BPM[1].StartBeat;
- TopBeat := GetBeats(AktSong.BPM[1].BPM, Time);
- Result := CurBeat + TopBeat;
-
- end else begin
- (* pierwszy przedzial *)
- Result := TopBeat;
- end;
- end; // if}
-
- (* more BPMs *)
- if Length(AktSong.BPM) > 1 then begin
-
- CurBeat := 0;
- CurBPM := 0;
- while (Time > 0) do begin
- GetMidBeatSub(CurBPM, Time, CurBeat);
- Inc(CurBPM);
- end;
-
- Result := CurBeat;
- end; // if
-end;
-
-function GetTimeFromBeat(Beat: integer): real;
-var
- CurBPM: integer;
-begin
- Result := 0;
- if Length(AktSong.BPM) = 1 then Result := AktSong.GAP / 1000 + Beat * 60 / AktSong.BPM[0].BPM;
-
- (* more BPMs *)
- if Length(AktSong.BPM) > 1 then begin
- Result := AktSong.GAP / 1000;
- CurBPM := 0;
- while (CurBPM <= High(AktSong.BPM)) and (Beat > AktSong.BPM[CurBPM].StartBeat) do begin
- if (CurBPM < High(AktSong.BPM)) and (Beat >= AktSong.BPM[CurBPM+1].StartBeat) then begin
- // full range
- Result := Result + (60 / AktSong.BPM[CurBPM].BPM) * (AktSong.BPM[CurBPM+1].StartBeat - AktSong.BPM[CurBPM].StartBeat);
- end;
-
- if (CurBPM = High(AktSong.BPM)) or (Beat < AktSong.BPM[CurBPM+1].StartBeat) then begin
- // in the middle
- Result := Result + (60 / AktSong.BPM[CurBPM].BPM) * (Beat - AktSong.BPM[CurBPM].StartBeat);
- end;
- Inc(CurBPM);
- end;
-
-{ while (Time > 0) do begin
- GetMidBeatSub(CurBPM, Time, CurBeat);
- Inc(CurBPM);
- end;}
- end; // if}
-end;
-
-procedure Sing(Sender: TScreenSing);
-var
- Pet: integer;
- PetGr: integer;
- CP: integer;
- Done: real;
- N: integer;
-begin
- Czas.Teraz := Czas.Teraz + TimeSkip;
-
- Czas.OldBeat := Czas.AktBeat;
- Czas.MidBeat := GetMidBeat(Czas.Teraz - (AktSong.Gap{ + 90 I've forgotten for what it is}) / 1000); // new system with variable BPM in function
- Czas.AktBeat := Floor(Czas.MidBeat);
-
-// Czas.OldHalf := Czas.AktHalf;
-// Czas.MidHalf := Czas.MidBeat + 0.5;
-// Czas.AktHalf := Floor(Czas.MidHalf);
-
- Czas.OldBeatC := Czas.AktBeatC;
- Czas.MidBeatC := GetMidBeat(Czas.Teraz - (AktSong.Gap) / 1000);
- Czas.AktBeatC := Floor(Czas.MidBeatC);
-
- Czas.OldBeatD := Czas.AktBeatD;
- Czas.MidBeatD := -0.5+GetMidBeat(Czas.Teraz - (AktSong.Gap + 120 + 20) / 1000); // MidBeat with addition GAP
- Czas.AktBeatD := Floor(Czas.MidBeatD);
- Czas.FracBeatD := Frac(Czas.MidBeatD);
-
- // sentences routines
- for PetGr := 0 to 0 do begin;//High(Gracz) do begin
- CP := PetGr;
- // ustawianie starej czesci
- Czas.OldCzesc := Czesci[CP].Akt;
-
- // wybieranie aktualnej czesci
- for Pet := 0 to Czesci[CP].High do
- if Czas.AktBeat >= Czesci[CP].Czesc[Pet].Start then Czesci[CP].Akt := Pet;
-
- // czysczenie nut gracza, gdy to jest nowa plansza
- // (optymizacja raz na halfbeat jest zla)
- if Czesci[CP].Akt <> Czas.OldCzesc then NewSentence(Sender);
-
- end; // for PetGr
-
- // wykonuje operacje raz na beat
- if (Czas.AktBeat >= 0) and (Czas.OldBeat <> Czas.AktBeat) then
- NewBeat(Sender);
-
- // make some operations on clicks
- if {(Czas.AktBeatC >= 0) and }(Czas.OldBeatC <> Czas.AktBeatC) then
- NewBeatC(Sender);
-
- // make some operations when detecting new voice pitch
- if (Czas.AktBeatD >= 0) and (Czas.OldBeatD <> Czas.AktBeatD) then
- NewBeatD(Sender);
-
- // wykonuje operacje w polowie beatu
-// if (Czas.AktHalf >= 1) and (Czas.OldHalf <> Czas.AktHalf) then
-// NewHalf;
-
- // plynnie przesuwa text
- Done := 1;
- for N := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
- if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start <= Czas.MidBeat)
- and (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start + Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc >= Czas.MidBeat) then
- Done := (Czas.MidBeat - Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start) / (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc);
-
- N := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
-
- // wylacza ostatnia nute po przejsciu
- if (Ini.LyricsEffect = 1) and (Done = 1) and
- (Czas.MidBeat > Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start + Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc)
- then Sender.LyricMain.Selected := -1;
-
- if Done > 1 then Done := 1;
- Sender.LyricMain.Done := Done;
-
- // use Done with LCD
-{ with ScreenSing do begin
- if LyricMain.Selected >= 0 then begin
- LCD.MoveCursor(1, LyricMain.SelectedLetter + Round((LyricMain.SelectedLength-1) * Done));
- LCD.ShowCursor;
- end;
- end;}
-
-
-end;
-
-procedure NewSentence(Sender: TScreenSing);
-var
-G: Integer;
-begin
- // czyszczenie nut graczy
- for G := 0 to High(Player) do begin
- Player[G].IlNut := 0;
- Player[G].HighNut := -1;
- SetLength(Player[G].Nuta, 0);
- end;
-
- // wstawianie tekstow
- with Sender do begin
- LyricMain.AddCzesc(Czesci[0].Akt);
- if Czesci[0].Akt < Czesci[0].High then
- LyricSub.AddCzesc(Czesci[0].Akt+1)
- else
- LyricSub.Clear;
- end;
-
- Sender.UpdateLCD;
-
- //On Sentence Change...
- Sender.onSentenceChange(Czesci[0].Akt);
-end;
-
-procedure NewBeat(Sender: TScreenSing);
-var
- Pet: integer;
-// TempBeat: integer;
-begin
- // ustawia zaznaczenie tekstu
-// SingScreen.LyricMain.Selected := -1;
- for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
- if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeat) then begin
- // operates on currently beated note
- Sender.LyricMain.Selected := Pet;
-
-// LCD.MoveCursor(1, ScreenSing.LyricMain.SelectedLetter);
-// LCD.ShowCursor;
-
- LCD.MoveCursorBR(Sender.LyricMain.SelectedLetter);
- LCD.ShowCursor;
-
- end;
-end;
-
-procedure NewBeatC;
-var
- Pet: integer;
-// LPT_1: integer;
-// LPT_2: integer;
-begin
-// LPT_1 := 1;
-// LPT_2 := 1;
-
- // beat click
- if (Ini.BeatClick = 1) and ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod Czesci[0].Resolution = 0) then
- Music.PlayClick;
-
- // debug system on LPT
- if ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod Czesci[0].Resolution = 0) then begin
- //LPT_1 := 0;
-// Light.LightOne(0, 150);
-
- Light.LightOne(1, 200); // beat light
- if ParamStr(1) = '-doublelights' then
- Light.LightOne(0, 200); // beat light
-
-
-{ if ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod (Czesci[0].Resolution * 2) = 0) then
- Light.LightOne(0, 150)
- else
- Light.LightOne(1, 150)}
- end;
-
- for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
- if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeatC) then begin
- // click assist
- if Ini.ClickAssist = 1 then
- Music.PlayClick;
-
- //LPT_2 := 0;
- if ParamStr(1) <> '-doublelights' then
- Light.LightOne(0, 150); //125
-
-
- // drum machine
-(* TempBeat := Czas.AktBeat;// + 2;
- if (TempBeat mod 8 = 0) then Music.PlayDrum;
- if (TempBeat mod 8 = 4) then Music.PlayClap;
-// if (TempBeat mod 4 = 2) then Music.PlayHihat;
- if (TempBeat mod 4 <> 0) then Music.PlayHihat;*)
- end;
-
- {$IFDEF UseSerialPort}
- // PortWriteB($378, LPT_1 + LPT_2 * 2); // 0 zapala
- {$ENDIF}
-end;
-
-procedure NewBeatD(Sender: TScreenSing);
-begin
- NewNote(Sender);
-end;
-
-//procedure NewHalf;
-//begin
-// NewNote;
-//end;
-
-procedure NewNote(Sender: TScreenSing);
-var
- CP: integer; // current player
- S: integer; // sentence
- SMin: integer;
- SMax: integer;
- SDet: integer; // temporary: sentence of detected note
- Pet: integer;
- Mozna: boolean;
- Nowa: boolean;
- Range: integer;
- NoteHit:boolean;
-begin
-// Log.LogStatus('Beat ' + IntToStr(Czas.AktBeat) + ' HalfBeat ' + IntToStr(Czas.AktHalf), 'NewBeat');
-// beep;
-
- // analizuje dla obu graczy ten sam sygnal (Sound.OneSrcForBoth)
- // albo juz lepiej nie
- for CP := 0 to PlayersPlay-1 do begin
-
- // analyze buffer
- Sound[CP].AnalizujBufor;
-
- // adds some noise
-// Czas.Ton := Czas.Ton + Round(Random(3)) - 1;
-
- // 0.5.0: count min and max sentence range for checking (detection is delayed to the notes we see on the screen)
- SMin := Czesci[0].Akt-1;
- if SMin < 0 then SMin := 0;
- SMax := Czesci[0].Akt;
-
- // check if we can add new note
- Mozna := false;
- SDet:=SMin;
- for S := SMin to SMax do
- for Pet := 0 to Czesci[0].Czesc[S].HighNut do
- if ((Czesci[0].Czesc[S].Nuta[Pet].Start <= Czas.AktBeatD)
- and (Czesci[0].Czesc[S].Nuta[Pet].Start + Czesci[0].Czesc[S].Nuta[Pet].Dlugosc - 1 >= Czas.AktBeatD))
- and (not Czesci[0].Czesc[S].Nuta[Pet].FreeStyle) // but don't allow when it's FreeStyle note
- and (Czesci[0].Czesc[S].Nuta[Pet].Dlugosc > 0) // and make sure the note lenghts is at least 1
- then begin
- SDet := S;
- Mozna := true;
- Break;
- end;
-
- S := SDet;
-
-
-
-
-
-// Czas.SzczytJest := true;
-// Czas.Ton := 27;
-
- // gdy moze, to dodaje nute
- if (Sound[CP].SzczytJest) and (Mozna) then begin
- // operowanie na ostatniej nucie
- for Pet := 0 to Czesci[0].Czesc[S].HighNut do
- if (Czesci[0].Czesc[S].Nuta[Pet].Start <= Czas.OldBeatD+1)
- and (Czesci[0].Czesc[S].Nuta[Pet].Start +
- Czesci[0].Czesc[S].Nuta[Pet].Dlugosc > Czas.OldBeatD+1) then begin
- // to robi, tylko dla pary nut (oryginalnej i gracza)
-
- // przesuwanie tonu w odpowiednia game
- while (Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton > 6) do
- Sound[CP].Ton := Sound[CP].Ton - 12;
- while (Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton < -6) do
- Sound[CP].Ton := Sound[CP].Ton + 12;
-
- // Half size Notes Patch
- NoteHit := false;
-
- //if Ini.Difficulty = 0 then Range := 2;
- //if Ini.Difficulty = 1 then Range := 1;
- //if Ini.Difficulty = 2 then Range := 0;
- Range := 2 - Ini.Difficulty;
- if abs(Czesci[0].Czesc[S].Nuta[Pet].Ton - Sound[CP].Ton) <= Range then begin
- Sound[CP].Ton := Czesci[0].Czesc[S].Nuta[Pet].Ton;
-
-
- // Half size Notes Patch
- NoteHit := true;
-
-
- if (Ini.LineBonus = 0) then
- begin
- // add points without LineBonus
- case Czesci[0].Czesc[S].Nuta[Pet].Wartosc of
- 1: Player[CP].Score := Player[CP].Score + 10000 / Czesci[0].Wartosc *
- Czesci[0].Czesc[S].Nuta[Pet].Wartosc;
- 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 10000 / Czesci[0].Wartosc *
- Czesci[0].Czesc[S].Nuta[Pet].Wartosc;
- end;
- end
- else
- begin
- // add points with Line Bonus
- case Czesci[0].Czesc[S].Nuta[Pet].Wartosc of
- 1: Player[CP].Score := Player[CP].Score + 9000 / Czesci[0].Wartosc *
- Czesci[0].Czesc[S].Nuta[Pet].Wartosc;
- 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 9000 / Czesci[0].Wartosc *
- Czesci[0].Czesc[S].Nuta[Pet].Wartosc;
- end;
- end;
-
- Player[CP].ScoreI := Floor(Player[CP].Score / 10) * 10;
- Player[CP].ScoreGoldenI := Floor(Player[CP].ScoreGolden / 10) * 10;
-
- Player[CP].ScoreTotalI := Player[CP].ScoreI + Player[CP].ScoreGoldenI + Player[CP].ScoreLineI;
- end;
-
- end; // operowanie
-
- // sprawdzanie czy to nowa nuta, czy przedluzenie
- if S = SMax then begin
- Nowa := true;
- // jezeli ostatnia ma ten sam ton
- if (Player[CP].IlNut > 0 ) and (Player[CP].Nuta[Player[CP].HighNut].Ton = Sound[CP].Ton)
- and (Player[CP].Nuta[Player[CP].HighNut].Start + Player[CP].Nuta[Player[CP].HighNut].Dlugosc = Czas.AktBeatD)
- then Nowa := false;
- // jezeli jest jakas nowa nuta na sprawdzanym beacie
- for Pet := 0 to Czesci[0].Czesc[S].HighNut do
- if (Czesci[0].Czesc[S].Nuta[Pet].Start = Czas.AktBeatD) then
- Nowa := true;
-
- // dodawanie nowej nuty
- if Nowa then begin
- // nowa nuta
- Player[CP].IlNut := Player[CP].IlNut + 1;
- Player[CP].HighNut := Player[CP].HighNut + 1;
- SetLength(Player[CP].Nuta, Player[CP].IlNut);
- Player[CP].Nuta[Player[CP].HighNut].Start := Czas.AktBeatD;
- Player[CP].Nuta[Player[CP].HighNut].Dlugosc := 1;
- Player[CP].Nuta[Player[CP].HighNut].Ton := Sound[CP].Ton; // Ton || TonDokl
- Player[CP].Nuta[Player[CP].HighNut].Detekt := Czas.MidBeat;
-
-
- // Half Note Patch
- Player[CP].Nuta[Player[CP].HighNut].Hit := NoteHit;
-
-
- // Log.LogStatus('Nowa Nuta ' + IntToStr(Gracz.Nuta[Gracz.HighNut].Start), 'NewBeat');
-
- end else begin
- // przedluzenie nuty
- Player[CP].Nuta[Player[CP].HighNut].Dlugosc := Player[CP].Nuta[Player[CP].HighNut].Dlugosc + 1;
- end;
-
-
- // check for perfect note and then lit the star (on Draw)
- for Pet := 0 to Czesci[0].Czesc[S].HighNut do
- if (Czesci[0].Czesc[S].Nuta[Pet].Start = Player[CP].Nuta[Player[CP].HighNut].Start)
- and (Czesci[0].Czesc[S].Nuta[Pet].Dlugosc = Player[CP].Nuta[Player[CP].HighNut].Dlugosc)
- and (Czesci[0].Czesc[S].Nuta[Pet].Ton = Player[CP].Nuta[Player[CP].HighNut].Ton) then begin
- Player[CP].Nuta[Player[CP].HighNut].Perfect := true;
- end;
-
- end;// else beep; // if S = SMax
-
- end; // if moze
- end; // for CP
-// Log.LogStatus('EndBeat', 'NewBeat');
-
-//On Sentence End -> For LineBonus + SingBar
-if (sDet >= low(Czesci[0].Czesc)) AND (sDet <= high(Czesci[0].Czesc)) then
-if ((Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Start + Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Dlugosc - 1) = Czas.AktBeatD) then
- Sender.onSentenceEnd(sDet);
-
-end;
-
-procedure ClearScores(PlayerNum: integer);
-begin
- Player[PlayerNum].Score := 0;
- Player[PlayerNum].ScoreI := 0;
- Player[PlayerNum].ScoreLine := 0;
- Player[PlayerNum].ScoreLineI := 0;
- Player[PlayerNum].ScoreGolden := 0;
- Player[PlayerNum].ScoreGoldenI := 0;
- Player[PlayerNum].ScoreTotalI := 0;
-
-
- //SingBar Mod
- Player[PlayerNum].ScoreLast := 0;
- Player[PlayerNum].ScorePercent := 50;// Sets to 50% when song starts
- Player[PlayerNum].ScorePercentTarget := 50;// Sets to 50% when song starts
- //end SingBar Mod
-
- //PhrasenBonus - Line Bonus Mod
- Player[PlayerNum].LineBonus_Visible := False; //Hide Line Bonus
- Player[PlayerNum].LineBonus_Alpha := 0;
- Player[PlayerNum].LineBonus_TargetX := 70 + PlayerNum*500;
- Player[PlayerNum].LineBonus_TargetY := 30;
- //PhrasenBonus - Line Bonus Mod End
-end;
-
-//--------------------
-// Function sets all Absolute Paths e.g. Song Path and makes sure the Directorys exist
-//--------------------
-procedure InitializePaths;
-
- // Initialize a Path Variable
- // After Setting Paths, make sure that Paths exist
- function initialize_path( out aPathVar : String; const aLocation : String ): boolean;
- var
- lWriteable: Boolean;
- begin
- aPathVar := aLocation;
-
- If DirectoryExists(aPathVar) then
- lWriteable := ForceDirectories(aPathVar)
- else
- lWriteable := false;
-
- if not lWriteable then
- Log.LogError('Error: Dir ('+ aLocation +') is Readonly');
-
- result := lWriteable;
- end;
-
-begin
-
- GamePath := ExtractFilePath(ParamStr(0));
-
- initialize_path( LogPath , GamePath );
- initialize_path( SoundPath , GamePath + 'Sounds\' );
- initialize_path( SongPath , GamePath + 'Songs\' );
- initialize_path( ThemePath , GamePath + 'Themes\' );
- initialize_path( ScreenshotsPath , GamePath + 'Screenshots\');
- initialize_path( CoversPath , GamePath + 'Covers\' );
- initialize_path( LanguagesPath , GamePath + 'Languages\' );
- initialize_path( PluginPath , GamePath + 'Plugins\' );
- initialize_path( PlaylistPath , GamePath + 'Playlists\' );
-
- DecimalSeparator := ',';
-end;
-
-end.
-
+unit UMain;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ SDL,
+ UGraphic,
+ UMusic,
+ URecord,
+ UTime,
+ SysUtils,
+ UDisplay,
+ UIni,
+ ULog,
+ ULyrics,
+ UScreenSing,
+ OpenGL12,
+ {$IFDEF UseSerialPort}
+ zlportio {you can disable it and all PortWriteB calls},
+ {$ENDIF}
+ ULCD,
+ ULight,
+ UThemes;
+
+type
+ TPlayer = record
+ Name: string;
+
+ Score: real;
+ ScoreLine: real;
+ ScoreGolden: real;
+
+ ScoreI: integer;
+ ScoreLineI: integer;
+ ScoreGoldenI: integer;
+ ScoreTotalI: integer;
+
+
+
+ //SingBar Mod
+ ScoreLast: Real;//Last Line Score
+ ScorePercent: integer;//Aktual Fillstate of the SingBar
+ ScorePercentTarget: integer;//Target Fillstate of the SingBar
+ //end Singbar Mod
+
+ //PhrasenBonus - Line Bonus Mod
+ LineBonus_PosX: Single;
+ LineBonus_PosY: Single;
+ LineBonus_Alpha: Single;
+ LineBonus_Visible: boolean;
+ LineBonus_Text: string;
+ LineBonus_Color: TRGB;
+ LineBonus_Age: Integer;
+ LineBonus_Rating: Integer;
+ //Variable vor Positioning -> Set on ScreenShow, different when Playercount Changes
+ LineBonus_TargetX: integer;
+ LineBonus_TargetY: integer;
+ LineBonus_StartX: integer;
+ LineBonus_StartY: integer;
+ //PhrasenBonus - Line Bonus Mod End
+
+ //PerfectLineTwinkle Mod (effect)
+ LastSentencePerfect: Boolean;
+ //PerfectLineTwinkle Mod end
+
+
+// Meter: real;
+
+ HighNut: integer;
+ IlNut: integer;
+ Nuta: array of record
+ Start: integer;
+ Dlugosc: integer;
+ Detekt: real; // dokladne miejsce, w ktorym wykryto ta nute
+ Ton: real;
+ Perfect: boolean; // true if the note matches the original one, lit the star
+
+
+
+ // Half size Notes Patch
+ Hit: boolean; // true if the note Hits the Line
+ //end Half size Notes Patch
+
+
+
+ end;
+ end;
+
+
+var
+ //Absolute Paths
+ GamePath: string;
+ SoundPath: string;
+ SongPath: string;
+ LogPath: string;
+ ThemePath: string;
+ ScreenshotsPath: string;
+ CoversPath: string;
+ LanguagesPath: string;
+ PluginPath: string;
+ PlayListPath: string;
+
+ OGL: Boolean;
+ Done: Boolean;
+ Event: TSDL_event;
+ FileName: string;
+ Restart: boolean;
+
+ // gracz i jego nuty
+ Player: array of TPlayer;
+ PlayersPlay: integer;
+
+procedure InitializePaths;
+
+procedure MainLoop;
+procedure CheckEvents;
+procedure Sing(Sender: TScreenSing);
+procedure NewSentence(Sender: TScreenSing);
+procedure NewBeat(Sender: TScreenSing); // executed when on then new beat
+procedure NewBeatC(Sender: TScreenSing); // executed when on then new beat for click
+procedure NewBeatD(Sender: TScreenSing); // executed when on then new beat for detection
+//procedure NewHalf; // executed when in the half between beats
+procedure NewNote(Sender: TScreenSing); // detect note
+function GetMidBeat(Time: real): real;
+function GetTimeFromBeat(Beat: integer): real;
+procedure ClearScores(PlayerNum: integer);
+
+implementation
+uses USongs, UJoystick, math, UCommandLine;
+
+procedure MainLoop;
+var
+ Delay: integer;
+begin
+ SDL_EnableKeyRepeat(125, 125);
+ While not Done do
+ Begin
+ // joypad
+ if (Ini.Joypad = 1) OR (Params.Joypad) then
+ Joy.Update;
+
+ // keyboard events
+ CheckEvents;
+
+ // display
+ done := not Display.Draw;
+ SwapBuffers;
+
+ // light
+ Light.Refresh;
+
+ // delay
+ CountMidTime;
+// if 1000*TimeMid > 100 then beep;
+ Delay := Floor(1000 / 100 - 1000 * TimeMid);
+ if Delay >= 1 then
+ SDL_Delay(Delay); // dynamic, maximum is 100 fps
+ CountSkipTime;
+
+ // reinitialization of graphics
+ if Restart then begin
+ Reinitialize3D;
+ Restart := false;
+ end;
+
+ End;
+ UnloadOpenGL;
+End;
+
+Procedure CheckEvents;
+//var
+// p: pointer;
+Begin
+ if not Assigned(Display.NextScreen) then
+ While SDL_PollEvent( @event ) = 1 Do
+ Begin
+// beep;
+ Case Event.type_ Of
+ SDL_QUITEV: begin
+ Display.Fade := 0;
+ Display.NextScreenWithCheck := nil;
+ Display.CheckOK := True;
+ end;
+{ SDL_MOUSEBUTTONDOWN:
+ With Event.button Do
+ Begin
+ If State = SDL_BUTTON_LEFT Then
+ Begin
+ //
+ End;
+ End; // With}
+ SDL_KEYDOWN:
+ begin
+ //ScreenShot hack. If Print is pressed-> Make screenshot and Save to Screenshots Path
+ if (Event.key.keysym.sym = SDLK_SYSREQ) then
+ Display.ScreenShot
+
+ // popup hack... if there is a visible popup then let it handle input instead of underlying screen
+ // shoud be done in a way to be sure the topmost popup has preference (maybe error, then check)
+ else if (ScreenPopupError <> NIL) and (ScreenPopupError.Visible) then
+ done := not ScreenPopupError.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True)
+ else if (ScreenPopupCheck <> NIL) AND (ScreenPopupCheck.Visible) then
+ done := not ScreenPopupCheck.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True)
+ // end of popup hack
+
+ else
+ begin
+ // check for Screen want to Exit
+ done := Not Display.ActualScreen^.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True);
+
+ //If Screen wants to Exit
+ if done then
+ begin
+ //If Question Option is enabled then Show Exit Popup
+ if (Ini.AskbeforeDel = 1) then
+ begin
+ Display.ActualScreen^.CheckFadeTo(NIL,'MSG_QUIT_USDX');
+ end
+ else //When asking for exit is disabled then simply exit
+ begin
+ Display.Fade := 0;
+ Display.NextScreenWithCheck := nil;
+ Display.CheckOK := True;
+ end;
+ end;
+
+ end; // if (Not Display.ActualScreen^.ParseInput(Event.key.keysym.scancode, True)) then
+ end;
+// SDL_JOYAXISMOTION:
+// begin
+// beep
+// end;
+ SDL_JOYBUTTONDOWN:
+ begin
+ beep
+ end;
+ End; // Case Event.type_
+ End; // While
+End; // CheckEvents
+
+function GetTimeForBeats(BPM, Beats: real): real;
+begin
+ Result := 60 / BPM * Beats;
+end;
+
+function GetBeats(BPM, msTime: real): real;
+begin
+ Result := BPM * msTime / 60;
+end;
+
+procedure GetMidBeatSub(BPMNum: integer; var Time: real; var CurBeat: real);
+var
+ NewTime: real;
+begin
+ if High(AktSong.BPM) = BPMNum then begin
+ // last BPM
+ CurBeat := AktSong.BPM[BPMNum].StartBeat + GetBeats(AktSong.BPM[BPMNum].BPM, Time);
+ Time := 0;
+ end else begin
+ // not last BPM
+ // count how much time is it for start of the new BPM and store it in NewTime
+ NewTime := GetTimeForBeats(AktSong.BPM[BPMNum].BPM, AktSong.BPM[BPMNum+1].StartBeat - AktSong.BPM[BPMNum].StartBeat);
+
+ // compare it to remaining time
+ if (Time - NewTime) > 0 then begin
+ // there is still remaining time
+ CurBeat := AktSong.BPM[BPMNum].StartBeat;
+ Time := Time - NewTime;
+ end else begin
+ // there is no remaining time
+ CurBeat := AktSong.BPM[BPMNum].StartBeat + GetBeats(AktSong.BPM[BPMNum].BPM, Time);
+ Time := 0;
+ end; // if
+ end; // if
+end;
+
+function GetMidBeat(Time: real): real;
+var
+ CurBeat: real;
+ CurBPM: integer;
+// TopBeat: real;
+// TempBeat: real;
+// TempTime: real;
+begin
+ Result := 0;
+ if Length(AktSong.BPM) = 1 then Result := Time * AktSong.BPM[0].BPM / 60;
+
+ (* 2 BPMs *)
+{ if Length(AktSong.BPM) > 1 then begin
+ (* new system *)
+ CurBeat := 0;
+ TopBeat := GetBeats(AktSong.BPM[0].BPM, Time);
+ if TopBeat > AktSong.BPM[1].StartBeat then begin
+ // analyze second BPM
+ Time := Time - GetTimeForBeats(AktSong.BPM[0].BPM, AktSong.BPM[1].StartBeat - CurBeat);
+ CurBeat := AktSong.BPM[1].StartBeat;
+ TopBeat := GetBeats(AktSong.BPM[1].BPM, Time);
+ Result := CurBeat + TopBeat;
+
+ end else begin
+ (* pierwszy przedzial *)
+ Result := TopBeat;
+ end;
+ end; // if}
+
+ (* more BPMs *)
+ if Length(AktSong.BPM) > 1 then begin
+
+ CurBeat := 0;
+ CurBPM := 0;
+ while (Time > 0) do begin
+ GetMidBeatSub(CurBPM, Time, CurBeat);
+ Inc(CurBPM);
+ end;
+
+ Result := CurBeat;
+ end; // if
+end;
+
+function GetTimeFromBeat(Beat: integer): real;
+var
+ CurBPM: integer;
+begin
+ Result := 0;
+ if Length(AktSong.BPM) = 1 then Result := AktSong.GAP / 1000 + Beat * 60 / AktSong.BPM[0].BPM;
+
+ (* more BPMs *)
+ if Length(AktSong.BPM) > 1 then begin
+ Result := AktSong.GAP / 1000;
+ CurBPM := 0;
+ while (CurBPM <= High(AktSong.BPM)) and (Beat > AktSong.BPM[CurBPM].StartBeat) do begin
+ if (CurBPM < High(AktSong.BPM)) and (Beat >= AktSong.BPM[CurBPM+1].StartBeat) then begin
+ // full range
+ Result := Result + (60 / AktSong.BPM[CurBPM].BPM) * (AktSong.BPM[CurBPM+1].StartBeat - AktSong.BPM[CurBPM].StartBeat);
+ end;
+
+ if (CurBPM = High(AktSong.BPM)) or (Beat < AktSong.BPM[CurBPM+1].StartBeat) then begin
+ // in the middle
+ Result := Result + (60 / AktSong.BPM[CurBPM].BPM) * (Beat - AktSong.BPM[CurBPM].StartBeat);
+ end;
+ Inc(CurBPM);
+ end;
+
+{ while (Time > 0) do begin
+ GetMidBeatSub(CurBPM, Time, CurBeat);
+ Inc(CurBPM);
+ end;}
+ end; // if}
+end;
+
+procedure Sing(Sender: TScreenSing);
+var
+ Pet: integer;
+ PetGr: integer;
+ CP: integer;
+ Done: real;
+ N: integer;
+begin
+ Czas.Teraz := Czas.Teraz + TimeSkip;
+
+ Czas.OldBeat := Czas.AktBeat;
+ Czas.MidBeat := GetMidBeat(Czas.Teraz - (AktSong.Gap{ + 90 I've forgotten for what it is}) / 1000); // new system with variable BPM in function
+ Czas.AktBeat := Floor(Czas.MidBeat);
+
+// Czas.OldHalf := Czas.AktHalf;
+// Czas.MidHalf := Czas.MidBeat + 0.5;
+// Czas.AktHalf := Floor(Czas.MidHalf);
+
+ Czas.OldBeatC := Czas.AktBeatC;
+ Czas.MidBeatC := GetMidBeat(Czas.Teraz - (AktSong.Gap) / 1000);
+ Czas.AktBeatC := Floor(Czas.MidBeatC);
+
+ Czas.OldBeatD := Czas.AktBeatD;
+ Czas.MidBeatD := -0.5+GetMidBeat(Czas.Teraz - (AktSong.Gap + 120 + 20) / 1000); // MidBeat with addition GAP
+ Czas.AktBeatD := Floor(Czas.MidBeatD);
+ Czas.FracBeatD := Frac(Czas.MidBeatD);
+
+ // sentences routines
+ for PetGr := 0 to 0 do begin;//High(Gracz) do begin
+ CP := PetGr;
+ // ustawianie starej czesci
+ Czas.OldCzesc := Czesci[CP].Akt;
+
+ // wybieranie aktualnej czesci
+ for Pet := 0 to Czesci[CP].High do
+ if Czas.AktBeat >= Czesci[CP].Czesc[Pet].Start then Czesci[CP].Akt := Pet;
+
+ // czysczenie nut gracza, gdy to jest nowa plansza
+ // (optymizacja raz na halfbeat jest zla)
+ if Czesci[CP].Akt <> Czas.OldCzesc then NewSentence(Sender);
+
+ end; // for PetGr
+
+ // wykonuje operacje raz na beat
+ if (Czas.AktBeat >= 0) and (Czas.OldBeat <> Czas.AktBeat) then
+ NewBeat(Sender);
+
+ // make some operations on clicks
+ if {(Czas.AktBeatC >= 0) and }(Czas.OldBeatC <> Czas.AktBeatC) then
+ NewBeatC(Sender);
+
+ // make some operations when detecting new voice pitch
+ if (Czas.AktBeatD >= 0) and (Czas.OldBeatD <> Czas.AktBeatD) then
+ NewBeatD(Sender);
+
+ // wykonuje operacje w polowie beatu
+// if (Czas.AktHalf >= 1) and (Czas.OldHalf <> Czas.AktHalf) then
+// NewHalf;
+
+ // plynnie przesuwa text
+ Done := 1;
+ for N := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
+ if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start <= Czas.MidBeat)
+ and (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start + Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc >= Czas.MidBeat) then
+ Done := (Czas.MidBeat - Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start) / (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc);
+
+ N := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
+
+ // wylacza ostatnia nute po przejsciu
+ if (Ini.LyricsEffect = 1) and (Done = 1) and
+ (Czas.MidBeat > Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start + Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc)
+ then Sender.LyricMain.Selected := -1;
+
+ if Done > 1 then Done := 1;
+ Sender.LyricMain.Done := Done;
+
+ // use Done with LCD
+{ with ScreenSing do begin
+ if LyricMain.Selected >= 0 then begin
+ LCD.MoveCursor(1, LyricMain.SelectedLetter + Round((LyricMain.SelectedLength-1) * Done));
+ LCD.ShowCursor;
+ end;
+ end;}
+
+
+end;
+
+procedure NewSentence(Sender: TScreenSing);
+var
+G: Integer;
+begin
+ // czyszczenie nut graczy
+ for G := 0 to High(Player) do begin
+ Player[G].IlNut := 0;
+ Player[G].HighNut := -1;
+ SetLength(Player[G].Nuta, 0);
+ end;
+
+ // wstawianie tekstow
+ with Sender do begin
+ LyricMain.AddCzesc(Czesci[0].Akt);
+ if Czesci[0].Akt < Czesci[0].High then
+ LyricSub.AddCzesc(Czesci[0].Akt+1)
+ else
+ LyricSub.Clear;
+ end;
+
+ Sender.UpdateLCD;
+
+ //On Sentence Change...
+ Sender.onSentenceChange(Czesci[0].Akt);
+end;
+
+procedure NewBeat(Sender: TScreenSing);
+var
+ Pet: integer;
+// TempBeat: integer;
+begin
+ // ustawia zaznaczenie tekstu
+// SingScreen.LyricMain.Selected := -1;
+ for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
+ if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeat) then begin
+ // operates on currently beated note
+ Sender.LyricMain.Selected := Pet;
+
+// LCD.MoveCursor(1, ScreenSing.LyricMain.SelectedLetter);
+// LCD.ShowCursor;
+
+ LCD.MoveCursorBR(Sender.LyricMain.SelectedLetter);
+ LCD.ShowCursor;
+
+ end;
+end;
+
+procedure NewBeatC;
+var
+ Pet: integer;
+// LPT_1: integer;
+// LPT_2: integer;
+begin
+// LPT_1 := 1;
+// LPT_2 := 1;
+
+ // beat click
+ if (Ini.BeatClick = 1) and ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod Czesci[0].Resolution = 0) then
+ Music.PlayClick;
+
+ // debug system on LPT
+ if ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod Czesci[0].Resolution = 0) then begin
+ //LPT_1 := 0;
+// Light.LightOne(0, 150);
+
+ Light.LightOne(1, 200); // beat light
+ if ParamStr(1) = '-doublelights' then
+ Light.LightOne(0, 200); // beat light
+
+
+{ if ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod (Czesci[0].Resolution * 2) = 0) then
+ Light.LightOne(0, 150)
+ else
+ Light.LightOne(1, 150)}
+ end;
+
+ for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
+ if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeatC) then begin
+ // click assist
+ if Ini.ClickAssist = 1 then
+ Music.PlayClick;
+
+ //LPT_2 := 0;
+ if ParamStr(1) <> '-doublelights' then
+ Light.LightOne(0, 150); //125
+
+
+ // drum machine
+(* TempBeat := Czas.AktBeat;// + 2;
+ if (TempBeat mod 8 = 0) then Music.PlayDrum;
+ if (TempBeat mod 8 = 4) then Music.PlayClap;
+// if (TempBeat mod 4 = 2) then Music.PlayHihat;
+ if (TempBeat mod 4 <> 0) then Music.PlayHihat;*)
+ end;
+
+ {$IFDEF UseSerialPort}
+ // PortWriteB($378, LPT_1 + LPT_2 * 2); // 0 zapala
+ {$ENDIF}
+end;
+
+procedure NewBeatD(Sender: TScreenSing);
+begin
+ NewNote(Sender);
+end;
+
+//procedure NewHalf;
+//begin
+// NewNote;
+//end;
+
+procedure NewNote(Sender: TScreenSing);
+var
+ CP: integer; // current player
+ S: integer; // sentence
+ SMin: integer;
+ SMax: integer;
+ SDet: integer; // temporary: sentence of detected note
+ Pet: integer;
+ Mozna: boolean;
+ Nowa: boolean;
+ Range: integer;
+ NoteHit:boolean;
+begin
+// Log.LogStatus('Beat ' + IntToStr(Czas.AktBeat) + ' HalfBeat ' + IntToStr(Czas.AktHalf), 'NewBeat');
+// beep;
+
+ // analizuje dla obu graczy ten sam sygnal (Sound.OneSrcForBoth)
+ // albo juz lepiej nie
+ for CP := 0 to PlayersPlay-1 do begin
+
+ // analyze buffer
+ Sound[CP].AnalizujBufor;
+
+ // adds some noise
+// Czas.Ton := Czas.Ton + Round(Random(3)) - 1;
+
+ // 0.5.0: count min and max sentence range for checking (detection is delayed to the notes we see on the screen)
+ SMin := Czesci[0].Akt-1;
+ if SMin < 0 then SMin := 0;
+ SMax := Czesci[0].Akt;
+
+ // check if we can add new note
+ Mozna := false;
+ SDet:=SMin;
+ for S := SMin to SMax do
+ for Pet := 0 to Czesci[0].Czesc[S].HighNut do
+ if ((Czesci[0].Czesc[S].Nuta[Pet].Start <= Czas.AktBeatD)
+ and (Czesci[0].Czesc[S].Nuta[Pet].Start + Czesci[0].Czesc[S].Nuta[Pet].Dlugosc - 1 >= Czas.AktBeatD))
+ and (not Czesci[0].Czesc[S].Nuta[Pet].FreeStyle) // but don't allow when it's FreeStyle note
+ and (Czesci[0].Czesc[S].Nuta[Pet].Dlugosc > 0) // and make sure the note lenghts is at least 1
+ then begin
+ SDet := S;
+ Mozna := true;
+ Break;
+ end;
+
+ S := SDet;
+
+
+
+
+
+// Czas.SzczytJest := true;
+// Czas.Ton := 27;
+
+ // gdy moze, to dodaje nute
+ if (Sound[CP].SzczytJest) and (Mozna) then begin
+ // operowanie na ostatniej nucie
+ for Pet := 0 to Czesci[0].Czesc[S].HighNut do
+ if (Czesci[0].Czesc[S].Nuta[Pet].Start <= Czas.OldBeatD+1)
+ and (Czesci[0].Czesc[S].Nuta[Pet].Start +
+ Czesci[0].Czesc[S].Nuta[Pet].Dlugosc > Czas.OldBeatD+1) then begin
+ // to robi, tylko dla pary nut (oryginalnej i gracza)
+
+ // przesuwanie tonu w odpowiednia game
+ while (Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton > 6) do
+ Sound[CP].Ton := Sound[CP].Ton - 12;
+ while (Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton < -6) do
+ Sound[CP].Ton := Sound[CP].Ton + 12;
+
+ // Half size Notes Patch
+ NoteHit := false;
+
+ //if Ini.Difficulty = 0 then Range := 2;
+ //if Ini.Difficulty = 1 then Range := 1;
+ //if Ini.Difficulty = 2 then Range := 0;
+ Range := 2 - Ini.Difficulty;
+ if abs(Czesci[0].Czesc[S].Nuta[Pet].Ton - Sound[CP].Ton) <= Range then begin
+ Sound[CP].Ton := Czesci[0].Czesc[S].Nuta[Pet].Ton;
+
+
+ // Half size Notes Patch
+ NoteHit := true;
+
+
+ if (Ini.LineBonus = 0) then
+ begin
+ // add points without LineBonus
+ case Czesci[0].Czesc[S].Nuta[Pet].Wartosc of
+ 1: Player[CP].Score := Player[CP].Score + 10000 / Czesci[0].Wartosc *
+ Czesci[0].Czesc[S].Nuta[Pet].Wartosc;
+ 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 10000 / Czesci[0].Wartosc *
+ Czesci[0].Czesc[S].Nuta[Pet].Wartosc;
+ end;
+ end
+ else
+ begin
+ // add points with Line Bonus
+ case Czesci[0].Czesc[S].Nuta[Pet].Wartosc of
+ 1: Player[CP].Score := Player[CP].Score + 9000 / Czesci[0].Wartosc *
+ Czesci[0].Czesc[S].Nuta[Pet].Wartosc;
+ 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 9000 / Czesci[0].Wartosc *
+ Czesci[0].Czesc[S].Nuta[Pet].Wartosc;
+ end;
+ end;
+
+ Player[CP].ScoreI := Floor(Player[CP].Score / 10) * 10;
+ Player[CP].ScoreGoldenI := Floor(Player[CP].ScoreGolden / 10) * 10;
+
+ Player[CP].ScoreTotalI := Player[CP].ScoreI + Player[CP].ScoreGoldenI + Player[CP].ScoreLineI;
+ end;
+
+ end; // operowanie
+
+ // sprawdzanie czy to nowa nuta, czy przedluzenie
+ if S = SMax then begin
+ Nowa := true;
+ // jezeli ostatnia ma ten sam ton
+ if (Player[CP].IlNut > 0 ) and (Player[CP].Nuta[Player[CP].HighNut].Ton = Sound[CP].Ton)
+ and (Player[CP].Nuta[Player[CP].HighNut].Start + Player[CP].Nuta[Player[CP].HighNut].Dlugosc = Czas.AktBeatD)
+ then Nowa := false;
+ // jezeli jest jakas nowa nuta na sprawdzanym beacie
+ for Pet := 0 to Czesci[0].Czesc[S].HighNut do
+ if (Czesci[0].Czesc[S].Nuta[Pet].Start = Czas.AktBeatD) then
+ Nowa := true;
+
+ // dodawanie nowej nuty
+ if Nowa then begin
+ // nowa nuta
+ Player[CP].IlNut := Player[CP].IlNut + 1;
+ Player[CP].HighNut := Player[CP].HighNut + 1;
+ SetLength(Player[CP].Nuta, Player[CP].IlNut);
+ Player[CP].Nuta[Player[CP].HighNut].Start := Czas.AktBeatD;
+ Player[CP].Nuta[Player[CP].HighNut].Dlugosc := 1;
+ Player[CP].Nuta[Player[CP].HighNut].Ton := Sound[CP].Ton; // Ton || TonDokl
+ Player[CP].Nuta[Player[CP].HighNut].Detekt := Czas.MidBeat;
+
+
+ // Half Note Patch
+ Player[CP].Nuta[Player[CP].HighNut].Hit := NoteHit;
+
+
+ // Log.LogStatus('Nowa Nuta ' + IntToStr(Gracz.Nuta[Gracz.HighNut].Start), 'NewBeat');
+
+ end else begin
+ // przedluzenie nuty
+ Player[CP].Nuta[Player[CP].HighNut].Dlugosc := Player[CP].Nuta[Player[CP].HighNut].Dlugosc + 1;
+ end;
+
+
+ // check for perfect note and then lit the star (on Draw)
+ for Pet := 0 to Czesci[0].Czesc[S].HighNut do
+ if (Czesci[0].Czesc[S].Nuta[Pet].Start = Player[CP].Nuta[Player[CP].HighNut].Start)
+ and (Czesci[0].Czesc[S].Nuta[Pet].Dlugosc = Player[CP].Nuta[Player[CP].HighNut].Dlugosc)
+ and (Czesci[0].Czesc[S].Nuta[Pet].Ton = Player[CP].Nuta[Player[CP].HighNut].Ton) then begin
+ Player[CP].Nuta[Player[CP].HighNut].Perfect := true;
+ end;
+
+ end;// else beep; // if S = SMax
+
+ end; // if moze
+ end; // for CP
+// Log.LogStatus('EndBeat', 'NewBeat');
+
+//On Sentence End -> For LineBonus + SingBar
+if (sDet >= low(Czesci[0].Czesc)) AND (sDet <= high(Czesci[0].Czesc)) then
+if ((Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Start + Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Dlugosc - 1) = Czas.AktBeatD) then
+ Sender.onSentenceEnd(sDet);
+
+end;
+
+procedure ClearScores(PlayerNum: integer);
+begin
+ Player[PlayerNum].Score := 0;
+ Player[PlayerNum].ScoreI := 0;
+ Player[PlayerNum].ScoreLine := 0;
+ Player[PlayerNum].ScoreLineI := 0;
+ Player[PlayerNum].ScoreGolden := 0;
+ Player[PlayerNum].ScoreGoldenI := 0;
+ Player[PlayerNum].ScoreTotalI := 0;
+
+
+ //SingBar Mod
+ Player[PlayerNum].ScoreLast := 0;
+ Player[PlayerNum].ScorePercent := 50;// Sets to 50% when song starts
+ Player[PlayerNum].ScorePercentTarget := 50;// Sets to 50% when song starts
+ //end SingBar Mod
+
+ //PhrasenBonus - Line Bonus Mod
+ Player[PlayerNum].LineBonus_Visible := False; //Hide Line Bonus
+ Player[PlayerNum].LineBonus_Alpha := 0;
+ Player[PlayerNum].LineBonus_TargetX := 70 + PlayerNum*500;
+ Player[PlayerNum].LineBonus_TargetY := 30;
+ //PhrasenBonus - Line Bonus Mod End
+end;
+
+//--------------------
+// Function sets all Absolute Paths e.g. Song Path and makes sure the Directorys exist
+//--------------------
+procedure InitializePaths;
+
+ // Initialize a Path Variable
+ // After Setting Paths, make sure that Paths exist
+ function initialize_path( out aPathVar : String; const aLocation : String ): boolean;
+ var
+ lWriteable: Boolean;
+ begin
+ aPathVar := aLocation;
+
+ If DirectoryExists(aPathVar) then
+ lWriteable := ForceDirectories(aPathVar)
+ else
+ lWriteable := false;
+
+ if not lWriteable then
+ Log.LogError('Error: Dir ('+ aLocation +') is Readonly');
+
+ result := lWriteable;
+ end;
+
+begin
+
+ GamePath := ExtractFilePath(ParamStr(0));
+
+ initialize_path( LogPath , GamePath );
+ initialize_path( SoundPath , GamePath + 'Sounds' + PathDelim );
+ initialize_path( SongPath , GamePath + 'Songs' + PathDelim );
+ initialize_path( ThemePath , GamePath + 'Themes' + PathDelim );
+ initialize_path( ScreenshotsPath , GamePath + 'Screenshots' + PathDelim );
+ initialize_path( CoversPath , GamePath + 'Covers' + PathDelim );
+ initialize_path( LanguagesPath , GamePath + 'Languages' + PathDelim );
+ initialize_path( PluginPath , GamePath + 'Plugins' + PathDelim );
+ initialize_path( PlaylistPath , GamePath + 'Playlists' + PathDelim );
+
+ DecimalSeparator := ',';
+end;
+
+end.
+
diff --git a/Game/Code/Classes/UMusic.pas b/Game/Code/Classes/UMusic.pas
index be585ee1..e2e1f27e 100644
--- a/Game/Code/Classes/UMusic.pas
+++ b/Game/Code/Classes/UMusic.pas
@@ -1,625 +1,731 @@
-unit UMusic;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-
-uses Classes,
- Windows,
- Messages,
- SysUtils,
- {$IFNDEF FPC}
- Forms,
- {$ENDIF}
- ULog,
- USongs,
- Bass;
-
-procedure InitializeSound;
-
-type
- TSoundCard = record
- Name: string;
- Source: array of string;
- end;
-
- TFFTData = array [0..256] of Single;
-
- TCustomSoundEntry = record
- Filename: String;
- Handle: hStream;
- end;
-
-
- TMusic = class
- private
- BassStart: hStream; // Wait, I've replaced this with BASS
- BassBack: hStream; // It has almost all features we need
- BassSwoosh: hStream;
- BassChange: hStream; // Almost? It aleady has them all :)
- BassOption: hStream;
- BassClick: hStream;
- BassDrum: hStream;
- BassHihat: hStream;
- BassClap: hStream;
- BassShuffle: hStream;
-
- //Custom Sounds
- CustomSounds: array of TCustomSoundEntry;
-
-
- Loaded: boolean;
- Loop: boolean;
- public
- Bass: hStream;
- procedure InitializePlayback;
- procedure InitializeRecord;
- procedure SetVolume(Volume: integer);
- procedure SetMusicVolume(Volume: integer);
- procedure SetLoop(Enabled: boolean);
- function Open(Name: string): boolean; // true if succeed
- procedure Rewind;
- procedure MoveTo(Time: real);
- procedure Play;
- procedure Pause; //Pause Mod
- procedure Stop;
- procedure Close;
- function Finished: boolean;
- function Length: real;
- function Position: real;
- procedure PlayStart;
- procedure PlayBack;
- procedure PlaySwoosh;
- procedure PlayChange;
- procedure PlayOption;
- procedure PlayClick;
- procedure PlayDrum;
- procedure PlayHihat;
- procedure PlayClap;
- procedure PlayShuffle;
- procedure StopShuffle;
- procedure CaptureStart;
- procedure CaptureStop;
- procedure CaptureCard(RecordI, PlayerLeft, PlayerRight: byte);
- procedure StopCard(Card: byte);
- function LoadSoundFromFile(var hStream: hStream; Name: string): boolean;
-
- //Equalizer
- function GetFFTData: TFFTData;
-
- //Custom Sounds
- function LoadCustomSound(const Filename: String): Cardinal;
- procedure PlayCustomSound(const Index: Cardinal);
-
-end;
-
-const
- RecordSystem = 1;
-
-type
- TMuzyka = record
- Path: string;
- Start: integer; // start of song in ms
- IlNut: integer;
- DlugoscNut: integer;
- end;
-
- TCzesci = record
- Akt: integer; // aktualna czesc utworu do rysowania
- High: integer;
- Ilosc: integer;
- Resolution: integer;
- NotesGAP: integer;
- Wartosc: integer;
- Czesc: array of record
- Start: integer;
- StartNote: integer;
- Lyric: string;
- LyricWidth: real;
- Koniec: integer;
- BaseNote: integer;
- HighNut: integer;
- IlNut: integer;
- TotalNotes: integer;
- Nuta: array of record
- Color: integer;
- Start: integer;
- Dlugosc: integer;
- Ton: integer;
- TonGamy: integer;
- Tekst: string;
- FreeStyle: boolean;
- Wartosc: integer; // zwykla nuta x1, zlota nuta x2
- end;
- end;
- end;
-
- TCzas = record // wszystko, co dotyczy aktualnej klatki
- OldBeat: integer; // poprzednio wykryty beat w utworze
- AktBeat: integer; // aktualny beat w utworze
- MidBeat: real; // dokladny AktBeat
-
- // now we use this for super synchronization!
- // only used when analyzing voice
- OldBeatD: integer; // poprzednio wykryty beat w utworze
- AktBeatD: integer; // aktualny beat w utworze
- MidBeatD: real; // dokladny AktBeatD
- FracBeatD: real; // fractional part of MidBeatD
-
- // we use this for audiable clicks
- OldBeatC: integer; // poprzednio wykryty beat w utworze
- AktBeatC: integer; // aktualny beat w utworze
- MidBeatC: real; // dokladny AktBeatC
- FracBeatC: real; // fractional part of MidBeatC
-
-
- OldCzesc: integer; // poprzednio wyswietlana czesc
- // akt jest w czesci.akt
-
- Teraz: real; // aktualny czas w utworze
- Razem: real; // caly czas utworu
- end;
-
-var
- Music: TMusic;
-
- // muzyka
- Muzyka: TMuzyka;
-
- // czesci z nutami;
- Czesci: array of TCzesci;
-
- // czas
- Czas: TCzas;
-
- fHWND: Thandle;
-
-type
- TMPModes = (mpNotReady, mpStopped, mpPlaying, mpRecording, mpSeeking,
- mpPaused, mpOpen);
-
-const
- ModeStr: array[TMPModes] of string = ('Not ready', 'Stopped', 'Playing', 'Recording', 'Seeking', 'Paused', 'Open');
-
-implementation
-
-uses UCommon,
- UGraphic,
- URecord,
- UFiles,
- UIni,
- UMain,
- UThemes;
-
-procedure InitializeSound;
-begin
- Log.LogStatus('Initializing Playback', 'InitializeSound'); Music.InitializePlayback;
- Log.LogStatus('Initializing Record', 'InitializeSound'); Music.InitializeRecord;
-end;
-
-procedure TMusic.InitializePlayback;
-var
- Pet: integer;
- S: integer;
-begin
- Log.BenchmarkStart(4);
- Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize');
-
- Loaded := false;
- Loop := false;
-
- fHWND := AllocateHWND( nil); // TODO : JB - can we do something different here ?? lazarus didnt like this function
-
- if not BASS_Init(1, 44100, 0, fHWND, nil) then
- begin
- {$IFNDEF FPC}
- // TODO : JB find a way to do this nice..
- Application.MessageBox ('Could not initialize BASS', 'Error');
- {$ENDIF}
- Exit;
- end;
-
- Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4);
-
- // config playing buffer
-// BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 10);
-// BASS_SetConfig(BASS_CONFIG_BUFFER, 100);
-
- Log.LogStatus('Loading Sounds', 'Music Initialize');
-
- Log.BenchmarkStart(4);
- LoadSoundFromFile(BassStart, SoundPath + 'Common Start.mp3');
- LoadSoundFromFile(BassBack, SoundPath + 'Common Back.mp3');
- LoadSoundFromFile(BassSwoosh, SoundPath + 'menu swoosh.mp3');
- LoadSoundFromFile(BassChange, SoundPath + 'select music change music 50.mp3');
- LoadSoundFromFile(BassOption, SoundPath + 'option change col.mp3');
- LoadSoundFromFile(BassClick, SoundPath + 'rimshot022b.mp3');
-
-// LoadSoundFromFile(BassDrum, SoundPath + 'bassdrumhard076b.mp3');
-// LoadSoundFromFile(BassHihat, SoundPath + 'hihatclosed068b.mp3');
-// LoadSoundFromFile(BassClap, SoundPath + 'claps050b.mp3');
-
-// LoadSoundFromFile(BassShuffle, SoundPath + 'Shuffle.mp3');
-
- Log.BenchmarkEnd(4); Log.LogBenchmark('--> Loading Sounds', 4);
-end;
-
-procedure TMusic.InitializeRecord;
-var
- S: integer;
- device: integer;
- descr: string;
- input: integer;
- input2: integer;
- flags: integer;
- mic: array[0..15] of integer;
- SC: integer; // soundcard
- SCI: integer; // soundcard input
-begin
- if RecordSystem = 1 then begin
- SetLength(Sound, 6 {max players});//Ini.Players+1);
- for S := 0 to High(Sound) do begin //Ini.Players do begin
- Sound[S] := TSound.Create;
- Sound[S].Num := S;
- Sound[S].BufferNew := TMemoryStream.Create;
- SetLength(Sound[S].BufferLong, 1);
- Sound[S].BufferLong[0] := TMemoryStream.Create;
- Sound[S].n := 4*1024;
- end;
-
-
- // check for recording devices;
- {device := 0;
- descr := BASS_RecordGetDeviceDescription(device);
-
- SetLength(SoundCard, 0);
- while (descr <> '') do begin
- SC := High(SoundCard) + 1;
- SetLength(SoundCard, SC+1);
-
- Log.LogAnalyze('Device #'+IntToStr(device)+': '+ descr);
- SoundCard[SC].Description := Descr;
-
- // check for recording inputs
- mic[device] := -1; // default to no change
- input := 0;
- BASS_RecordInit(device);
- Log.LogAnalyze('Input #' + IntToStr(Input) + ': ' + BASS_RecordGetInputName(input));
- flags := BASS_RecordGetInput(input);
-
- SetLength(SoundCard[SC].Input, 0);
- while (flags <> -1) do begin
- SCI := High(SoundCard[SC].Input) + 1;
- SetLength(SoundCard[SC].Input, SCI+1);
-
- Log.LogAnalyze('Input #' + IntToStr(Input) + ': ' + BASS_RecordGetInputName(input));
- SoundCard[SC].Input[SCI].Name := BASS_RecordGetInputName(Input);
-
- if (flags and BASS_INPUT_TYPE_MASK) = BASS_INPUT_TYPE_MIC then begin
- mic[device] := input; // auto set microphone
- end;
- Inc(Input);
- flags := BASS_RecordGetInput(input);
- end;
-
- if mic[device] <> -1 then begin
- Log.LogAnalyze('Found the mic at input ' + IntToStr(Mic[device]))
- end else begin
- Log.LogAnalyze('Mic not found');
- mic[device] := 0; // setting to the first one (for kxproject)
- end;
- SoundCard[SC].InputSeleceted := Mic[Device];
-
-
- BASS_RecordFree;
-
- inc(Device);
- descr := BASS_RecordGetDeviceDescription(Device);
- end; // while}
- end; // if
-end;
-
-procedure TMusic.SetVolume(Volume: integer);
-begin
- //Old Sets Wave Volume
- //BASS_SetVolume(Volume);
- //New: Sets Volume only for this Application
- BASS_SetConfig(BASS_CONFIG_GVOL_SAMPLE, Volume);
- BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume);
- BASS_SetConfig(BASS_CONFIG_GVOL_MUSIC, Volume);
-end;
-
-procedure TMusic.SetMusicVolume(Volume: Integer);
-begin
- //Max Volume Prevention
- if Volume > 100 then
- Volume := 100;
-
- //Set Volume
- BASS_ChannelSetAttributes (Bass, -1, Volume, -101);
-end;
-
-procedure TMusic.SetLoop(Enabled: boolean);
-begin
- Loop := Enabled;
-end;
-
-function TMusic.Open(Name: string): boolean;
-begin
- Loaded := false;
- if FileExists(Name) then begin
- Bass := Bass_StreamCreateFile(false, pchar(Name), 0, 0, 0);
- Loaded := true;
- //Set Max Volume
- SetMusicVolume (100);
- end;
-
- Result := Loaded;
-end;
-
-procedure TMusic.Rewind;
-begin
- if Loaded then begin
- end;
-end;
-
-procedure TMusic.MoveTo(Time: real);
-var
- bytes: integer;
-begin
- bytes := BASS_ChannelSeconds2Bytes(Bass, Time);
- BASS_ChannelSetPosition(Bass, bytes);
-end;
-
-procedure TMusic.Play;
-begin
- if Loaded then
- begin
- if Loop then
- BASS_ChannelPlay(Bass, True); // start from beginning... actually bass itself does not loop, nor does this TMusic Class
-
- BASS_ChannelPlay(Bass, False); // for setting position before playing
- end;
-end;
-
-procedure TMusic.Pause; //Pause Mod
-begin
- if Loaded then begin
- BASS_ChannelPause(Bass); // Pauses Song
- end;
-end;
-
-procedure TMusic.Stop;
-begin
- Bass_ChannelStop(Bass);
-end;
-
-procedure TMusic.Close;
-begin
- Bass_StreamFree(Bass);
-end;
-
-function TMusic.Length: real;
-var
- bytes: integer;
-begin
- Result := 60;
-
- bytes := BASS_ChannelGetLength(Bass);
- Result := BASS_ChannelBytes2Seconds(Bass, bytes);
-end;
-
-function TMusic.Position: real;
-var
- bytes: integer;
-begin
- Result := 0;
- bytes := BASS_ChannelGetPosition(BASS);
- Result := BASS_ChannelBytes2Seconds(BASS, bytes);
-end;
-
-function TMusic.Finished: boolean;
-begin
- Result := false;
-
- if BASS_ChannelIsActive(BASS) = BASS_ACTIVE_STOPPED then
- begin
- Result := true;
- end;
-end;
-
-procedure TMusic.PlayStart;
-begin
- BASS_ChannelPlay(BassStart, True);
-end;
-
-procedure TMusic.PlayBack;
-begin
- BASS_ChannelPlay(BassBack, True);// then
-end;
-
-procedure TMusic.PlaySwoosh;
-begin
- BASS_ChannelPlay(BassSwoosh, True);
-end;
-
-procedure TMusic.PlayChange;
-begin
- BASS_ChannelPlay(BassChange, True);
-end;
-
-procedure TMusic.PlayOption;
-begin
- BASS_ChannelPlay(BassOption, True);
-end;
-
-procedure TMusic.PlayClick;
-begin
- BASS_ChannelPlay(BassClick, True);
-end;
-
-procedure TMusic.PlayDrum;
-begin
- BASS_ChannelPlay(BassDrum, True);
-end;
-
-procedure TMusic.PlayHihat;
-begin
- BASS_ChannelPlay(BassHihat, True);
-end;
-
-procedure TMusic.PlayClap;
-begin
- BASS_ChannelPlay(BassClap, True);
-end;
-
-procedure TMusic.PlayShuffle;
-begin
- BASS_ChannelPlay(BassShuffle, True);
-end;
-
-procedure TMusic.StopShuffle;
-begin
- BASS_ChannelStop(BassShuffle);
-end;
-
-procedure TMusic.CaptureStart;
-var
- S: integer;
- SC: integer;
- P1: integer;
- P2: integer;
-begin
- for S := 0 to High(Sound) do
- Sound[S].BufferLong[0].Clear;
-
- for SC := 0 to High(Ini.CardList) do begin
- P1 := Ini.CardList[SC].ChannelL;
- P2 := Ini.CardList[SC].ChannelR;
- if P1 > PlayersPlay then P1 := 0;
- if P2 > PlayersPlay then P2 := 0;
- if (P1 > 0) or (P2 > 0) then
- CaptureCard(SC, P1, P2);
- end;
-end;
-
-procedure TMusic.CaptureStop;
-var
- SC: integer;
- P1: integer;
- P2: integer;
-begin
-
- for SC := 0 to High(Ini.CardList) do begin
- P1 := Ini.CardList[SC].ChannelL;
- P2 := Ini.CardList[SC].ChannelR;
- if P1 > PlayersPlay then P1 := 0;
- if P2 > PlayersPlay then P2 := 0;
- if (P1 > 0) or (P2 > 0) then StopCard(SC);
- end;
-
-end;
-
-//procedure TMusic.CaptureCard(RecordI, SoundNum, PlayerLeft, PlayerRight: byte);
-procedure TMusic.CaptureCard(RecordI, PlayerLeft, PlayerRight: byte);
-var
- Error: integer;
- ErrorMsg: string;
-begin
- if not BASS_RecordInit(RecordI) then begin
- Error := BASS_ErrorGetCode;
-
- ErrorMsg := IntToStr(Error);
- if Error = BASS_ERROR_DX then ErrorMsg := 'No DX5';
- if Error = BASS_ERROR_ALREADY then ErrorMsg := 'The device has already been initialized';
- if Error = BASS_ERROR_DEVICE then ErrorMsg := 'The device number specified is invalid';
- if Error = BASS_ERROR_DRIVER then ErrorMsg := 'There is no available device driver';
-
- {Log.LogAnalyze('Error initializing record [' + IntToStr(RecordI) + ', '
- + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: '
- + ErrorMsg);}
- Log.LogError('Error initializing record [' + IntToStr(RecordI) + ', '
- + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: '
- + ErrorMsg);
- Log.LogError('Music -> CaptureCard: Error initializing record: ' + ErrorMsg);
-
-
- end
- else
- begin
- Recording.SoundCard[RecordI].BassRecordStream := BASS_RecordStart(44100, 2, MakeLong(0, 20) , @GetMicrophone, PlayerLeft + PlayerRight*256);
- end;
-end;
-
-procedure TMusic.StopCard(Card: byte);
-begin
- BASS_RecordSetDevice(Card);
- BASS_RecordFree;
-end;
-
-function TMusic.LoadSoundFromFile(var hStream: hStream; Name: string): boolean;
-var
- L: Integer;
-begin
- if FileExists(Name) then begin
- Log.LogStatus('Loading Sound: "' + Name + '"', 'LoadSoundFromFile');
- try
- hStream := BASS_StreamCreateFile(False, pchar(Name), 0, 0, 0);
- //Add CustomSound
- L := High(CustomSounds) + 1;
- SetLength (CustomSounds, L + 1);
- CustomSounds[L].Filename := Name;
- CustomSounds[L].Handle := hStream;
- except
- Log.LogError('Failed to open using BASS', 'LoadSoundFromFile');
- end;
- end else begin
- Log.LogError('Sound not found: "' + Name + '"', 'LoadSoundFromFile');
- exit;
- end;
-end;
-
-//Equalizer
-function TMusic.GetFFTData: TFFTData;
-var
-Data: TFFTData;
-begin
- //Get Channel Data Mono and 256 Values
- BASS_ChannelGetData(Bass, @Result, BASS_DATA_FFT512);
- //Result := Data;
-end;
-
-function TMusic.LoadCustomSound(const Filename: String): Cardinal;
-var
- S: hStream;
- I: Integer;
- F: String;
-begin
- //Search for Sound in already loaded Sounds
- F := UpperCase(SoundPath + FileName);
- For I := 0 to High(CustomSounds) do
- begin
- if (UpperCase(CustomSounds[I].Filename) = F) then
- begin
- Result := I;
- Exit;
- end;
- end;
-
- if LoadSoundFromFile(S, SoundPath + Filename) then
- Result := High(CustomSounds)
- else
- Result := 0;
-end;
-
-procedure TMusic.PlayCustomSound(const Index: Cardinal);
-begin
-if Index <= High(CustomSounds) then
- BASS_ChannelPlay(CustomSounds[Index].Handle, True);
-end;
-
-
-end.
+unit UMusic;
+
+interface
+
+{$I switches.inc}
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+
+uses Classes,
+ {$IFDEF win32}
+ windows,
+ {$ENDIF}
+ UCommon,
+ Messages,
+ SysUtils,
+ {$IFNDEF FPC}
+ Forms,
+ {$ENDIF}
+ {$IFDEF useBASS}
+ bass,
+ {$ENDIF}
+ ULog,
+ USongs;
+
+
+procedure InitializeSound;
+
+type
+ TSoundCard = record
+ Name: string;
+ Source: array of string;
+ end;
+
+ TFFTData = array [0..256] of Single;
+
+ TCustomSoundEntry = record
+ Filename : String;
+ Handle : hStream;
+ end;
+
+
+ TMusic = class
+ private
+ BassStart: hStream; // Wait, I've replaced this with BASS
+ BassBack: hStream; // It has almost all features we need
+ BassSwoosh: hStream;
+ BassChange: hStream; // Almost? It aleady has them all :)
+ BassOption: hStream;
+ BassClick: hStream;
+ BassDrum: hStream;
+ BassHihat: hStream;
+ BassClap: hStream;
+ BassShuffle: hStream;
+
+ //Custom Sounds
+ CustomSounds: array of TCustomSoundEntry;
+
+
+ Loaded: boolean;
+ Loop: boolean;
+ public
+ Bass: hStream;
+ procedure InitializePlayback;
+ procedure InitializeRecord;
+ procedure SetVolume(Volume: integer);
+ procedure SetMusicVolume(Volume: integer);
+ procedure SetLoop(Enabled: boolean);
+ function Open(Name: string): boolean; // true if succeed
+ procedure Rewind;
+ procedure MoveTo(Time: real);
+ procedure Play;
+ procedure Pause; //Pause Mod
+ procedure Stop;
+ procedure Close;
+ function Finished: boolean;
+ function Length: real;
+ function Position: real;
+ procedure PlayStart;
+ procedure PlayBack;
+ procedure PlaySwoosh;
+ procedure PlayChange;
+ procedure PlayOption;
+ procedure PlayClick;
+ procedure PlayDrum;
+ procedure PlayHihat;
+ procedure PlayClap;
+ procedure PlayShuffle;
+ procedure StopShuffle;
+ procedure CaptureStart;
+ procedure CaptureStop;
+ procedure CaptureCard(RecordI, PlayerLeft, PlayerRight: byte);
+ procedure StopCard(Card: byte);
+ function LoadSoundFromFile(var hStream: hStream; Name: string): boolean;
+
+ //Equalizer
+ function GetFFTData: TFFTData;
+
+ //Custom Sounds
+ function LoadCustomSound(const Filename: String): Cardinal;
+ procedure PlayCustomSound(const Index: Cardinal);
+
+end;
+
+const
+ RecordSystem = 1;
+
+type
+ TMuzyka = record
+ Path: string;
+ Start: integer; // start of song in ms
+ IlNut: integer;
+ DlugoscNut: integer;
+ end;
+
+ TCzesci = record
+ Akt: integer; // aktualna czesc utworu do rysowania
+ High: integer;
+ Ilosc: integer;
+ Resolution: integer;
+ NotesGAP: integer;
+ Wartosc: integer;
+ Czesc: array of record
+ Start: integer;
+ StartNote: integer;
+ Lyric: string;
+ LyricWidth: real;
+ Koniec: integer;
+ BaseNote: integer;
+ HighNut: integer;
+ IlNut: integer;
+ TotalNotes: integer;
+ Nuta: array of record
+ Color: integer;
+ Start: integer;
+ Dlugosc: integer;
+ Ton: integer;
+ TonGamy: integer;
+ Tekst: string;
+ FreeStyle: boolean;
+ Wartosc: integer; // zwykla nuta x1, zlota nuta x2
+ end;
+ end;
+ end;
+
+ TCzas = record // wszystko, co dotyczy aktualnej klatki
+ OldBeat: integer; // poprzednio wykryty beat w utworze
+ AktBeat: integer; // aktualny beat w utworze
+ MidBeat: real; // dokladny AktBeat
+
+ // now we use this for super synchronization!
+ // only used when analyzing voice
+ OldBeatD: integer; // poprzednio wykryty beat w utworze
+ AktBeatD: integer; // aktualny beat w utworze
+ MidBeatD: real; // dokladny AktBeatD
+ FracBeatD: real; // fractional part of MidBeatD
+
+ // we use this for audiable clicks
+ OldBeatC: integer; // poprzednio wykryty beat w utworze
+ AktBeatC: integer; // aktualny beat w utworze
+ MidBeatC: real; // dokladny AktBeatC
+ FracBeatC: real; // fractional part of MidBeatC
+
+
+ OldCzesc: integer; // poprzednio wyswietlana czesc
+ // akt jest w czesci.akt
+
+ Teraz: real; // aktualny czas w utworze
+ Razem: real; // caly czas utworu
+ end;
+
+var
+ Music: TMusic;
+
+ // muzyka
+ Muzyka: TMuzyka;
+
+ // czesci z nutami;
+ Czesci: array of TCzesci;
+
+ // czas
+ Czas: TCzas;
+
+ fHWND: Thandle;
+
+type
+ TMPModes = (mpNotReady, mpStopped, mpPlaying, mpRecording, mpSeeking,
+ mpPaused, mpOpen);
+
+const
+ ModeStr: array[TMPModes] of string = ('Not ready', 'Stopped', 'Playing', 'Recording', 'Seeking', 'Paused', 'Open');
+
+implementation
+
+uses
+ {$IFDEF FPC}
+ lclintf,
+ {$ENDIF}
+ UGraphic,
+ URecord,
+ UFiles,
+ UIni,
+ UMain,
+ UThemes;
+
+procedure InitializeSound;
+begin
+ Log.LogStatus('Initializing Playback', 'InitializeSound'); Music.InitializePlayback;
+ Log.LogStatus('Initializing Record', 'InitializeSound'); Music.InitializeRecord;
+end;
+
+procedure TMusic.InitializePlayback;
+var
+ Pet: integer;
+ S: integer;
+begin
+ Log.BenchmarkStart(4);
+ Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize');
+
+ Loaded := false;
+ Loop := false;
+
+ fHWND := AllocateHWND( nil); // TODO : JB_lazarus - can we do something different here ?? lazarus didnt like this function
+
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ if not BASS_Init(1, 44100, 0, fHWND, nil) then
+ begin
+ {$IFNDEF FPC}
+ // TODO : JB_lazarus find a way to do this nice..
+ Application.MessageBox ('Could not initialize BASS', 'Error');
+ {$ENDIF}
+ Exit;
+ end;
+ {$ENDIF}
+
+ Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4);
+
+ // config playing buffer
+// BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 10);
+// BASS_SetConfig(BASS_CONFIG_BUFFER, 100);
+
+ Log.LogStatus('Loading Sounds', 'Music Initialize');
+
+ Log.BenchmarkStart(4);
+ LoadSoundFromFile(BassStart, SoundPath + 'Common Start.mp3');
+ LoadSoundFromFile(BassBack, SoundPath + 'Common Back.mp3');
+ LoadSoundFromFile(BassSwoosh, SoundPath + 'menu swoosh.mp3');
+ LoadSoundFromFile(BassChange, SoundPath + 'select music change music 50.mp3');
+ LoadSoundFromFile(BassOption, SoundPath + 'option change col.mp3');
+ LoadSoundFromFile(BassClick, SoundPath + 'rimshot022b.mp3');
+
+// LoadSoundFromFile(BassDrum, SoundPath + 'bassdrumhard076b.mp3');
+// LoadSoundFromFile(BassHihat, SoundPath + 'hihatclosed068b.mp3');
+// LoadSoundFromFile(BassClap, SoundPath + 'claps050b.mp3');
+
+// LoadSoundFromFile(BassShuffle, SoundPath + 'Shuffle.mp3');
+
+ Log.BenchmarkEnd(4); Log.LogBenchmark('--> Loading Sounds', 4);
+end;
+
+procedure TMusic.InitializeRecord;
+var
+ S: integer;
+ device: integer;
+ descr: string;
+ input: integer;
+ input2: integer;
+ flags: integer;
+ mic: array[0..15] of integer;
+ SC: integer; // soundcard
+ SCI: integer; // soundcard input
+begin
+ if RecordSystem = 1 then begin
+ SetLength(Sound, 6 {max players});//Ini.Players+1);
+ for S := 0 to High(Sound) do begin //Ini.Players do begin
+ Sound[S] := TSound.Create;
+ Sound[S].Num := S;
+ Sound[S].BufferNew := TMemoryStream.Create;
+ SetLength(Sound[S].BufferLong, 1);
+ Sound[S].BufferLong[0] := TMemoryStream.Create;
+ Sound[S].n := 4*1024;
+ end;
+
+
+ // check for recording devices;
+ {device := 0;
+ descr := BASS_RecordGetDeviceDescription(device);
+
+ SetLength(SoundCard, 0);
+ while (descr <> '') do begin
+ SC := High(SoundCard) + 1;
+ SetLength(SoundCard, SC+1);
+
+ Log.LogAnalyze('Device #'+IntToStr(device)+': '+ descr);
+ SoundCard[SC].Description := Descr;
+
+ // check for recording inputs
+ mic[device] := -1; // default to no change
+ input := 0;
+ BASS_RecordInit(device);
+ Log.LogAnalyze('Input #' + IntToStr(Input) + ': ' + BASS_RecordGetInputName(input));
+ flags := BASS_RecordGetInput(input);
+
+ SetLength(SoundCard[SC].Input, 0);
+ while (flags <> -1) do begin
+ SCI := High(SoundCard[SC].Input) + 1;
+ SetLength(SoundCard[SC].Input, SCI+1);
+
+ Log.LogAnalyze('Input #' + IntToStr(Input) + ': ' + BASS_RecordGetInputName(input));
+ SoundCard[SC].Input[SCI].Name := BASS_RecordGetInputName(Input);
+
+ if (flags and BASS_INPUT_TYPE_MASK) = BASS_INPUT_TYPE_MIC then begin
+ mic[device] := input; // auto set microphone
+ end;
+ Inc(Input);
+ flags := BASS_RecordGetInput(input);
+ end;
+
+ if mic[device] <> -1 then begin
+ Log.LogAnalyze('Found the mic at input ' + IntToStr(Mic[device]))
+ end else begin
+ Log.LogAnalyze('Mic not found');
+ mic[device] := 0; // setting to the first one (for kxproject)
+ end;
+ SoundCard[SC].InputSeleceted := Mic[Device];
+
+
+ BASS_RecordFree;
+
+ inc(Device);
+ descr := BASS_RecordGetDeviceDescription(Device);
+ end; // while}
+ end; // if
+end;
+
+procedure TMusic.SetVolume(Volume: integer);
+begin
+ //Old Sets Wave Volume
+ //BASS_SetVolume(Volume);
+ //New: Sets Volume only for this Application
+
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ BASS_SetConfig(BASS_CONFIG_GVOL_SAMPLE, Volume);
+ BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume);
+ BASS_SetConfig(BASS_CONFIG_GVOL_MUSIC, Volume);
+ {$ENDIF}
+end;
+
+procedure TMusic.SetMusicVolume(Volume: Integer);
+begin
+ //Max Volume Prevention
+ if Volume > 100 then
+ Volume := 100;
+
+ //Set Volume
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ BASS_ChannelSetAttributes (Bass, -1, Volume, -101);
+ {$ENDIF}
+end;
+
+procedure TMusic.SetLoop(Enabled: boolean);
+begin
+ Loop := Enabled;
+end;
+
+function TMusic.Open(Name: string): boolean;
+begin
+ Loaded := false;
+ if FileExists(Name) then
+ begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ Bass := Bass_StreamCreateFile(false, pchar(Name), 0, 0, 0);
+ {$ENDIF}
+
+ Loaded := true;
+ //Set Max Volume
+ SetMusicVolume (100);
+ end;
+
+ Result := Loaded;
+end;
+
+procedure TMusic.Rewind;
+begin
+ if Loaded then begin
+ end;
+end;
+
+procedure TMusic.MoveTo(Time: real);
+var
+ bytes: integer;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ bytes := BASS_ChannelSeconds2Bytes(Bass, Time);
+ BASS_ChannelSetPosition(Bass, bytes);
+ {$ENDIF}
+end;
+
+procedure TMusic.Play;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ if Loaded then
+ begin
+ if Loop then
+ BASS_ChannelPlay(Bass, True); // start from beginning... actually bass itself does not loop, nor does this TMusic Class
+
+ BASS_ChannelPlay(Bass, False); // for setting position before playing
+ end;
+ {$ENDIF}
+end;
+
+procedure TMusic.Pause; //Pause Mod
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ if Loaded then begin
+ BASS_ChannelPause(Bass); // Pauses Song
+ end;
+ {$ENDIF}
+end;
+
+procedure TMusic.Stop;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ Bass_ChannelStop(Bass);
+ {$ENDIF}
+end;
+
+procedure TMusic.Close;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ Bass_StreamFree(Bass);
+ {$ENDIF}
+end;
+
+function TMusic.Length: real;
+var
+ bytes: integer;
+begin
+ Result := 60;
+
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ bytes := BASS_ChannelGetLength(Bass);
+ Result := BASS_ChannelBytes2Seconds(Bass, bytes);
+ {$ENDIF}
+end;
+
+function TMusic.Position: real;
+var
+ bytes: integer;
+begin
+ Result := 0;
+
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ bytes := BASS_ChannelGetPosition(BASS);
+ Result := BASS_ChannelBytes2Seconds(BASS, bytes);
+ {$ENDIF}
+end;
+
+function TMusic.Finished: boolean;
+begin
+ Result := false;
+
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ if BASS_ChannelIsActive(BASS) = BASS_ACTIVE_STOPPED then
+ begin
+ Result := true;
+ end;
+ {$ENDIF}
+end;
+
+procedure TMusic.PlayStart;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ BASS_ChannelPlay(BassStart, True);
+ {$ENDIF}
+end;
+
+procedure TMusic.PlayBack;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ BASS_ChannelPlay(BassBack, True);// then
+ {$ENDIF}
+end;
+
+procedure TMusic.PlaySwoosh;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ BASS_ChannelPlay(BassSwoosh, True);
+ {$ENDIF}
+end;
+
+procedure TMusic.PlayChange;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ BASS_ChannelPlay(BassChange, True);
+ {$ENDIF}
+end;
+
+procedure TMusic.PlayOption;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ BASS_ChannelPlay(BassOption, True);
+ {$ENDIF}
+end;
+
+procedure TMusic.PlayClick;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ BASS_ChannelPlay(BassClick, True);
+ {$ENDIF}
+end;
+
+procedure TMusic.PlayDrum;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ BASS_ChannelPlay(BassDrum, True);
+ {$ENDIF}
+end;
+
+procedure TMusic.PlayHihat;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ BASS_ChannelPlay(BassHihat, True);
+ {$ENDIF}
+end;
+
+procedure TMusic.PlayClap;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ BASS_ChannelPlay(BassClap, True);
+ {$ENDIF}
+end;
+
+procedure TMusic.PlayShuffle;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ BASS_ChannelPlay(BassShuffle, True);
+ {$ENDIF}
+end;
+
+procedure TMusic.StopShuffle;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ BASS_ChannelStop(BassShuffle);
+ {$ENDIF}
+end;
+
+procedure TMusic.CaptureStart;
+var
+ S: integer;
+ SC: integer;
+ P1: integer;
+ P2: integer;
+begin
+ for S := 0 to High(Sound) do
+ Sound[S].BufferLong[0].Clear;
+
+ for SC := 0 to High(Ini.CardList) do begin
+ P1 := Ini.CardList[SC].ChannelL;
+ P2 := Ini.CardList[SC].ChannelR;
+ if P1 > PlayersPlay then P1 := 0;
+ if P2 > PlayersPlay then P2 := 0;
+ if (P1 > 0) or (P2 > 0) then
+ CaptureCard(SC, P1, P2);
+ end;
+end;
+
+procedure TMusic.CaptureStop;
+var
+ SC: integer;
+ P1: integer;
+ P2: integer;
+begin
+
+ for SC := 0 to High(Ini.CardList) do begin
+ P1 := Ini.CardList[SC].ChannelL;
+ P2 := Ini.CardList[SC].ChannelR;
+ if P1 > PlayersPlay then P1 := 0;
+ if P2 > PlayersPlay then P2 := 0;
+ if (P1 > 0) or (P2 > 0) then StopCard(SC);
+ end;
+
+end;
+
+//procedure TMusic.CaptureCard(RecordI, SoundNum, PlayerLeft, PlayerRight: byte);
+procedure TMusic.CaptureCard(RecordI, PlayerLeft, PlayerRight: byte);
+var
+ Error: integer;
+ ErrorMsg: string;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+
+ if not BASS_RecordInit(RecordI) then begin
+ Error := BASS_ErrorGetCode;
+
+ ErrorMsg := IntToStr(Error);
+ if Error = BASS_ERROR_DX then ErrorMsg := 'No DX5';
+ if Error = BASS_ERROR_ALREADY then ErrorMsg := 'The device has already been initialized';
+ if Error = BASS_ERROR_DEVICE then ErrorMsg := 'The device number specified is invalid';
+ if Error = BASS_ERROR_DRIVER then ErrorMsg := 'There is no available device driver';
+
+ {Log.LogAnalyze('Error initializing record [' + IntToStr(RecordI) + ', '
+ + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: '
+ + ErrorMsg);}
+ Log.LogError('Error initializing record [' + IntToStr(RecordI) + ', '
+ + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: '
+ + ErrorMsg);
+ Log.LogError('Music -> CaptureCard: Error initializing record: ' + ErrorMsg);
+
+
+ end
+ else
+ begin
+ Recording.SoundCard[RecordI].BassRecordStream := BASS_RecordStart(44100, 2, MakeLong(0, 20) , @GetMicrophone, PlayerLeft + PlayerRight*256);
+ end;
+
+ {$ENDIF}
+end;
+
+procedure TMusic.StopCard(Card: byte);
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ BASS_RecordSetDevice(Card);
+ BASS_RecordFree;
+ {$ENDIF}
+end;
+
+function TMusic.LoadSoundFromFile(var hStream: hStream; Name: string): boolean;
+var
+ L: Integer;
+begin
+ if FileExists(Name) then begin
+ Log.LogStatus('Loading Sound: "' + Name + '"', 'LoadSoundFromFile');
+ try
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+ hStream := BASS_StreamCreateFile(False, pchar(Name), 0, 0, 0);
+ {$ENDIF}
+
+ //Add CustomSound
+ L := High(CustomSounds) + 1;
+ SetLength (CustomSounds, L + 1);
+ CustomSounds[L].Filename := Name;
+ CustomSounds[L].Handle := hStream;
+ except
+ Log.LogError('Failed to open using BASS', 'LoadSoundFromFile');
+ end;
+ end else begin
+ Log.LogError('Sound not found: "' + Name + '"', 'LoadSoundFromFile');
+ exit;
+ end;
+end;
+
+//Equalizer
+function TMusic.GetFFTData: TFFTData;
+var
+Data: TFFTData;
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+
+ //Get Channel Data Mono and 256 Values
+ BASS_ChannelGetData(Bass, @Result, BASS_DATA_FFT512);
+ //Result := Data;
+
+ {$ENDIF}
+end;
+
+function TMusic.LoadCustomSound(const Filename: String): Cardinal;
+var
+ S: hStream;
+ I: Integer;
+ F: String;
+begin
+ //Search for Sound in already loaded Sounds
+ F := UpperCase(SoundPath + FileName);
+ For I := 0 to High(CustomSounds) do
+ begin
+ if (UpperCase(CustomSounds[I].Filename) = F) then
+ begin
+ Result := I;
+ Exit;
+ end;
+ end;
+
+ if LoadSoundFromFile(S, SoundPath + Filename) then
+ Result := High(CustomSounds)
+ else
+ Result := 0;
+end;
+
+procedure TMusic.PlayCustomSound(const Index: Cardinal);
+begin
+ {$IFDEF useBASS}
+ // TODO : jb_linux replace with something other than bass
+
+ if Index <= High(CustomSounds) then
+ BASS_ChannelPlay(CustomSounds[Index].Handle, True);
+
+ {$ENDIF}
+end;
+
+
+end.
diff --git a/Game/Code/Classes/URecord.pas b/Game/Code/Classes/URecord.pas
index 03c87a35..d22e20d3 100644
--- a/Game/Code/Classes/URecord.pas
+++ b/Game/Code/Classes/URecord.pas
@@ -1,347 +1,359 @@
-unit URecord;
-
-interface
-
-uses Classes,
- Math,
- SysUtils,
- UMusic,
- UIni,
- BASS;
-
-type
- TSound = class
- BufferNew: TMemoryStream; // buffer for newest sample
- BufferArray: array[1..4096] of smallint; // (Signal) newest 4096 samples
- BufferLong: array of TMemoryStream; // full buffer
-
- Num: integer;
- n: integer; // length of Signal to analyze
-
- // pitch detection
- SzczytJest: boolean; // czy jest szczyt
- Szczyt: integer; // pozycja szczytu na osi poziomej
- TonDokl: real; // ton aktualnego szczytu
- Ton: integer; // ton bez ulamka
- TonGamy: integer; // ton w gamie. wartosci: 0-11
- Skala: real; // skala FFT
-
- // procedures
- procedure ProcessNewBuffer;
- procedure AnalizujBufor; // use to analyze sound from buffers to get new pitch
- procedure AnalizujByAutocorrelation; // we call it to analyze sound by checking Autocorrelation
- function AnalyzeAutocorrelationFreq(Freq: real): real; // use this to check one frequency by Autocorrelation
- end;
-
- TSoundCardInput = record
- Name: string;
- end;
-
- TSoundCard = record
- // here can be the soundcard information - whole database from which user will select recording source
- Description: string;
- Input: array of TSoundCardInput;
- InputSelected: integer;
- MicInput: Integer;
-
- // bass record
- BassRecordStream: hStream;
- end;
-
- TRecord = class
- SoundCard: array of TSoundCard;
- constructor Create;
- end;
-
- smallintarray = array [0..maxInt shr 1-1] of smallInt;
- psmallintarray = ^smallintarray;
-
- // procedures - bass record
- function GetMicrophone(handle: HSTREAM; buffer: Pointer; len: DWORD; user: DWORD): boolean; stdcall;
-
-
-var
- Sound: array of TSound;
- SoundCard: array of TSoundCard;
- Poz: integer;
- Recording: TRecord;
-
-implementation
-uses UMain;
-
-procedure TSound.ProcessNewBuffer;
-var
- S: integer;
- L: integer;
- A: integer;
-begin
- // process BufferArray
- S := 0;
- L := BufferNew.Size div 2;
- if L > n then begin
- S := L - n;
- L := n;
- end;
-
- // copy to array
- for A := L+1 to n do
- BufferArray[A-L] := BufferArray[A];
-
- BufferNew.Seek(2*S, soBeginning);
- BufferNew.ReadBuffer(BufferArray[1+n-L], 2*L);
-
- // process BufferLong
- if Ini.SavePlayback = 1 then
- begin
- BufferNew.Seek(0, soBeginning);
- BufferLong[0].CopyFrom(BufferNew, BufferNew.Size);
- end;
-end;
-
-procedure TSound.AnalizujBufor;
-begin
- AnalizujByAutocorrelation;
-end;
-
-procedure TSound.AnalizujByAutocorrelation;
-var
- T: integer; // tone
- F: real; // freq
- Wages: array[0..35] of real; // wages
- MaxT: integer; // max tone
- MaxW: real; // max wage
- V: real; // volume
- MaxV: real; // max volume
- S: integer; // Signal
- Threshold: real; // threshold
-begin
- SzczytJest := false;
-
- // find maximum volume of first 1024 words of signal
- MaxV := 0;
- for S := 1 to 1024 do // 0.5.2: fix. was from 0 to 1023
- begin
- V := Abs(BufferArray[S]) / $10000;
-
- if V > MaxV then
- MaxV := V;
- end;
-
- // prepare to analyze
- MaxW := 0;
-
- // analyze all 12 halftones
- for T := 0 to 35 do // to 11, then 23, now 35 (for Whitney and my high voice)
- begin
- F := 130.81*Power(1.05946309436, T)/2; // let's analyze below 130.81
- Wages[T] := AnalyzeAutocorrelationFreq(F);
-
- if Wages[T] > MaxW then
- begin // this frequency has better wage
- MaxW := Wages[T];
- MaxT := T;
- end;
- end; // for T
-
- Threshold := 0.1;
- case Ini.Threshold of
- 0: Threshold := 0.05;
- 1: Threshold := 0.1;
- 2: Threshold := 0.15;
- 3: Threshold := 0.2;
- end;
-
- if MaxV >= Threshold then
- begin // found acceptable volume // 0.1
- SzczytJest := true;
- TonGamy := MaxT mod 12;
- Ton := MaxT mod 12;
- end;
-
-end;
-
-function TSound.AnalyzeAutocorrelationFreq(Freq: real): real; // result medium difference
-var
- Count: real;
- Src: integer;
- Dst: integer;
- Move: integer;
- Il: integer; // how many counts were done
-begin
- // we use Signal as source
- Count := 0;
- Il := 0;
- Src := 1;
- Move := Round(44100/Freq);
- Dst := Src + Move;
-
- // ver 2 - compare in vertical
- while (Dst < n) do
- begin // process up to n (4KB) of Signal
- Count := Count + Abs(BufferArray[Src] - BufferArray[Dst]) / $10000;
- Inc(Src);
- Inc(Dst);
- Inc(Il);
- end;
-
- Result := 1 - Count / Il;
-end;
-
-function GetMicrophone(handle: HSTREAM; buffer: Pointer; len: DWORD; user: DWORD): boolean; stdcall;
-var
- L: integer;
- S: integer;
- PB: pbytearray;
- PSI: psmallintarray;
- I: integer;
- Skip: integer;
- P1: integer;
- P2: integer;
- Boost: byte;
-begin
- // set boost
- case Ini.MicBoost of
- 0: Boost := 1;
- 1: Boost := 2;
- 2: Boost := 4;
- 3: Boost := 8;
- end;
-
- // boost buffer
- L := Len div 2; // number of samples
- PSI := Buffer;
- for S := 0 to L-1 do
- begin
- I := PSI^[S] * Boost;
- if I > 32767 then I := 32767; // 0.5.0: limit
- if I < -32768 then I := -32768; // 0.5.0: limit
- PSI^[S] := I;
- end;
-
- // decode user
- P1 := (user and 255) - 1;
- P2 := (user div 256) - 1;
-
-
- // 2 players USB mic, left channel
- if P1 >= 0 then
- begin
- L := Len div 4; // number of samples
- PB := Buffer;
-
- Sound[P1].BufferNew.Clear; // 0.5.2: problem on exiting
- for S := 1 to L do
- begin
- Sound[P1].BufferNew.Write(PB[(S-1)*4], 2);
- end;
- Sound[P1].ProcessNewBuffer;
- end;
-
- // 2 players USB mic, right channel
- Skip := 2;
-
- if P2 >= 0 then
- begin
- L := Len div 4; // number of samples
- PB := Buffer;
- Sound[P2].BufferNew.Clear;
- for S := 1 to L do
- begin
- Sound[P2].BufferNew.Write(PB[Skip + (S-1)*4], 2);
- end;
- Sound[P2].ProcessNewBuffer;
- end;
-
- Result := true;
-end;
-
-constructor TRecord.Create;
-var
- SC: integer; // soundcard
- SCI: integer; // soundcard input
- Descr: string;
- InputName: PChar;
- Flags: integer;
- No: integer;
-
- function isDuplicate(Desc: String): Boolean;
- var
- I: Integer;
- begin
- Result := False;
- //Check for Soundcard with same Description
- For I := 0 to SC-1 do
- begin
- if (SoundCard[I].Description = Desc) then
- begin
- Result := True;
- Break;
- end;
- end;
- end;
-
-begin
- // checks for recording devices and puts them into array;
- SetLength(SoundCard, 0);
-
- SC := 0;
- Descr := BASS_RecordGetDeviceDescription(SC);
-
- while (Descr <> '') do
- begin
-
- //If there is another SoundCard with the Same ID, Search an available Name
- if (IsDuplicate(Descr)) then
- begin
- No:= 1; //Count of SoundCards with same Name
- Repeat
- Inc(No)
- Until not IsDuplicate(Descr + ' (' + InttoStr(No) + ')');
-
- //Set Description
- Descr := Descr + ' (' + InttoStr(No) + ')';
- end;
-
- SetLength(SoundCard, SC+1);
-
- SoundCard[SC].Description := Descr;
-
- //Get Recording Inputs
- SCI := 0;
- BASS_RecordInit(SC);
-
- InputName := BASS_RecordGetInputName(SCI);
-
- SetLength(SoundCard[SC].Input, 1);
- SoundCard[SC].Input[SCI].Name := InputName;
-
- // process each input
- while (InputName <> nil) do
- begin
- Flags := BASS_RecordGetInput(SCI);
- if (SCI >= 1) {AND (Flags AND BASS_INPUT_OFF = 0)} then
- begin
- SetLength(SoundCard[SC].Input, SCI+1);
- SoundCard[SC].Input[SCI].Name := InputName;
- end;
-
- //Set Mic Index
- if ((Flags and BASS_INPUT_TYPE_MIC) = 1) then
- SoundCard[SC].MicInput := SCI;
-
- Inc(SCI);
- InputName := BASS_RecordGetInputName(SCI);
- end;
-
- BASS_RecordFree;
-
- Inc(SC);
- Descr := BASS_RecordGetDeviceDescription(SC);
- end; // while
-end;
-
-
-end.
-
-
-
+unit URecord;
+
+interface
+
+{$I switches.inc}
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+uses Classes,
+ Math,
+ SysUtils,
+ {$IFDEF useBASS}
+ bass,
+ {$ENDIF}
+ UCommon,
+ UMusic,
+ UIni;
+
+type
+ TSound = class
+ BufferNew: TMemoryStream; // buffer for newest sample
+ BufferArray: array[1..4096] of smallint; // (Signal) newest 4096 samples
+ BufferLong: array of TMemoryStream; // full buffer
+
+ Num: integer;
+ n: integer; // length of Signal to analyze
+
+ // pitch detection
+ SzczytJest: boolean; // czy jest szczyt
+ Szczyt: integer; // pozycja szczytu na osi poziomej
+ TonDokl: real; // ton aktualnego szczytu
+ Ton: integer; // ton bez ulamka
+ TonGamy: integer; // ton w gamie. wartosci: 0-11
+ Skala: real; // skala FFT
+
+ // procedures
+ procedure ProcessNewBuffer;
+ procedure AnalizujBufor; // use to analyze sound from buffers to get new pitch
+ procedure AnalizujByAutocorrelation; // we call it to analyze sound by checking Autocorrelation
+ function AnalyzeAutocorrelationFreq(Freq: real): real; // use this to check one frequency by Autocorrelation
+ end;
+
+ TSoundCardInput = record
+ Name: string;
+ end;
+
+ TSoundCard = record
+ // here can be the soundcard information - whole database from which user will select recording source
+ Description: string;
+ Input: array of TSoundCardInput;
+ InputSelected: integer;
+ MicInput: Integer;
+
+ // bass record
+ BassRecordStream: hStream;
+ end;
+
+ TRecord = class
+ SoundCard: array of TSoundCard;
+ constructor Create;
+ end;
+
+ smallintarray = array [0..maxInt shr 1-1] of smallInt;
+ psmallintarray = ^smallintarray;
+
+ // procedures - bass record
+ function GetMicrophone(handle: HSTREAM; buffer: Pointer; len: DWORD; user: DWORD): boolean; stdcall;
+
+
+var
+ Sound: array of TSound;
+ SoundCard: array of TSoundCard;
+ Poz: integer;
+ Recording: TRecord;
+
+implementation
+uses UMain;
+
+procedure TSound.ProcessNewBuffer;
+var
+ S: integer;
+ L: integer;
+ A: integer;
+begin
+ // process BufferArray
+ S := 0;
+ L := BufferNew.Size div 2;
+ if L > n then begin
+ S := L - n;
+ L := n;
+ end;
+
+ // copy to array
+ for A := L+1 to n do
+ BufferArray[A-L] := BufferArray[A];
+
+ BufferNew.Seek(2*S, soBeginning);
+ BufferNew.ReadBuffer(BufferArray[1+n-L], 2*L);
+
+ // process BufferLong
+ if Ini.SavePlayback = 1 then
+ begin
+ BufferNew.Seek(0, soBeginning);
+ BufferLong[0].CopyFrom(BufferNew, BufferNew.Size);
+ end;
+end;
+
+procedure TSound.AnalizujBufor;
+begin
+ AnalizujByAutocorrelation;
+end;
+
+procedure TSound.AnalizujByAutocorrelation;
+var
+ T: integer; // tone
+ F: real; // freq
+ Wages: array[0..35] of real; // wages
+ MaxT: integer; // max tone
+ MaxW: real; // max wage
+ V: real; // volume
+ MaxV: real; // max volume
+ S: integer; // Signal
+ Threshold: real; // threshold
+begin
+ SzczytJest := false;
+
+ // find maximum volume of first 1024 words of signal
+ MaxV := 0;
+ for S := 1 to 1024 do // 0.5.2: fix. was from 0 to 1023
+ begin
+ V := Abs(BufferArray[S]) / $10000;
+
+ if V > MaxV then
+ MaxV := V;
+ end;
+
+ // prepare to analyze
+ MaxW := 0;
+
+ // analyze all 12 halftones
+ for T := 0 to 35 do // to 11, then 23, now 35 (for Whitney and my high voice)
+ begin
+ F := 130.81*Power(1.05946309436, T)/2; // let's analyze below 130.81
+ Wages[T] := AnalyzeAutocorrelationFreq(F);
+
+ if Wages[T] > MaxW then
+ begin // this frequency has better wage
+ MaxW := Wages[T];
+ MaxT := T;
+ end;
+ end; // for T
+
+ Threshold := 0.1;
+ case Ini.Threshold of
+ 0: Threshold := 0.05;
+ 1: Threshold := 0.1;
+ 2: Threshold := 0.15;
+ 3: Threshold := 0.2;
+ end;
+
+ if MaxV >= Threshold then
+ begin // found acceptable volume // 0.1
+ SzczytJest := true;
+ TonGamy := MaxT mod 12;
+ Ton := MaxT mod 12;
+ end;
+
+end;
+
+function TSound.AnalyzeAutocorrelationFreq(Freq: real): real; // result medium difference
+var
+ Count: real;
+ Src: integer;
+ Dst: integer;
+ Move: integer;
+ Il: integer; // how many counts were done
+begin
+ // we use Signal as source
+ Count := 0;
+ Il := 0;
+ Src := 1;
+ Move := Round(44100/Freq);
+ Dst := Src + Move;
+
+ // ver 2 - compare in vertical
+ while (Dst < n) do
+ begin // process up to n (4KB) of Signal
+ Count := Count + Abs(BufferArray[Src] - BufferArray[Dst]) / $10000;
+ Inc(Src);
+ Inc(Dst);
+ Inc(Il);
+ end;
+
+ Result := 1 - Count / Il;
+end;
+
+function GetMicrophone(handle: HSTREAM; buffer: Pointer; len: DWORD; user: DWORD): boolean; stdcall;
+var
+ L: integer;
+ S: integer;
+ PB: pbytearray;
+ PSI: psmallintarray;
+ I: integer;
+ Skip: integer;
+ P1: integer;
+ P2: integer;
+ Boost: byte;
+begin
+ // set boost
+ case Ini.MicBoost of
+ 0: Boost := 1;
+ 1: Boost := 2;
+ 2: Boost := 4;
+ 3: Boost := 8;
+ end;
+
+ // boost buffer
+ L := Len div 2; // number of samples
+ PSI := Buffer;
+ for S := 0 to L-1 do
+ begin
+ I := PSI^[S] * Boost;
+ if I > 32767 then I := 32767; // 0.5.0: limit
+ if I < -32768 then I := -32768; // 0.5.0: limit
+ PSI^[S] := I;
+ end;
+
+ // decode user
+ P1 := (user and 255) - 1;
+ P2 := (user div 256) - 1;
+
+
+ // 2 players USB mic, left channel
+ if P1 >= 0 then
+ begin
+ L := Len div 4; // number of samples
+ PB := Buffer;
+
+ Sound[P1].BufferNew.Clear; // 0.5.2: problem on exiting
+ for S := 1 to L do
+ begin
+ Sound[P1].BufferNew.Write(PB[(S-1)*4], 2);
+ end;
+ Sound[P1].ProcessNewBuffer;
+ end;
+
+ // 2 players USB mic, right channel
+ Skip := 2;
+
+ if P2 >= 0 then
+ begin
+ L := Len div 4; // number of samples
+ PB := Buffer;
+ Sound[P2].BufferNew.Clear;
+ for S := 1 to L do
+ begin
+ Sound[P2].BufferNew.Write(PB[Skip + (S-1)*4], 2);
+ end;
+ Sound[P2].ProcessNewBuffer;
+ end;
+
+ Result := true;
+end;
+
+constructor TRecord.Create;
+var
+ SC: integer; // soundcard
+ SCI: integer; // soundcard input
+ Descr: string;
+ InputName: PChar;
+ Flags: integer;
+ No: integer;
+
+ function isDuplicate(Desc: String): Boolean;
+ var
+ I: Integer;
+ begin
+ Result := False;
+ //Check for Soundcard with same Description
+ For I := 0 to SC-1 do
+ begin
+ if (SoundCard[I].Description = Desc) then
+ begin
+ Result := True;
+ Break;
+ end;
+ end;
+ end;
+
+begin
+ // TODO : JB_linux - Reimplement recording, without bass for linux
+ {$IFDEF useBASS}
+ // checks for recording devices and puts them into array;
+ SetLength(SoundCard, 0);
+
+ SC := 0;
+ Descr := BASS_RecordGetDeviceDescription(SC);
+
+ while (Descr <> '') do
+ begin
+
+ //If there is another SoundCard with the Same ID, Search an available Name
+ if (IsDuplicate(Descr)) then
+ begin
+ No:= 1; //Count of SoundCards with same Name
+ Repeat
+ Inc(No)
+ Until not IsDuplicate(Descr + ' (' + InttoStr(No) + ')');
+
+ //Set Description
+ Descr := Descr + ' (' + InttoStr(No) + ')';
+ end;
+
+ SetLength(SoundCard, SC+1);
+
+ SoundCard[SC].Description := Descr;
+
+ //Get Recording Inputs
+ SCI := 0;
+ BASS_RecordInit(SC);
+
+ InputName := BASS_RecordGetInputName(SCI);
+
+ SetLength(SoundCard[SC].Input, 1);
+ SoundCard[SC].Input[SCI].Name := InputName;
+
+ // process each input
+ while (InputName <> nil) do
+ begin
+ Flags := BASS_RecordGetInput(SCI);
+ if (SCI >= 1) {AND (Flags AND BASS_INPUT_OFF = 0)} then
+ begin
+ SetLength(SoundCard[SC].Input, SCI+1);
+ SoundCard[SC].Input[SCI].Name := InputName;
+ end;
+
+ //Set Mic Index
+ if ((Flags and BASS_INPUT_TYPE_MIC) = 1) then
+ SoundCard[SC].MicInput := SCI;
+
+ Inc(SCI);
+ InputName := BASS_RecordGetInputName(SCI);
+ end;
+
+ BASS_RecordFree;
+
+ Inc(SC);
+ Descr := BASS_RecordGetDeviceDescription(SC);
+ end; // while
+ {$ENDIF}
+end;
+
+
+end.
+
+
+
diff --git a/Game/Code/Classes/UTexture.pas b/Game/Code/Classes/UTexture.pas
index 7f0b85c0..1bc4c558 100644
--- a/Game/Code/Classes/UTexture.pas
+++ b/Game/Code/Classes/UTexture.pas
@@ -1,1028 +1,1043 @@
-unit UTexture;
-
-// Plain (alpha = 1)
-// Transparent
-// Transparent Range
-// Font (white is drawn, black is transparent)
-// Font Outline (Font with darker outline)
-// Font Outline 2 (Font with darker outline)
-// Font Black (black is drawn, white is transparent)
-// Font Gray (gray is drawn, white is transparent)
-// Arrow (for arrows, white is white, gray has color, black is transparent);
-
-interface
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-uses OpenGL12,
- Windows,
- Math,
- Classes,
- SysUtils,
- {$IFDEF FPC}
- ulazjpeg,
- {$ELSE}
- Graphics,
- JPEG,
- PNGImage,
- {$ENDIF}
- UCommon,
- UThemes;
-
-
-procedure glGenTextures(n: GLsizei; var textures: GLuint); stdcall; external opengl32;
-
-type
- TTexture = record
- TexNum: integer;
- X: real;
- Y: real;
- Z: real; // new
- W: real;
- H: real;
- ScaleW: real; // for dynamic scalling while leaving width constant
- ScaleH: real; // for dynamic scalling while leaving height constant
- Rot: real; // 0 - 2*pi
- Int: real; // intensity
- ColR: real;
- ColG: real;
- ColB: real;
- TexW: real; // used?
- TexH: real; // used?
- TexX1: real;
- TexY1: real;
- TexX2: real;
- TexY2: real;
- Alpha: real;
- Name: string; // 0.5.0: experimental for handling cache images. maybe it's useful for dynamic skins
- end;
-
- TTextureEntry = record
- Name: string;
- Typ: string;
-
- // we use normal TTexture, it's easier to implement and if needed - we copy ready data
- Texture: TTexture;
- TextureCache: TTexture; // 0.5.0
- end;
-
- TTextureDatabase = record
- Texture: array of TTextureEntry;
- end;
-
- TTextureUnit = class
- Limit: integer;
- CreateCacheMipmap: boolean;
-
-// function GetNumberFor
- function GetTexture(Name, Typ: string): TTexture; overload;
- function GetTexture(Name, Typ: string; FromCache: boolean): TTexture; overload;
- function FindTexture(Name: string): integer;
- function LoadTexture(FromRegistry: boolean; Identifier, Format, Typ: PChar; Col: LongWord): TTexture; overload;
- function LoadTexture(Identifier, Format, Typ: PChar; Col: LongWord): TTexture; overload;
- function LoadTexture(Identifier: string): TTexture; overload;
- function CreateTexture(var Data: array of byte; Name: string; W, H: word; Bits: byte): TTexture;
- procedure UnloadTexture(Name: string; FromCache: boolean);
- end;
-
-var
- lasthue: double;
- Texture: TTextureUnit;
- TextureDatabase: TTextureDatabase;
-
- PrintScreenData: array[0..1024*768-1] of longword;
-
- ActTex: GLuint;//integer;
-
- TexOrigW: integer;
- TexOrigH: integer;
- TexNewW: integer;
- TexNewH: integer;
-
- TexFitW: integer;
- TexFitH: integer; // new for limit
-
- TextureD8: array[1..1024*1024] of byte; // 1MB
- TextureD16: array[1..1024*1024, 1..2] of byte; // luminance/alpha tex (2MB)
- TextureD24: array[1..1024*1024, 1..3] of byte; // normal 24-bit tex (3MB)
- TextureD242: array[1..512*512, 1..3] of byte; // normal 24-bit tex (0,75MB)
- TextureD32: array[1..1024*1024, 1..4] of byte; // transparent 32-bit tex (4MB)
- // total 40MB at 2048*2048
- // total 10MB at 1024*1024
-
- Mipmapping: Boolean;
-
- CacheMipmap: array[0..256*256*3-1] of byte; // 3KB
-
-
-implementation
-uses ULog, DateUtils, UCovers, StrUtils;
-
-function TTextureUnit.GetTexture(Name, Typ: string): TTexture;
-begin
- Result := GetTexture(Name, Typ, true);
-end;
-
-function TTextureUnit.GetTexture(Name, Typ: string; FromCache: boolean): TTexture;
-var
- T: integer; // texture
- C: integer; // cover
- Data: array of byte;
-begin
- // find texture entry
- T := FindTexture(Name);
-
- if T = -1 then begin
- // create texture entry
- T := Length(TextureDatabase.Texture);
- SetLength(TextureDatabase.Texture, T+1);
- TextureDatabase.Texture[T].Name := Name;
- TextureDatabase.Texture[T].Typ := Typ;
-
- // inform database that no textures have been loaded into memory
- TextureDatabase.Texture[T].Texture.TexNum := -1;
- TextureDatabase.Texture[T].TextureCache.TexNum := -1;
- end;
-
- // use preloaded texture
- if (not FromCache) or (FromCache and not Covers.CoverExists(Name)) then begin
- // use full texture
- if TextureDatabase.Texture[T].Texture.TexNum = -1 then begin
- // load texture
- TextureDatabase.Texture[T].Texture := LoadTexture(false, pchar(Name), 'JPG', pchar(Typ), $0);
- end;
-
- // use texture
- Result := TextureDatabase.Texture[T].Texture;
-
- end;
-
- if FromCache and Covers.CoverExists(Name) then begin
- // use cache texture
- C := Covers.CoverNumber(Name);
-
- if TextureDatabase.Texture[T].TextureCache.TexNum = -1 then begin
- // load texture
- Covers.PrepareData(Name);
- TextureDatabase.Texture[T].TextureCache := CreateTexture(Covers.Data, Name, Covers.Cover[C].W, Covers.Cover[C].H, 24);
- end;
-
- // use texture
- Result := TextureDatabase.Texture[T].TextureCache;
- end;
-end;
-
-function TTextureUnit.FindTexture(Name: string): integer;
-var
- T: integer; // texture
-begin
- Result := -1;
- for T := 0 to high(TextureDatabase.Texture) do
- if TextureDatabase.Texture[T].Name = Name then
- Result := T;
-end;
-
-// expects: src, dst: pointers to r,g,b,a
-// hue: new hue within range [0.0-6.0)
-procedure ColorizeCopy(Src, Dst: PByteArray; hue: Double); overload;
-var
- i,j,k: Cardinal;
- clr, hls: array[0..2] of Double;
- delta, f, p, q, t: Double;
-begin
- hls[0]:=hue;
-
- clr[0] := src[0]/255;
- clr[1] := src[1]/255;
- clr[2] := src[2]/255;
-
- //calculate luminance and saturation from rgb
- hls[1] := maxvalue(clr); //l:=...
- delta := hls[1] - minvalue(clr);
-
- if hls[1] = 0.0 then
- hls[2] := 0.0
- else
- hls[2] := delta/hls[1]; //v:=...
-
- // calc new rgb from our hls (h from color, l ans s from pixel)
-// if (hls[1]<>0.0) and (hls[2]<>0.0) then // only if colorizing makes sense
- begin
- k:=trunc(hls[0]);
- f:=hls[0]-k;
- p:=hls[1]*(1.0-hls[2]);
- q:=hls[1]*(1.0-(hls[2]*f));
- t:=hls[1]*(1.0-(hls[2]*(1.0-f)));
- case k of
- 0: begin clr[0]:=hls[1]; clr[1]:=t; clr[2]:=p; end;
- 1: begin clr[0]:=q; clr[1]:=hls[1]; clr[2]:=p; end;
- 2: begin clr[0]:=p; clr[1]:=hls[1]; clr[2]:=t; end;
- 3: begin clr[0]:=p; clr[1]:=q; clr[2]:=hls[1]; end;
- 4: begin clr[0]:=t; clr[1]:=p; clr[2]:=hls[1]; end;
- 5: begin clr[0]:=hls[1]; clr[1]:=p; clr[2]:=q; end;
- end;
- // and store new rgb back into the image
- dst[0]:=floor(255*clr[0]);
- dst[1]:=floor(255*clr[1]);
- dst[2]:=floor(255*clr[2]);
- dst[3]:=src[3];
- end;
-end;
-
-// expects: src: $rrggbb
-// dst: pointer to r,g,b,a
-// hue: new hue within range [0.0-6.0)
-procedure ColorizeCopy(Src: Cardinal; Dst: PByteArray; hue: Double); overload;
-var
- i,j,k: Cardinal;
- clr, hls: array[0..2] of Double;
- delta, f, p, q, t: Double;
-begin
- hls[0]:=hue;
-
- clr[0]:=((src shr 16) and $ff)/255;
- clr[1]:=((src shr 8) and $ff)/255;
- clr[2]:=(src and $ff)/255;
- //calculate luminance and saturation from rgb
- hls[1]:=maxvalue(clr); //l:=...
- delta:=hls[1]-minvalue(clr);
- if hls[1]=0.0 then hls[2]:=0.0 else hls[2]:=delta/hls[1]; //v:=...
- // calc new rgb from our hls (h from color, l ans s from pixel)
-// if (hls[1]<>0.0) and (hls[2]<>0.0) then // only if colorizing makes sense
- begin
- k:=trunc(hls[0]);
- f:=hls[0]-k;
- p:=hls[1]*(1.0-hls[2]);
- q:=hls[1]*(1.0-(hls[2]*f));
- t:=hls[1]*(1.0-(hls[2]*(1.0-f)));
- case k of
- 0: begin clr[0]:=hls[1]; clr[1]:=t; clr[2]:=p; end;
- 1: begin clr[0]:=q; clr[1]:=hls[1]; clr[2]:=p; end;
- 2: begin clr[0]:=p; clr[1]:=hls[1]; clr[2]:=t; end;
- 3: begin clr[0]:=p; clr[1]:=q; clr[2]:=hls[1]; end;
- 4: begin clr[0]:=t; clr[1]:=p; clr[2]:=hls[1]; end;
- 5: begin clr[0]:=hls[1]; clr[1]:=p; clr[2]:=q; end;
- end;
- // and store new rgb back into the image
- dst[0]:=floor(255*clr[0]);
- dst[1]:=floor(255*clr[1]);
- dst[2]:=floor(255*clr[2]);
- dst[3]:=255;
- end;
-end;
-//returns hue within range [0.0-6.0)
-function col2h(Color:Cardinal):double;
-var
- clr,hls: array[0..2] of double;
- delta: double;
-begin
- clr[0]:=((Color and $ff0000) shr 16)/255;
- clr[1]:=((Color and $ff00) shr 8)/255;
- clr[2]:=(Color and $ff)/255;
- hls[1]:=maxvalue(clr);
- delta:=hls[1]-minvalue(clr);
- if clr[0]=hls[1] then hls[0]:=(clr[1]-clr[2])/delta
- else if clr[1]=hls[1] then hls[0]:=2.0+(clr[2]-clr[0])/delta
- else if clr[2]=hls[1] then hls[0]:=4.0+(clr[0]-clr[1])/delta;
- if hls[0]<0.0 then hls[0]:=hls[0]+6.0;
- if hls[0]=6.0 then hls[0]:=0.0;
- col2h:=hls[0];
-end;
-
-
-function TTextureUnit.LoadTexture(FromRegistry: boolean; Identifier, Format, Typ: PChar; Col: LongWord): TTexture;
-var
- Res: TResourceStream;
- TextureB: TBitmap;
- TextureJ: TJPEGImage;
- {$IFNDEF FPC}
- TexturePNG: TPNGObject;
- {$ENDIF}
-
- TextureAlpha: array of byte;
- AlphaPtr: PByte;
- TransparentColor: TColor;
- PixelColor: TColor;
-
- Position: integer;
- Position2: integer;
- Pix: integer;
- ColInt: real;
- PPix: PByteArray;
- TempA: integer;
- Error: integer;
- SkipX: integer;
- myAlpha: Real;
- myRGBABitmap: array of byte;
- RGBPtr: PByte;
- myHue: Double;
-begin
- {$IFNDEF FPC} // TODO : JB eeeew this is a nasty one...
- // but lazarus implementation scanlines is different :(
- // need to implement as per
- // http://www.lazarus.freepascal.org/index.php?name=PNphpBB2&file=viewtopic&p=18512
- // http://www.lazarus.freepascal.org/index.php?name=PNphpBB2&file=viewtopic&p=10797
- // http://wiki.lazarus.freepascal.org/Developing_with_Graphics
- Log.BenchmarkStart(4);
- Mipmapping := true;
-
- if FromRegistry then begin
- try
- Res := TResourceStream.Create(HInstance, Identifier, Format);
- except
- beep;
- Exit;
- end;
- end;
-
- // filetype "detection"
- if (not FromRegistry) and (FileExists(Identifier)) then begin
- Format:='';
- Format := PAnsichar(UpperCase(RightStr(ExtractFileExt(Identifier),3)));
- end;
-// else Format:='JPG';
-// if not ((Format='BMP')or(Format='JPG')or(Format='PNG')) then Format:='JPG';
-
- if FromRegistry or ((not FromRegistry) and FileExists(Identifier)) then begin
- TextureB := TBitmap.Create;
-
- if Format = 'BMP' then
- begin
- if FromRegistry then
- TextureB.LoadFromStream(Res)
- else
- TextureB.LoadFromFile(Identifier);
- end
- else
- if Format = 'JPG' then
- begin
- TextureJ := TJPEGImage.Create;
-
- if FromRegistry then
- TextureJ.LoadFromStream(Res)
- else
- begin
- if FileExists(Identifier) then
- TextureJ.LoadFromFile(Identifier)
- else
- Exit;
- end;
-
- TextureB.Assign(TextureJ);
- TextureJ.Free;
- end
- else if Format = 'PNG' then
- begin
- {$IFNDEF FPC}
- // TODO : JB - fix this for lazarus..
- TexturePNG := TPNGObject.Create;
- if FromRegistry then
- TexturePNG.LoadFromStream(Res)
- else
- begin
- if FileExists(Identifier) then
- TexturePNG.LoadFromFile(Identifier)
- else
- Exit;
- end;
-
- TextureB.Assign(TexturePNG);
- // transparent png hack start (part 1 of 2)
- if ((Typ = 'Transparent') or (Typ = 'Colorized')) and (TexturePNG.TransparencyMode = ptmPartial) then
- begin
- setlength(TextureAlpha, TextureB.Width*TextureB.Height);
- setlength(MyRGBABitmap,TextureB.Width*TextureB.Height*4);
- if (TexturePNG.Header.ColorType = COLOR_GRAYSCALEALPHA) or
- (TexturePNG.Header.ColorType = COLOR_RGBALPHA) then
- begin
- // i would have preferred english variables here but i use Position because i'm lazy
- for Position := 0 to TextureB.Height - 1 do
- begin
- AlphaPtr := PByte(TexturePNG.AlphaScanline[Position]);
- RGBPtr:=PByte(TexturePNG.Scanline[Position]);
- for Position2 := 0 to TextureB.Width - 1 do
- begin
- TextureAlpha[Position*TextureB.Width+Position2]:= AlphaPtr^;
- MyRGBABitmap[(Position*TextureB.Width+Position2)*4]:= RGBPtr^;
- Inc(RGBPtr);
- MyRGBABitmap[(Position*TextureB.Width+Position2)*4+1]:= RGBPtr^;
- Inc(RGBPtr);
- MyRGBABitmap[(Position*TextureB.Width+Position2)*4+2]:= RGBPtr^;
- Inc(RGBPtr);
- MyRGBABitmap[(Position*TextureB.Width+Position2)*4+3]:= AlphaPtr^;
-// Inc(RGBPtr);
- Inc(AlphaPtr);
- end;
- end;
- end;
- end else
- setlength(TextureAlpha,0); // just no special transparency for unimplemented transparency types (ptmBit)
- // transparent png hack end
- TexturePNG.Free;
- {$ENDIF}
- end;
-
- if FromRegistry then Res.Free;
-
- if (TextureB.Width > 1024) or (TextureB.Height > 1024) then begin // will be fixed in 0.5.1 and dynamically extended to 8192x8192 depending on the driver
- Log.LogError('Image ' + Identifier + ' is too big (' + IntToStr(TextureB.Width) + 'x' + IntToStr(TextureB.Height) + ')');
- Result.TexNum := -1;
- end else begin
-
- glGenTextures(1, ActTex);
- glBindTexture(GL_TEXTURE_2D, ActTex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- if Typ = 'Plain' then begin
- // dimensions
- TexOrigW := TextureB.Width;
- TexOrigH := TextureB.Height;
- TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
- TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
-
- // copy and process pixeldata
- TextureB.PixelFormat := pf24bit;
-{ if (TextureB.PixelFormat = pf8bit) then begin
- for Position := 0 to TexOrigH-1 do begin
- for Position2 := 0 to TexOrigW-1 do begin
- Pix := TextureB.Canvas.Pixels[Position2, Position];
- TextureD24[Position*TexNewW + Position2+1, 1] := Pix;
- TextureD24[Position*TexNewW + Position2+1, 2] := Pix div 256;
- TextureD24[Position*TexNewW + Position2+1, 3] := Pix div (256*256);
- end;
- end;
- end;}
- if (TexOrigW <= Limit) and (TexOrigW <= Limit) then begin
- if (TextureB.PixelFormat = pf24bit) then begin
- for Position := 0 to TexOrigH-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TexOrigW-1 do begin
- TextureD24[Position*TexNewW + Position2+1, 1] := PPix[Position2*3+2];
- TextureD24[Position*TexNewW + Position2+1, 2] := PPix[Position2*3+1];
- TextureD24[Position*TexNewW + Position2+1, 3] := PPix[Position2*3];
- end;
- end;
- end;
- end else begin
- // limit
- TexFitW := 4 * (TexOrigW div 4); // fix for bug in gluScaleImage
- TexFitH := TexOrigH;
- if (TextureB.PixelFormat = pf24bit) then begin
- for Position := 0 to TexOrigH-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TexOrigW-1 do begin
- TextureD24[Position*TexFitW + Position2+1, 1] := PPix[Position2*3+2];
- TextureD24[Position*TexFitW + Position2+1, 2] := PPix[Position2*3+1];
- TextureD24[Position*TexFitW + Position2+1, 3] := PPix[Position2*3];
- end;
- end;
- end;
- gluScaleImage(GL_RGB, TexFitW, TexFitH, GL_UNSIGNED_BYTE, @TextureD24,
- Limit, Limit, GL_UNSIGNED_BYTE, @TextureD24); // takes some time
-
- TexNewW := Limit;
- TexNewH := Limit;
- TexOrigW := Limit;
- TexOrigH := Limit;
- end;
-
- // creating cache mipmap
- if CreateCacheMipmap then begin
- if (TexOrigW <> TexNewW) or (TexOrigH <> TexNewH) then begin
- // texture only uses some of it's space. there's a need for resize to fit full size
- // and get best quality
- TexFitW := 4 * (TexOrigW div 4); // 0.5.0: fix for bug in gluScaleImage
- SkipX := (TexOrigW div 2) mod 2; // 0.5.0: try to center image
-
- TexFitH := TexOrigH;
- for Position := 0 to TexOrigH-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TexOrigW-1 do begin
- TextureD242[Position*TexFitW + Position2+1, 1] := PPix[(Position2+SkipX)*3+2];
- TextureD242[Position*TexFitW + Position2+1, 2] := PPix[(Position2+SkipX)*3+1];
- TextureD242[Position*TexFitW + Position2+1, 3] := PPix[(Position2+SkipX)*3];
- end;
- end;
- gluScaleImage(GL_RGB, TexFitW, TexFitH, GL_UNSIGNED_BYTE, @TextureD242,
- Covers.W, Covers.H, GL_UNSIGNED_BYTE, @CacheMipmap[0]); // takes some time
-
- end else begin
- // texture fits perfectly
- gluScaleImage(GL_RGB, TexOrigW, TexOrigH, GL_UNSIGNED_BYTE, @TextureD24,
- Covers.W, Covers.H, GL_UNSIGNED_BYTE, @CacheMipmap[0]); // takes some time
- end;
- end;
-
- glTexImage2D(GL_TEXTURE_2D, 0, 3, TexNewW, TexNewH, 0, GL_RGB, GL_UNSIGNED_BYTE, @TextureD24);
- if Mipmapping then begin
- Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TexNewW, TexNewH, GL_RGB, GL_UNSIGNED_BYTE, @TextureD24);
- if Error > 0 then beep;
- end
- end;
-
- if Typ = 'Transparent' then begin
- // dimensions
- TexOrigW := TextureB.Width;
- TexOrigH := TextureB.Height;
- TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
- TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
- TextureB.Width := TexNewW;
- TextureB.Height := TexNewH;
-
- // copy and process pixeldata
- for Position := 0 to TexOrigH-1 do begin
- for Position2 := 0 to TexOrigW-1 do begin
- Pix := TextureB.Canvas.Pixels[Position2, Position];
- // ,- part of transparent png hack
- if ((Pix = $fefefe) or (Pix = Col)) and (length(TextureAlpha)=0) then begin //Small fix, that caused artefacts to be drawn (#fe == dec254)
- TextureD32[Position*TexNewW + Position2 + 1, 1] := 0;
- TextureD32[Position*TexNewW + Position2 + 1, 2] := 0;
- TextureD32[Position*TexNewW + Position2 + 1, 3] := 0;
- TextureD32[Position*TexNewW + Position2 + 1, 4] := 0;
- end else if (Format = 'PNG') and (length(TextureAlpha) <> 0) then begin
- myAlpha:=TextureAlpha[Position*TexOrigW+Position2];
- TextureD32[Position*TexNewW + Position2+1, 1] := MyRGBABitmap[(Position*TexOrigW+Position2)*4+2];
- TextureD32[Position*TexNewW + Position2+1, 2] := MyRGBABitmap[(Position*TexOrigW+Position2)*4+1];
- TextureD32[Position*TexNewW + Position2+1, 3] := MyRGBABitmap[(Position*TexOrigW+Position2)*4];
- TextureD32[Position*TexNewW+Position2+1,4]:=MyRGBABitmap[(Position*TexOrigW+Position2)*4+3];
- end else begin
- TextureD32[Position*TexNewW + Position2+1, 1] := (Pix and $ff);
- TextureD32[Position*TexNewW + Position2+1, 2] := ((Pix shr 8) and $ff);
- TextureD32[Position*TexNewW + Position2+1, 3] := ((Pix shr 16) and $ff);
- TextureD32[Position*TexNewW + Position2+1, 4] := 255;
- end;
- end;
- end;
- setlength(TextureAlpha,0);
- setlength(MyRGBABitmap,0);
- glTexImage2D(GL_TEXTURE_2D, 0, 4, TexNewW, TexNewH, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
-{ if Mipmapping then begin
- Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 4, TextureB.Width, TextureB.Height, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
- if Error > 0 then beep;
- end;}
- end;
-
-// The new awesomeness of colorized pngs starts here
-// We're the first who had this feature, so give credit when you copy+paste :P
- if Typ = 'Colorized' then begin
- // dimensions
- TexOrigW := TextureB.Width;
- TexOrigH := TextureB.Height;
- TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
- TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
- TextureB.Width := TexNewW;
- TextureB.Height := TexNewH;
-
- myHue:=col2h(Col);
- // copy and process pixeldata
- for Position := 0 to TexOrigH-1 do begin
- for Position2 := 0 to TexOrigW-1 do begin
- Pix := TextureB.Canvas.Pixels[Position2, Position];
- if (Format = 'PNG') and (length(MyRGBABitmap) <> 0) then
- ColorizeCopy(@MyRGBABitmap[(Position*TexOrigW+Position2)*4],
- @TextureD32[Position*TexNewW + Position2+1, 1],
- myHue)
- else
- ColorizeCopy(Pix,
- @TextureD32[Position*TexNewW + Position2+1, 1],
- myHue);
- end;
- end;
-
- setlength(TextureAlpha,0);
- setlength(MyRGBABitmap,0);
- glTexImage2D(GL_TEXTURE_2D, 0, 4, TexNewW, TexNewH, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
- end;
-// eoa COLORIZE
-
- if Typ = 'Transparent Range' then begin
- // dimensions
- TexOrigW := TextureB.Width;
- TexOrigH := TextureB.Height;
- TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
- TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
- TextureB.Width := TexNewW;
- TextureB.Height := TexNewH;
- // copy and process pixeldata
- for Position := 0 to TexOrigH-1 do begin
- for Position2 := 0 to TexOrigW-1 do begin
- Pix := TextureB.Canvas.Pixels[Position2, Position];
- TextureD32[Position*TexNewW + Position2+1, 1] := Pix;
- TextureD32[Position*TexNewW + Position2+1, 2] := Pix div 256;
- TextureD32[Position*TexNewW + Position2+1, 3] := Pix div (256*256);
- TextureD32[Position*TexNewW + Position2+1, 4] := 256 - Pix div 256;
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 4, TexNewW, TexNewH, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
-{ if Mipmapping then begin
- Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 4, TextureB.Width, TextureB.Height, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
- if Error > 0 then beep;
- end;}
- end;
-
- if Typ = 'Font' then begin
- TextureB.PixelFormat := pf24bit;
- for Position := 0 to TextureB.Height-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TextureB.Width-1 do begin
- Pix := PPix[Position2 * 3];
- TextureD16[Position*TextureB.Width + Position2 + 1, 1] := 255;
- TextureD16[Position*TextureB.Width + Position2 + 1, 2] := Pix;
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 2, TextureB.Width, TextureB.Height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
-
- if Mipmapping then glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- if Mipmapping then begin
- Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 2, TextureB.Width, TextureB.Height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
- if Error > 0 then beep;
- end;
- end;
-
- if Typ = 'Font Outline' then begin
- TextureB.PixelFormat := pf24bit;
- for Position := 0 to TextureB.Height-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TextureB.Width-1 do begin
- Pix := PPix[Position2 * 3];
-
- Col := Pix;
- if Col < 127 then Col := 127;
-
- TempA := Pix;
- if TempA >= 95 then TempA := 255;
- if TempA >= 31 then TempA := 255;
- if Pix < 95 then TempA := (Pix * 256) div 96;
-
-
- TextureD16[Position*TextureB.Width + Position2 + 1, 1] := Col;
- TextureD16[Position*TextureB.Width + Position2 + 1, 2] := TempA;
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 2, TextureB.Width, TextureB.Height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
-
- if Mipmapping then glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- if Mipmapping then begin
- Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 2, TextureB.Width, TextureB.Height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
- if Error > 0 then beep;
- end;
- end;
-
- if Typ = 'Font Outline 2' then begin
- TextureB.PixelFormat := pf24bit;
- for Position := 0 to TextureB.Height-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TextureB.Width-1 do begin
- Pix := PPix[Position2 * 3];
-
- Col := Pix;
- if Col < 31 then Col := 31;
-
- TempA := Pix;
- if TempA >= 31 then TempA := 255;
- if Pix < 31 then TempA := Pix * (256 div 32);
-
- TextureD16[Position*TextureB.Width + Position2 + 1, 1] := Col;
- TextureD16[Position*TextureB.Width + Position2 + 1, 2] := TempA;
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 2, TextureB.Width, TextureB.Height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
-
- if Mipmapping then glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- if Mipmapping then begin
- Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 2, TextureB.Width, TextureB.Height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
- if Error > 0 then beep;
- end;
- end;
-
- if Typ = 'Font Black' then begin
- // normalnie 0,125s bez niczego 0,015s - 0,030s z pix 0,125s <-- ???
- // dimensions
- TextureB.PixelFormat := pf24bit;
- TexOrigW := TextureB.Width;
- TexOrigH := TextureB.Height;
- TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
- TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
- TextureB.Width := TexNewW;
- TextureB.Height := TexNewH;
- // copy and process pixeldata
- for Position := 0 to TextureB.Height-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TextureB.Width-1 do begin
- Pix := PPix[Position2*3];
- TextureD32[Position*TextureB.Width + Position2 + 1, 1] := 255;
- TextureD32[Position*TextureB.Width + Position2 + 1, 2] := 255;
- TextureD32[Position*TextureB.Width + Position2 + 1, 3] := 255;
- TextureD32[Position*TextureB.Width + Position2 + 1, 4] := 255 - (Pix mod 256);
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
- end;
-
- if Typ = 'Alpha Black Colored' then begin
- TextureB.PixelFormat := pf24bit;
- TexOrigW := TextureB.Width;
- TexOrigH := TextureB.Height;
- TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
- TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
- TextureB.Width := TexNewW;
- TextureB.Height := TexNewH;
- // copy and process pixeldata
- for Position := 0 to TextureB.Height-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TextureB.Width-1 do begin
- Pix := PPix[Position2*3];
- TextureD32[Position*TextureB.Width + Position2 + 1, 1] := (Col div $10000) and $FF;
- TextureD32[Position*TextureB.Width + Position2 + 1, 2] := (Col div $100) and $FF;
- TextureD32[Position*TextureB.Width + Position2 + 1, 3] := Col and $FF;
- TextureD32[Position*TextureB.Width + Position2 + 1, 4] := 255 - (Pix mod 256);
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
- end;
-
- if Typ = 'Font Gray' then begin
- // dimensions
- TexOrigW := TextureB.Width;
- TexOrigH := TextureB.Height;
- TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
- TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
- TextureB.Width := TexNewW;
- TextureB.Height := TexNewH;
- // copy and process pixeldata
- for Position := 0 to TextureB.Height-1 do begin
- for Position2 := 0 to TextureB.Width-1 do begin
- Pix := TextureB.Canvas.Pixels[Position2, Position];
- TextureD32[Position*TextureB.Width + Position2 + 1, 1] := 127;
- TextureD32[Position*TextureB.Width + Position2 + 1, 2] := 127;
- TextureD32[Position*TextureB.Width + Position2 + 1, 3] := 127;
- TextureD32[Position*TextureB.Width + Position2 + 1, 4] := 255 - (Pix mod 256);
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
-{ if Mipmapping then begin
- Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 4, TextureB.Width, TextureB.Height, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
- if Error > 0 then beep;
- end;}
- end;
-
- if Typ = 'Arrow' then begin
- TextureB.PixelFormat := pf24bit;
- for Position := 0 to TextureB.Height-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TextureB.Width-1 do begin
- Pix := PPix[Position2 * 3];
-
- // transparency
- if Pix >= 127 then TempA := 255;
- if Pix < 127 then TempA := Pix * 2;
-
- // ColInt = color intensity
- if Pix < 127 then ColInt := 1;
- if Pix >= 127 then ColInt := 2 - Pix / 128;
- //0.75, 0.6, 0.25
-
- TextureD32[Position*TextureB.Width + Position2 + 1, 1] := Round(ColInt * 0.75 * 255 + (1 - ColInt) * 255);
- TextureD32[Position*TextureB.Width + Position2 + 1, 2] := Round(ColInt * 0.6 * 255 + (1 - ColInt) * 255);
- TextureD32[Position*TextureB.Width + Position2 + 1, 3] := Round(ColInt * 0.25 * 255 + (1 - ColInt) * 255);
- TextureD32[Position*TextureB.Width + Position2 + 1, 4] := TempA;
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
-
- if Mipmapping then glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- if Mipmapping then begin
- Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 4, TextureB.Width, TextureB.Height, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
- if Error > 0 then beep;
- end;
- end;
-
- if Typ = 'Note Plain' then begin
- for Position := 0 to TextureB.Height-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TextureB.Width-1 do begin
-
-
-
- // Skin Patch
- // 0-191= Fade Black to Col, 192= Col, 193-254 Fade Col to White, 255= White
- case PPix[Position2*3] of
- 0..191: Pix := $10000 * ((((Col div $10000) and $FF) * PPix[Position2*3]) div $Bf) + $100 * ((((Col div $100) and $FF) * PPix[Position2*3]) div $Bf) + (((Col and $FF) * PPix[Position2*3]) div $Bf);
- 192: Pix := Col;
- 193..254: Pix := Col + ($10000 * ((($FF - ((Col div $10000) and $FF)) * ((PPix[Position2*3] - $C0) * 4) ) div $FF) + $100 * ((($FF - ((Col div $100) and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF) + ((($FF - (Col and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF));
- 255: Pix := $FFFFFF;
- end;
-// 0.5.0. Original
-// case PPix[Position2*3] of
-// 128: Pix := $10000 * ((Col div $10000) div 2) + $100 * (((Col div $100) and $FF) div 2) + (Col and $FF) div 2;
-// 192: Pix := Col;
-// 255: Pix := $FFFFFF;
-// end;
-
-
-
-
-
- TextureD24[Position*TextureB.Width + Position2 + 1, 1] := Pix div $10000;
- TextureD24[Position*TextureB.Width + Position2 + 1, 2] := (Pix div $100) and $FF;
- TextureD24[Position*TextureB.Width + Position2 + 1, 3] := Pix and $FF;
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureB.Width, TextureB.Height, 0, GL_RGB, GL_UNSIGNED_BYTE, @TextureD24);
- end;
-
- if Typ = 'Note Transparent' then begin
- for Position := 0 to TextureB.Height-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TextureB.Width-1 do begin
- TempA := 255;
-
-
-
- //Skin Patch
- // 0= Transparent, 1-191= Fade Black to Col, 192= Col, 193-254 Fade Col to White, 255= White
- case PPix[Position2*3] of
- 0: TempA := 0;
- 1..191: Pix := $10000 * ((((Col div $10000) and $FF) * PPix[Position2*3]) div $Bf) + $100 * ((((Col div $100) and $FF) * PPix[Position2*3]) div $Bf) + (((Col and $FF) * PPix[Position2*3]) div $Bf);
- 192: Pix := Col;
- 193..254: Pix := Col + ($10000 * ((($FF - ((Col div $10000) and $FF)) * ((PPix[Position2*3] - $C0) * 4) ) div $FF) + $100 * ((($FF - ((Col div $100) and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF) + ((($FF - (Col and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF));
- 255: Pix := $FFFFFF;
- end;
-// 0.5.0 Original
-// case PPix[Position2*3] of
-// 0: TempA := 0;
-// 128: Pix := $10000 * ((Col div $10000) div 2) + $100 * (((Col div $100) and $FF) div 2) + (Col and $FF) div 2;
-// 192: Pix := Col;
-// 255: Pix := $FFFFFF;
-// end;
-
-
-
-
- TextureD32[Position*TextureB.Width + Position2 + 1, 1] := Pix div $10000;
- TextureD32[Position*TextureB.Width + Position2 + 1, 2] := (Pix div $100) and $FF;
- TextureD32[Position*TextureB.Width + Position2 + 1, 3] := Pix and $FF;
- TextureD32[Position*TextureB.Width + Position2 + 1, 4] := TempA;
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
- end;
-
- TextureB.Free;
- Result.X := 0;
- Result.Y := 0;
- Result.W := 0;
- Result.H := 0;
- Result.ScaleW := 1;
- Result.ScaleH := 1;
- Result.Rot := 0;
- Result.TexNum := ActTex;
- Result.TexW := TexOrigW / TexNewW;
- Result.TexH := TexOrigH / TexNewH;
-
- Result.Int := 1;
- Result.ColR := 1;
- Result.ColG := 1;
- Result.ColB := 1;
- Result.Alpha := 1;
-
- // 0.4.2 new test - default use whole texure, taking TexW and TexH as const and changing these
- Result.TexX1 := 0;
- Result.TexY1 := 0;
- Result.TexX2 := 1;
- Result.TexY2 := 1;
-
- // 0.5.0
- Result.Name := Identifier;
-
- end;
-
- Log.BenchmarkEnd(4);
- if Log.BenchmarkTimeLength[4] >= 1 then
- Log.LogBenchmark('**********> Texture Load Time Warning - ' + Format + '/' + Identifier + '/' + Typ, 4);
-
- end; // logerror
- {$ENDIF}
-end;
-
-{procedure ResizeTexture(s: pbytearray; d: pbytearray);
-var
- Position: integer;
- Position2: integer;
-begin
- for Position := 0 to TexNewH*4-1 do
- for Position2 := 0 to TexNewW-1 do
- d[Position*TexNewW + Position2] := 0;
-
- for Position := 0 to TexOrigH-1 do begin
- for Position2 := 0 to TexOrigW-1 do begin
- d[(Position*TexNewW + Position2)*4] := Paleta[s[Position*TexOrigW + Position2], 1];
- d[(Position*TexNewW + Position2)*4+1] := Paleta[s[Position*TexOrigW + Position2], 2];
- d[(Position*TexNewW + Position2)*4+2] := Paleta[s[Position*TexOrigW + Position2], 3];
- d[(Position*TexNewW + Position2)*4+3] := Paleta[s[Position*TexOrigW + Position2], 4];
- end;
- end;
-end;}
-
-{procedure SetTexture(p: pointer);
-begin
- glGenTextures(1, Tekstur);
- glBindTexture(GL_TEXTURE_2D, Tekstur);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
- glTexImage2D(GL_TEXTURE_2D, 0, 4, TexNewW, TexNewH, 0, GL_RGBA, GL_UNSIGNED_BYTE, p);
-end;}
-
-function TTextureUnit.LoadTexture(Identifier, Format, Typ: PChar; Col: LongWord): TTexture;
-begin
- Result := LoadTexture(false, Identifier, Format, Typ, Col);
-// Result := LoadTexture(SkinReg, Identifier, Format, Typ, Col); // default to SkinReg
-
-end;
-
-function TTextureUnit.LoadTexture(Identifier: string): TTexture;
-begin
- Result := LoadTexture(false, pchar(Identifier), 'JPG', 'Plain', 0);
-end;
-
-function TTextureUnit.CreateTexture(var Data: array of byte; Name: string; W, H: word; Bits: byte): TTexture;
-var
- Position: integer;
- Position2: integer;
- Pix: integer;
- ColInt: real;
- PPix: PByteArray;
- TempA: integer;
- Error: integer;
-begin
- Mipmapping := false;
-
- glGenTextures(1, ActTex); // ActText = new texture number
- glBindTexture(GL_TEXTURE_2D, ActTex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glTexImage2D(GL_TEXTURE_2D, 0, 3, W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, @Data[0]);
- if Mipmapping then begin
- Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 3, W, H, GL_RGB, GL_UNSIGNED_BYTE, @Data[0]);
- if Error > 0 then beep;
- end;
-
- Result.X := 0;
- Result.Y := 0;
- Result.W := 0;
- Result.H := 0;
- Result.ScaleW := 1;
- Result.ScaleH := 1;
- Result.Rot := 0;
- Result.TexNum := ActTex;
- Result.TexW := 1;
- Result.TexH := 1;
-
- Result.Int := 1;
- Result.ColR := 1;
- Result.ColG := 1;
- Result.ColB := 1;
- Result.Alpha := 1;
-
- // 0.4.2 new test - default use whole texure, taking TexW and TexH as const and changing these
- Result.TexX1 := 0;
- Result.TexY1 := 0;
- Result.TexX2 := 1;
- Result.TexY2 := 1;
-
- // 0.5.0
- Result.Name := Name;
-end;
-
-procedure TTextureUnit.UnloadTexture(Name: string; FromCache: boolean);
-var
- T: integer;
- TexNum: GLuint;
-begin
- T := FindTexture(Name);
-
- if not FromCache then begin
- TexNum := TextureDatabase.Texture[T].Texture.TexNum;
- if TexNum >= 0 then begin
- glDeleteTextures(1, @TexNum);
- TextureDatabase.Texture[T].Texture.TexNum := -1;
-// Log.LogError('Unload texture no '+IntToStr(TexNum));
- end;
- end else begin
- TexNum := TextureDatabase.Texture[T].TextureCache.TexNum;
- if TexNum >= 0 then begin
- glDeleteTextures(1, @TexNum);
- TextureDatabase.Texture[T].TextureCache.TexNum := -1;
-// Log.LogError('Unload texture cache no '+IntToStr(TexNum));
- end;
- end;
-end;
-
-end.
+unit UTexture;
+
+// Plain (alpha = 1)
+// Transparent
+// Transparent Range
+// Font (white is drawn, black is transparent)
+// Font Outline (Font with darker outline)
+// Font Outline 2 (Font with darker outline)
+// Font Black (black is drawn, white is transparent)
+// Font Gray (gray is drawn, white is transparent)
+// Arrow (for arrows, white is white, gray has color, black is transparent);
+
+interface
+
+{$I switches.inc}
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+{$ENDIF}
+
+uses OpenGL12,
+ {$IFDEF win32}
+ windows,
+ {$ENDIF}
+ Math,
+ Classes,
+ SysUtils,
+ {$IFDEF FPC}
+ ulazjpeg,
+ {$ELSE}
+ JPEG,
+ PNGImage,
+ {$ENDIF}
+ Graphics,
+ UCommon,
+ UThemes;
+
+
+ {$IFDEF Win32}
+ procedure glGenTextures(n: GLsizei; var textures: GLuint); stdcall; external opengl32;
+
+ {$ELSE}
+ {$ifdef darwin}
+ const opengl32 = '/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib';
+ {$ELSE}
+ const opengl32 = 'libGL.so' ; // YES Capital GL
+ {$ENDIF}
+
+ procedure glGenTextures(n: GLsizei; var textures: GLuint); stdcall; external opengl32;
+ {$ENDIF}
+
+type
+ TTexture = record
+ TexNum: integer;
+ X: real;
+ Y: real;
+ Z: real; // new
+ W: real;
+ H: real;
+ ScaleW: real; // for dynamic scalling while leaving width constant
+ ScaleH: real; // for dynamic scalling while leaving height constant
+ Rot: real; // 0 - 2*pi
+ Int: real; // intensity
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ TexW: real; // used?
+ TexH: real; // used?
+ TexX1: real;
+ TexY1: real;
+ TexX2: real;
+ TexY2: real;
+ Alpha: real;
+ Name: string; // 0.5.0: experimental for handling cache images. maybe it's useful for dynamic skins
+ end;
+
+ TTextureEntry = record
+ Name: string;
+ Typ: string;
+
+ // we use normal TTexture, it's easier to implement and if needed - we copy ready data
+ Texture: TTexture;
+ TextureCache: TTexture; // 0.5.0
+ end;
+
+ TTextureDatabase = record
+ Texture: array of TTextureEntry;
+ end;
+
+ TTextureUnit = class
+ Limit: integer;
+ CreateCacheMipmap: boolean;
+
+// function GetNumberFor
+ function GetTexture(Name, Typ: string): TTexture; overload;
+ function GetTexture(Name, Typ: string; FromCache: boolean): TTexture; overload;
+ function FindTexture(Name: string): integer;
+ function LoadTexture(FromRegistry: boolean; Identifier, Format, Typ: PChar; Col: LongWord): TTexture; overload;
+ function LoadTexture(Identifier, Format, Typ: PChar; Col: LongWord): TTexture; overload;
+ function LoadTexture(Identifier: string): TTexture; overload;
+ function CreateTexture(var Data: array of byte; Name: string; W, H: word; Bits: byte): TTexture;
+ procedure UnloadTexture(Name: string; FromCache: boolean);
+ end;
+
+var
+ lasthue: double;
+ Texture: TTextureUnit;
+ TextureDatabase: TTextureDatabase;
+
+ PrintScreenData: array[0..1024*768-1] of longword;
+
+ ActTex: GLuint;//integer;
+
+ TexOrigW: integer;
+ TexOrigH: integer;
+ TexNewW: integer;
+ TexNewH: integer;
+
+ TexFitW: integer;
+ TexFitH: integer; // new for limit
+
+ TextureD8: array[1..1024*1024] of byte; // 1MB
+ TextureD16: array[1..1024*1024, 1..2] of byte; // luminance/alpha tex (2MB)
+ TextureD24: array[1..1024*1024, 1..3] of byte; // normal 24-bit tex (3MB)
+ TextureD242: array[1..512*512, 1..3] of byte; // normal 24-bit tex (0,75MB)
+ TextureD32: array[1..1024*1024, 1..4] of byte; // transparent 32-bit tex (4MB)
+ // total 40MB at 2048*2048
+ // total 10MB at 1024*1024
+
+ Mipmapping: Boolean;
+
+ CacheMipmap: array[0..256*256*3-1] of byte; // 3KB
+
+
+implementation
+uses ULog, DateUtils, UCovers, StrUtils;
+
+function TTextureUnit.GetTexture(Name, Typ: string): TTexture;
+begin
+ Result := GetTexture(Name, Typ, true);
+end;
+
+function TTextureUnit.GetTexture(Name, Typ: string; FromCache: boolean): TTexture;
+var
+ T: integer; // texture
+ C: integer; // cover
+ Data: array of byte;
+begin
+ // find texture entry
+ T := FindTexture(Name);
+
+ if T = -1 then begin
+ // create texture entry
+ T := Length(TextureDatabase.Texture);
+ SetLength(TextureDatabase.Texture, T+1);
+ TextureDatabase.Texture[T].Name := Name;
+ TextureDatabase.Texture[T].Typ := Typ;
+
+ // inform database that no textures have been loaded into memory
+ TextureDatabase.Texture[T].Texture.TexNum := -1;
+ TextureDatabase.Texture[T].TextureCache.TexNum := -1;
+ end;
+
+ // use preloaded texture
+ if (not FromCache) or (FromCache and not Covers.CoverExists(Name)) then begin
+ // use full texture
+ if TextureDatabase.Texture[T].Texture.TexNum = -1 then begin
+ // load texture
+ TextureDatabase.Texture[T].Texture := LoadTexture(false, pchar(Name), 'JPG', pchar(Typ), $0);
+ end;
+
+ // use texture
+ Result := TextureDatabase.Texture[T].Texture;
+
+ end;
+
+ if FromCache and Covers.CoverExists(Name) then begin
+ // use cache texture
+ C := Covers.CoverNumber(Name);
+
+ if TextureDatabase.Texture[T].TextureCache.TexNum = -1 then begin
+ // load texture
+ Covers.PrepareData(Name);
+ TextureDatabase.Texture[T].TextureCache := CreateTexture(Covers.Data, Name, Covers.Cover[C].W, Covers.Cover[C].H, 24);
+ end;
+
+ // use texture
+ Result := TextureDatabase.Texture[T].TextureCache;
+ end;
+end;
+
+function TTextureUnit.FindTexture(Name: string): integer;
+var
+ T: integer; // texture
+begin
+ Result := -1;
+ for T := 0 to high(TextureDatabase.Texture) do
+ if TextureDatabase.Texture[T].Name = Name then
+ Result := T;
+end;
+
+// expects: src, dst: pointers to r,g,b,a
+// hue: new hue within range [0.0-6.0)
+procedure ColorizeCopy(Src, Dst: PByteArray; hue: Double); overload;
+var
+ i,j,k: Cardinal;
+ clr, hls: array[0..2] of Double;
+ delta, f, p, q, t: Double;
+begin
+ hls[0]:=hue;
+
+ clr[0] := src[0]/255;
+ clr[1] := src[1]/255;
+ clr[2] := src[2]/255;
+
+ //calculate luminance and saturation from rgb
+ hls[1] := maxvalue(clr); //l:=...
+ delta := hls[1] - minvalue(clr);
+
+ if hls[1] = 0.0 then
+ hls[2] := 0.0
+ else
+ hls[2] := delta/hls[1]; //v:=...
+
+ // calc new rgb from our hls (h from color, l ans s from pixel)
+// if (hls[1]<>0.0) and (hls[2]<>0.0) then // only if colorizing makes sense
+ begin
+ k:=trunc(hls[0]);
+ f:=hls[0]-k;
+ p:=hls[1]*(1.0-hls[2]);
+ q:=hls[1]*(1.0-(hls[2]*f));
+ t:=hls[1]*(1.0-(hls[2]*(1.0-f)));
+ case k of
+ 0: begin clr[0]:=hls[1]; clr[1]:=t; clr[2]:=p; end;
+ 1: begin clr[0]:=q; clr[1]:=hls[1]; clr[2]:=p; end;
+ 2: begin clr[0]:=p; clr[1]:=hls[1]; clr[2]:=t; end;
+ 3: begin clr[0]:=p; clr[1]:=q; clr[2]:=hls[1]; end;
+ 4: begin clr[0]:=t; clr[1]:=p; clr[2]:=hls[1]; end;
+ 5: begin clr[0]:=hls[1]; clr[1]:=p; clr[2]:=q; end;
+ end;
+ // and store new rgb back into the image
+ dst[0]:=floor(255*clr[0]);
+ dst[1]:=floor(255*clr[1]);
+ dst[2]:=floor(255*clr[2]);
+ dst[3]:=src[3];
+ end;
+end;
+
+// expects: src: $rrggbb
+// dst: pointer to r,g,b,a
+// hue: new hue within range [0.0-6.0)
+procedure ColorizeCopy(Src: Cardinal; Dst: PByteArray; hue: Double); overload;
+var
+ i,j,k: Cardinal;
+ clr, hls: array[0..2] of Double;
+ delta, f, p, q, t: Double;
+begin
+ hls[0]:=hue;
+
+ clr[0]:=((src shr 16) and $ff)/255;
+ clr[1]:=((src shr 8) and $ff)/255;
+ clr[2]:=(src and $ff)/255;
+ //calculate luminance and saturation from rgb
+ hls[1]:=maxvalue(clr); //l:=...
+ delta:=hls[1]-minvalue(clr);
+ if hls[1]=0.0 then hls[2]:=0.0 else hls[2]:=delta/hls[1]; //v:=...
+ // calc new rgb from our hls (h from color, l ans s from pixel)
+// if (hls[1]<>0.0) and (hls[2]<>0.0) then // only if colorizing makes sense
+ begin
+ k:=trunc(hls[0]);
+ f:=hls[0]-k;
+ p:=hls[1]*(1.0-hls[2]);
+ q:=hls[1]*(1.0-(hls[2]*f));
+ t:=hls[1]*(1.0-(hls[2]*(1.0-f)));
+ case k of
+ 0: begin clr[0]:=hls[1]; clr[1]:=t; clr[2]:=p; end;
+ 1: begin clr[0]:=q; clr[1]:=hls[1]; clr[2]:=p; end;
+ 2: begin clr[0]:=p; clr[1]:=hls[1]; clr[2]:=t; end;
+ 3: begin clr[0]:=p; clr[1]:=q; clr[2]:=hls[1]; end;
+ 4: begin clr[0]:=t; clr[1]:=p; clr[2]:=hls[1]; end;
+ 5: begin clr[0]:=hls[1]; clr[1]:=p; clr[2]:=q; end;
+ end;
+ // and store new rgb back into the image
+ dst[0]:=floor(255*clr[0]);
+ dst[1]:=floor(255*clr[1]);
+ dst[2]:=floor(255*clr[2]);
+ dst[3]:=255;
+ end;
+end;
+//returns hue within range [0.0-6.0)
+function col2h(Color:Cardinal):double;
+var
+ clr,hls: array[0..2] of double;
+ delta: double;
+begin
+ clr[0]:=((Color and $ff0000) shr 16)/255;
+ clr[1]:=((Color and $ff00) shr 8)/255;
+ clr[2]:=(Color and $ff)/255;
+ hls[1]:=maxvalue(clr);
+ delta:=hls[1]-minvalue(clr);
+ if clr[0]=hls[1] then hls[0]:=(clr[1]-clr[2])/delta
+ else if clr[1]=hls[1] then hls[0]:=2.0+(clr[2]-clr[0])/delta
+ else if clr[2]=hls[1] then hls[0]:=4.0+(clr[0]-clr[1])/delta;
+ if hls[0]<0.0 then hls[0]:=hls[0]+6.0;
+ if hls[0]=6.0 then hls[0]:=0.0;
+ col2h:=hls[0];
+end;
+
+
+function TTextureUnit.LoadTexture(FromRegistry: boolean; Identifier, Format, Typ: PChar; Col: LongWord): TTexture;
+var
+ Res: TResourceStream;
+ TextureB: TBitmap;
+ TextureJ: TJPEGImage;
+ {$IFNDEF FPC}
+ TexturePNG: TPNGObject;
+ {$ENDIF}
+
+ TextureAlpha: array of byte;
+ AlphaPtr: PByte;
+ TransparentColor: TColor;
+ PixelColor: TColor;
+
+ Position: integer;
+ Position2: integer;
+ Pix: integer;
+ ColInt: real;
+ PPix: PByteArray;
+ TempA: integer;
+ Error: integer;
+ SkipX: integer;
+ myAlpha: Real;
+ myRGBABitmap: array of byte;
+ RGBPtr: PByte;
+ myHue: Double;
+begin
+ {$IFNDEF FPC} // TODO : JB_lazarus eeeew this is a nasty one...
+ // but lazarus implementation scanlines is different :(
+ // need to implement as per
+ // http://www.lazarus.freepascal.org/index.php?name=PNphpBB2&file=viewtopic&p=18512
+ // http://www.lazarus.freepascal.org/index.php?name=PNphpBB2&file=viewtopic&p=10797
+ // http://wiki.lazarus.freepascal.org/Developing_with_Graphics
+ Log.BenchmarkStart(4);
+ Mipmapping := true;
+
+ if FromRegistry then begin
+ try
+ Res := TResourceStream.Create(HInstance, Identifier, Format);
+ except
+ beep;
+ Exit;
+ end;
+ end;
+
+ // filetype "detection"
+ if (not FromRegistry) and (FileExists(Identifier)) then begin
+ Format:='';
+ Format := PAnsichar(UpperCase(RightStr(ExtractFileExt(Identifier),3)));
+ end;
+// else Format:='JPG';
+// if not ((Format='BMP')or(Format='JPG')or(Format='PNG')) then Format:='JPG';
+
+ if FromRegistry or ((not FromRegistry) and FileExists(Identifier)) then begin
+ TextureB := TBitmap.Create;
+
+ if Format = 'BMP' then
+ begin
+ if FromRegistry then
+ TextureB.LoadFromStream(Res)
+ else
+ TextureB.LoadFromFile(Identifier);
+ end
+ else
+ if Format = 'JPG' then
+ begin
+ TextureJ := TJPEGImage.Create;
+
+ if FromRegistry then
+ TextureJ.LoadFromStream(Res)
+ else
+ begin
+ if FileExists(Identifier) then
+ TextureJ.LoadFromFile(Identifier)
+ else
+ Exit;
+ end;
+
+ TextureB.Assign(TextureJ);
+ TextureJ.Free;
+ end
+ else if Format = 'PNG' then
+ begin
+ {$IFNDEF FPC}
+ // TODO : JB_lazarus - fix this for lazarus..
+ TexturePNG := TPNGObject.Create;
+ if FromRegistry then
+ TexturePNG.LoadFromStream(Res)
+ else
+ begin
+ if FileExists(Identifier) then
+ TexturePNG.LoadFromFile(Identifier)
+ else
+ Exit;
+ end;
+
+ TextureB.Assign(TexturePNG);
+ // transparent png hack start (part 1 of 2)
+ if ((Typ = 'Transparent') or (Typ = 'Colorized')) and (TexturePNG.TransparencyMode = ptmPartial) then
+ begin
+ setlength(TextureAlpha, TextureB.Width*TextureB.Height);
+ setlength(MyRGBABitmap,TextureB.Width*TextureB.Height*4);
+ if (TexturePNG.Header.ColorType = COLOR_GRAYSCALEALPHA) or
+ (TexturePNG.Header.ColorType = COLOR_RGBALPHA) then
+ begin
+ // i would have preferred english variables here but i use Position because i'm lazy
+ for Position := 0 to TextureB.Height - 1 do
+ begin
+ AlphaPtr := PByte(TexturePNG.AlphaScanline[Position]);
+ RGBPtr:=PByte(TexturePNG.Scanline[Position]);
+ for Position2 := 0 to TextureB.Width - 1 do
+ begin
+ TextureAlpha[Position*TextureB.Width+Position2]:= AlphaPtr^;
+ MyRGBABitmap[(Position*TextureB.Width+Position2)*4]:= RGBPtr^;
+ Inc(RGBPtr);
+ MyRGBABitmap[(Position*TextureB.Width+Position2)*4+1]:= RGBPtr^;
+ Inc(RGBPtr);
+ MyRGBABitmap[(Position*TextureB.Width+Position2)*4+2]:= RGBPtr^;
+ Inc(RGBPtr);
+ MyRGBABitmap[(Position*TextureB.Width+Position2)*4+3]:= AlphaPtr^;
+// Inc(RGBPtr);
+ Inc(AlphaPtr);
+ end;
+ end;
+ end;
+ end else
+ setlength(TextureAlpha,0); // just no special transparency for unimplemented transparency types (ptmBit)
+ // transparent png hack end
+ TexturePNG.Free;
+ {$ENDIF}
+ end;
+
+ if FromRegistry then Res.Free;
+
+ if (TextureB.Width > 1024) or (TextureB.Height > 1024) then begin // will be fixed in 0.5.1 and dynamically extended to 8192x8192 depending on the driver
+ Log.LogError('Image ' + Identifier + ' is too big (' + IntToStr(TextureB.Width) + 'x' + IntToStr(TextureB.Height) + ')');
+ Result.TexNum := -1;
+ end else begin
+
+ glGenTextures(1, ActTex);
+ glBindTexture(GL_TEXTURE_2D, ActTex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ if Typ = 'Plain' then begin
+ // dimensions
+ TexOrigW := TextureB.Width;
+ TexOrigH := TextureB.Height;
+ TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
+ TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
+
+ // copy and process pixeldata
+ TextureB.PixelFormat := pf24bit;
+{ if (TextureB.PixelFormat = pf8bit) then begin
+ for Position := 0 to TexOrigH-1 do begin
+ for Position2 := 0 to TexOrigW-1 do begin
+ Pix := TextureB.Canvas.Pixels[Position2, Position];
+ TextureD24[Position*TexNewW + Position2+1, 1] := Pix;
+ TextureD24[Position*TexNewW + Position2+1, 2] := Pix div 256;
+ TextureD24[Position*TexNewW + Position2+1, 3] := Pix div (256*256);
+ end;
+ end;
+ end;}
+ if (TexOrigW <= Limit) and (TexOrigW <= Limit) then begin
+ if (TextureB.PixelFormat = pf24bit) then begin
+ for Position := 0 to TexOrigH-1 do begin
+ PPix := TextureB.ScanLine[Position];
+ for Position2 := 0 to TexOrigW-1 do begin
+ TextureD24[Position*TexNewW + Position2+1, 1] := PPix[Position2*3+2];
+ TextureD24[Position*TexNewW + Position2+1, 2] := PPix[Position2*3+1];
+ TextureD24[Position*TexNewW + Position2+1, 3] := PPix[Position2*3];
+ end;
+ end;
+ end;
+ end else begin
+ // limit
+ TexFitW := 4 * (TexOrigW div 4); // fix for bug in gluScaleImage
+ TexFitH := TexOrigH;
+ if (TextureB.PixelFormat = pf24bit) then begin
+ for Position := 0 to TexOrigH-1 do begin
+ PPix := TextureB.ScanLine[Position];
+ for Position2 := 0 to TexOrigW-1 do begin
+ TextureD24[Position*TexFitW + Position2+1, 1] := PPix[Position2*3+2];
+ TextureD24[Position*TexFitW + Position2+1, 2] := PPix[Position2*3+1];
+ TextureD24[Position*TexFitW + Position2+1, 3] := PPix[Position2*3];
+ end;
+ end;
+ end;
+ gluScaleImage(GL_RGB, TexFitW, TexFitH, GL_UNSIGNED_BYTE, @TextureD24,
+ Limit, Limit, GL_UNSIGNED_BYTE, @TextureD24); // takes some time
+
+ TexNewW := Limit;
+ TexNewH := Limit;
+ TexOrigW := Limit;
+ TexOrigH := Limit;
+ end;
+
+ // creating cache mipmap
+ if CreateCacheMipmap then begin
+ if (TexOrigW <> TexNewW) or (TexOrigH <> TexNewH) then begin
+ // texture only uses some of it's space. there's a need for resize to fit full size
+ // and get best quality
+ TexFitW := 4 * (TexOrigW div 4); // 0.5.0: fix for bug in gluScaleImage
+ SkipX := (TexOrigW div 2) mod 2; // 0.5.0: try to center image
+
+ TexFitH := TexOrigH;
+ for Position := 0 to TexOrigH-1 do begin
+ PPix := TextureB.ScanLine[Position];
+ for Position2 := 0 to TexOrigW-1 do begin
+ TextureD242[Position*TexFitW + Position2+1, 1] := PPix[(Position2+SkipX)*3+2];
+ TextureD242[Position*TexFitW + Position2+1, 2] := PPix[(Position2+SkipX)*3+1];
+ TextureD242[Position*TexFitW + Position2+1, 3] := PPix[(Position2+SkipX)*3];
+ end;
+ end;
+ gluScaleImage(GL_RGB, TexFitW, TexFitH, GL_UNSIGNED_BYTE, @TextureD242,
+ Covers.W, Covers.H, GL_UNSIGNED_BYTE, @CacheMipmap[0]); // takes some time
+
+ end else begin
+ // texture fits perfectly
+ gluScaleImage(GL_RGB, TexOrigW, TexOrigH, GL_UNSIGNED_BYTE, @TextureD24,
+ Covers.W, Covers.H, GL_UNSIGNED_BYTE, @CacheMipmap[0]); // takes some time
+ end;
+ end;
+
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, TexNewW, TexNewH, 0, GL_RGB, GL_UNSIGNED_BYTE, @TextureD24);
+ if Mipmapping then begin
+ Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TexNewW, TexNewH, GL_RGB, GL_UNSIGNED_BYTE, @TextureD24);
+ if Error > 0 then beep;
+ end
+ end;
+
+ if Typ = 'Transparent' then begin
+ // dimensions
+ TexOrigW := TextureB.Width;
+ TexOrigH := TextureB.Height;
+ TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
+ TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
+ TextureB.Width := TexNewW;
+ TextureB.Height := TexNewH;
+
+ // copy and process pixeldata
+ for Position := 0 to TexOrigH-1 do begin
+ for Position2 := 0 to TexOrigW-1 do begin
+ Pix := TextureB.Canvas.Pixels[Position2, Position];
+ // ,- part of transparent png hack
+ if ((Pix = $fefefe) or (Pix = Col)) and (length(TextureAlpha)=0) then begin //Small fix, that caused artefacts to be drawn (#fe == dec254)
+ TextureD32[Position*TexNewW + Position2 + 1, 1] := 0;
+ TextureD32[Position*TexNewW + Position2 + 1, 2] := 0;
+ TextureD32[Position*TexNewW + Position2 + 1, 3] := 0;
+ TextureD32[Position*TexNewW + Position2 + 1, 4] := 0;
+ end else if (Format = 'PNG') and (length(TextureAlpha) <> 0) then begin
+ myAlpha:=TextureAlpha[Position*TexOrigW+Position2];
+ TextureD32[Position*TexNewW + Position2+1, 1] := MyRGBABitmap[(Position*TexOrigW+Position2)*4+2];
+ TextureD32[Position*TexNewW + Position2+1, 2] := MyRGBABitmap[(Position*TexOrigW+Position2)*4+1];
+ TextureD32[Position*TexNewW + Position2+1, 3] := MyRGBABitmap[(Position*TexOrigW+Position2)*4];
+ TextureD32[Position*TexNewW+Position2+1,4]:=MyRGBABitmap[(Position*TexOrigW+Position2)*4+3];
+ end else begin
+ TextureD32[Position*TexNewW + Position2+1, 1] := (Pix and $ff);
+ TextureD32[Position*TexNewW + Position2+1, 2] := ((Pix shr 8) and $ff);
+ TextureD32[Position*TexNewW + Position2+1, 3] := ((Pix shr 16) and $ff);
+ TextureD32[Position*TexNewW + Position2+1, 4] := 255;
+ end;
+ end;
+ end;
+ setlength(TextureAlpha,0);
+ setlength(MyRGBABitmap,0);
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, TexNewW, TexNewH, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
+{ if Mipmapping then begin
+ Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 4, TextureB.Width, TextureB.Height, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
+ if Error > 0 then beep;
+ end;}
+ end;
+
+// The new awesomeness of colorized pngs starts here
+// We're the first who had this feature, so give credit when you copy+paste :P
+ if Typ = 'Colorized' then begin
+ // dimensions
+ TexOrigW := TextureB.Width;
+ TexOrigH := TextureB.Height;
+ TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
+ TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
+ TextureB.Width := TexNewW;
+ TextureB.Height := TexNewH;
+
+ myHue:=col2h(Col);
+ // copy and process pixeldata
+ for Position := 0 to TexOrigH-1 do begin
+ for Position2 := 0 to TexOrigW-1 do begin
+ Pix := TextureB.Canvas.Pixels[Position2, Position];
+ if (Format = 'PNG') and (length(MyRGBABitmap) <> 0) then
+ ColorizeCopy(@MyRGBABitmap[(Position*TexOrigW+Position2)*4],
+ @TextureD32[Position*TexNewW + Position2+1, 1],
+ myHue)
+ else
+ ColorizeCopy(Pix,
+ @TextureD32[Position*TexNewW + Position2+1, 1],
+ myHue);
+ end;
+ end;
+
+ setlength(TextureAlpha,0);
+ setlength(MyRGBABitmap,0);
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, TexNewW, TexNewH, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
+ end;
+// eoa COLORIZE
+
+ if Typ = 'Transparent Range' then begin
+ // dimensions
+ TexOrigW := TextureB.Width;
+ TexOrigH := TextureB.Height;
+ TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
+ TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
+ TextureB.Width := TexNewW;
+ TextureB.Height := TexNewH;
+ // copy and process pixeldata
+ for Position := 0 to TexOrigH-1 do begin
+ for Position2 := 0 to TexOrigW-1 do begin
+ Pix := TextureB.Canvas.Pixels[Position2, Position];
+ TextureD32[Position*TexNewW + Position2+1, 1] := Pix;
+ TextureD32[Position*TexNewW + Position2+1, 2] := Pix div 256;
+ TextureD32[Position*TexNewW + Position2+1, 3] := Pix div (256*256);
+ TextureD32[Position*TexNewW + Position2+1, 4] := 256 - Pix div 256;
+ end;
+ end;
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, TexNewW, TexNewH, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
+{ if Mipmapping then begin
+ Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 4, TextureB.Width, TextureB.Height, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
+ if Error > 0 then beep;
+ end;}
+ end;
+
+ if Typ = 'Font' then begin
+ TextureB.PixelFormat := pf24bit;
+ for Position := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Position];
+ for Position2 := 0 to TextureB.Width-1 do begin
+ Pix := PPix[Position2 * 3];
+ TextureD16[Position*TextureB.Width + Position2 + 1, 1] := 255;
+ TextureD16[Position*TextureB.Width + Position2 + 1, 2] := Pix;
+ end;
+ end;
+ glTexImage2D(GL_TEXTURE_2D, 0, 2, TextureB.Width, TextureB.Height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
+
+ if Mipmapping then glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ if Mipmapping then begin
+ Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 2, TextureB.Width, TextureB.Height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
+ if Error > 0 then beep;
+ end;
+ end;
+
+ if Typ = 'Font Outline' then begin
+ TextureB.PixelFormat := pf24bit;
+ for Position := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Position];
+ for Position2 := 0 to TextureB.Width-1 do begin
+ Pix := PPix[Position2 * 3];
+
+ Col := Pix;
+ if Col < 127 then Col := 127;
+
+ TempA := Pix;
+ if TempA >= 95 then TempA := 255;
+ if TempA >= 31 then TempA := 255;
+ if Pix < 95 then TempA := (Pix * 256) div 96;
+
+
+ TextureD16[Position*TextureB.Width + Position2 + 1, 1] := Col;
+ TextureD16[Position*TextureB.Width + Position2 + 1, 2] := TempA;
+ end;
+ end;
+ glTexImage2D(GL_TEXTURE_2D, 0, 2, TextureB.Width, TextureB.Height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
+
+ if Mipmapping then glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ if Mipmapping then begin
+ Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 2, TextureB.Width, TextureB.Height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
+ if Error > 0 then beep;
+ end;
+ end;
+
+ if Typ = 'Font Outline 2' then begin
+ TextureB.PixelFormat := pf24bit;
+ for Position := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Position];
+ for Position2 := 0 to TextureB.Width-1 do begin
+ Pix := PPix[Position2 * 3];
+
+ Col := Pix;
+ if Col < 31 then Col := 31;
+
+ TempA := Pix;
+ if TempA >= 31 then TempA := 255;
+ if Pix < 31 then TempA := Pix * (256 div 32);
+
+ TextureD16[Position*TextureB.Width + Position2 + 1, 1] := Col;
+ TextureD16[Position*TextureB.Width + Position2 + 1, 2] := TempA;
+ end;
+ end;
+ glTexImage2D(GL_TEXTURE_2D, 0, 2, TextureB.Width, TextureB.Height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
+
+ if Mipmapping then glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ if Mipmapping then begin
+ Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 2, TextureB.Width, TextureB.Height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
+ if Error > 0 then beep;
+ end;
+ end;
+
+ if Typ = 'Font Black' then begin
+ // normalnie 0,125s bez niczego 0,015s - 0,030s z pix 0,125s <-- ???
+ // dimensions
+ TextureB.PixelFormat := pf24bit;
+ TexOrigW := TextureB.Width;
+ TexOrigH := TextureB.Height;
+ TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
+ TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
+ TextureB.Width := TexNewW;
+ TextureB.Height := TexNewH;
+ // copy and process pixeldata
+ for Position := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Position];
+ for Position2 := 0 to TextureB.Width-1 do begin
+ Pix := PPix[Position2*3];
+ TextureD32[Position*TextureB.Width + Position2 + 1, 1] := 255;
+ TextureD32[Position*TextureB.Width + Position2 + 1, 2] := 255;
+ TextureD32[Position*TextureB.Width + Position2 + 1, 3] := 255;
+ TextureD32[Position*TextureB.Width + Position2 + 1, 4] := 255 - (Pix mod 256);
+ end;
+ end;
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
+ end;
+
+ if Typ = 'Alpha Black Colored' then begin
+ TextureB.PixelFormat := pf24bit;
+ TexOrigW := TextureB.Width;
+ TexOrigH := TextureB.Height;
+ TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
+ TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
+ TextureB.Width := TexNewW;
+ TextureB.Height := TexNewH;
+ // copy and process pixeldata
+ for Position := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Position];
+ for Position2 := 0 to TextureB.Width-1 do begin
+ Pix := PPix[Position2*3];
+ TextureD32[Position*TextureB.Width + Position2 + 1, 1] := (Col div $10000) and $FF;
+ TextureD32[Position*TextureB.Width + Position2 + 1, 2] := (Col div $100) and $FF;
+ TextureD32[Position*TextureB.Width + Position2 + 1, 3] := Col and $FF;
+ TextureD32[Position*TextureB.Width + Position2 + 1, 4] := 255 - (Pix mod 256);
+ end;
+ end;
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
+ end;
+
+ if Typ = 'Font Gray' then begin
+ // dimensions
+ TexOrigW := TextureB.Width;
+ TexOrigH := TextureB.Height;
+ TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
+ TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
+ TextureB.Width := TexNewW;
+ TextureB.Height := TexNewH;
+ // copy and process pixeldata
+ for Position := 0 to TextureB.Height-1 do begin
+ for Position2 := 0 to TextureB.Width-1 do begin
+ Pix := TextureB.Canvas.Pixels[Position2, Position];
+ TextureD32[Position*TextureB.Width + Position2 + 1, 1] := 127;
+ TextureD32[Position*TextureB.Width + Position2 + 1, 2] := 127;
+ TextureD32[Position*TextureB.Width + Position2 + 1, 3] := 127;
+ TextureD32[Position*TextureB.Width + Position2 + 1, 4] := 255 - (Pix mod 256);
+ end;
+ end;
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
+{ if Mipmapping then begin
+ Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 4, TextureB.Width, TextureB.Height, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
+ if Error > 0 then beep;
+ end;}
+ end;
+
+ if Typ = 'Arrow' then begin
+ TextureB.PixelFormat := pf24bit;
+ for Position := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Position];
+ for Position2 := 0 to TextureB.Width-1 do begin
+ Pix := PPix[Position2 * 3];
+
+ // transparency
+ if Pix >= 127 then TempA := 255;
+ if Pix < 127 then TempA := Pix * 2;
+
+ // ColInt = color intensity
+ if Pix < 127 then ColInt := 1;
+ if Pix >= 127 then ColInt := 2 - Pix / 128;
+ //0.75, 0.6, 0.25
+
+ TextureD32[Position*TextureB.Width + Position2 + 1, 1] := Round(ColInt * 0.75 * 255 + (1 - ColInt) * 255);
+ TextureD32[Position*TextureB.Width + Position2 + 1, 2] := Round(ColInt * 0.6 * 255 + (1 - ColInt) * 255);
+ TextureD32[Position*TextureB.Width + Position2 + 1, 3] := Round(ColInt * 0.25 * 255 + (1 - ColInt) * 255);
+ TextureD32[Position*TextureB.Width + Position2 + 1, 4] := TempA;
+ end;
+ end;
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
+
+ if Mipmapping then glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
+ if Mipmapping then begin
+ Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 4, TextureB.Width, TextureB.Height, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
+ if Error > 0 then beep;
+ end;
+ end;
+
+ if Typ = 'Note Plain' then begin
+ for Position := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Position];
+ for Position2 := 0 to TextureB.Width-1 do begin
+
+
+
+ // Skin Patch
+ // 0-191= Fade Black to Col, 192= Col, 193-254 Fade Col to White, 255= White
+ case PPix[Position2*3] of
+ 0..191: Pix := $10000 * ((((Col div $10000) and $FF) * PPix[Position2*3]) div $Bf) + $100 * ((((Col div $100) and $FF) * PPix[Position2*3]) div $Bf) + (((Col and $FF) * PPix[Position2*3]) div $Bf);
+ 192: Pix := Col;
+ 193..254: Pix := Col + ($10000 * ((($FF - ((Col div $10000) and $FF)) * ((PPix[Position2*3] - $C0) * 4) ) div $FF) + $100 * ((($FF - ((Col div $100) and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF) + ((($FF - (Col and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF));
+ 255: Pix := $FFFFFF;
+ end;
+// 0.5.0. Original
+// case PPix[Position2*3] of
+// 128: Pix := $10000 * ((Col div $10000) div 2) + $100 * (((Col div $100) and $FF) div 2) + (Col and $FF) div 2;
+// 192: Pix := Col;
+// 255: Pix := $FFFFFF;
+// end;
+
+
+
+
+
+ TextureD24[Position*TextureB.Width + Position2 + 1, 1] := Pix div $10000;
+ TextureD24[Position*TextureB.Width + Position2 + 1, 2] := (Pix div $100) and $FF;
+ TextureD24[Position*TextureB.Width + Position2 + 1, 3] := Pix and $FF;
+ end;
+ end;
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureB.Width, TextureB.Height, 0, GL_RGB, GL_UNSIGNED_BYTE, @TextureD24);
+ end;
+
+ if Typ = 'Note Transparent' then begin
+ for Position := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Position];
+ for Position2 := 0 to TextureB.Width-1 do begin
+ TempA := 255;
+
+
+
+ //Skin Patch
+ // 0= Transparent, 1-191= Fade Black to Col, 192= Col, 193-254 Fade Col to White, 255= White
+ case PPix[Position2*3] of
+ 0: TempA := 0;
+ 1..191: Pix := $10000 * ((((Col div $10000) and $FF) * PPix[Position2*3]) div $Bf) + $100 * ((((Col div $100) and $FF) * PPix[Position2*3]) div $Bf) + (((Col and $FF) * PPix[Position2*3]) div $Bf);
+ 192: Pix := Col;
+ 193..254: Pix := Col + ($10000 * ((($FF - ((Col div $10000) and $FF)) * ((PPix[Position2*3] - $C0) * 4) ) div $FF) + $100 * ((($FF - ((Col div $100) and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF) + ((($FF - (Col and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF));
+ 255: Pix := $FFFFFF;
+ end;
+// 0.5.0 Original
+// case PPix[Position2*3] of
+// 0: TempA := 0;
+// 128: Pix := $10000 * ((Col div $10000) div 2) + $100 * (((Col div $100) and $FF) div 2) + (Col and $FF) div 2;
+// 192: Pix := Col;
+// 255: Pix := $FFFFFF;
+// end;
+
+
+
+
+ TextureD32[Position*TextureB.Width + Position2 + 1, 1] := Pix div $10000;
+ TextureD32[Position*TextureB.Width + Position2 + 1, 2] := (Pix div $100) and $FF;
+ TextureD32[Position*TextureB.Width + Position2 + 1, 3] := Pix and $FF;
+ TextureD32[Position*TextureB.Width + Position2 + 1, 4] := TempA;
+ end;
+ end;
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
+ end;
+
+ TextureB.Free;
+ Result.X := 0;
+ Result.Y := 0;
+ Result.W := 0;
+ Result.H := 0;
+ Result.ScaleW := 1;
+ Result.ScaleH := 1;
+ Result.Rot := 0;
+ Result.TexNum := ActTex;
+ Result.TexW := TexOrigW / TexNewW;
+ Result.TexH := TexOrigH / TexNewH;
+
+ Result.Int := 1;
+ Result.ColR := 1;
+ Result.ColG := 1;
+ Result.ColB := 1;
+ Result.Alpha := 1;
+
+ // 0.4.2 new test - default use whole texure, taking TexW and TexH as const and changing these
+ Result.TexX1 := 0;
+ Result.TexY1 := 0;
+ Result.TexX2 := 1;
+ Result.TexY2 := 1;
+
+ // 0.5.0
+ Result.Name := Identifier;
+
+ end;
+
+ Log.BenchmarkEnd(4);
+ if Log.BenchmarkTimeLength[4] >= 1 then
+ Log.LogBenchmark('**********> Texture Load Time Warning - ' + Format + '/' + Identifier + '/' + Typ, 4);
+
+ end; // logerror
+ {$ENDIF}
+end;
+
+{procedure ResizeTexture(s: pbytearray; d: pbytearray);
+var
+ Position: integer;
+ Position2: integer;
+begin
+ for Position := 0 to TexNewH*4-1 do
+ for Position2 := 0 to TexNewW-1 do
+ d[Position*TexNewW + Position2] := 0;
+
+ for Position := 0 to TexOrigH-1 do begin
+ for Position2 := 0 to TexOrigW-1 do begin
+ d[(Position*TexNewW + Position2)*4] := Paleta[s[Position*TexOrigW + Position2], 1];
+ d[(Position*TexNewW + Position2)*4+1] := Paleta[s[Position*TexOrigW + Position2], 2];
+ d[(Position*TexNewW + Position2)*4+2] := Paleta[s[Position*TexOrigW + Position2], 3];
+ d[(Position*TexNewW + Position2)*4+3] := Paleta[s[Position*TexOrigW + Position2], 4];
+ end;
+ end;
+end;}
+
+{procedure SetTexture(p: pointer);
+begin
+ glGenTextures(1, Tekstur);
+ glBindTexture(GL_TEXTURE_2D, Tekstur);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, TexNewW, TexNewH, 0, GL_RGBA, GL_UNSIGNED_BYTE, p);
+end;}
+
+function TTextureUnit.LoadTexture(Identifier, Format, Typ: PChar; Col: LongWord): TTexture;
+begin
+ Result := LoadTexture(false, Identifier, Format, Typ, Col);
+// Result := LoadTexture(SkinReg, Identifier, Format, Typ, Col); // default to SkinReg
+
+end;
+
+function TTextureUnit.LoadTexture(Identifier: string): TTexture;
+begin
+ Result := LoadTexture(false, pchar(Identifier), 'JPG', 'Plain', 0);
+end;
+
+function TTextureUnit.CreateTexture(var Data: array of byte; Name: string; W, H: word; Bits: byte): TTexture;
+var
+ Position: integer;
+ Position2: integer;
+ Pix: integer;
+ ColInt: real;
+ PPix: PByteArray;
+ TempA: integer;
+ Error: integer;
+begin
+ Mipmapping := false;
+
+ glGenTextures(1, ActTex); // ActText = new texture number
+ glBindTexture(GL_TEXTURE_2D, ActTex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, @Data[0]);
+ if Mipmapping then begin
+ Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 3, W, H, GL_RGB, GL_UNSIGNED_BYTE, @Data[0]);
+ if Error > 0 then beep;
+ end;
+
+ Result.X := 0;
+ Result.Y := 0;
+ Result.W := 0;
+ Result.H := 0;
+ Result.ScaleW := 1;
+ Result.ScaleH := 1;
+ Result.Rot := 0;
+ Result.TexNum := ActTex;
+ Result.TexW := 1;
+ Result.TexH := 1;
+
+ Result.Int := 1;
+ Result.ColR := 1;
+ Result.ColG := 1;
+ Result.ColB := 1;
+ Result.Alpha := 1;
+
+ // 0.4.2 new test - default use whole texure, taking TexW and TexH as const and changing these
+ Result.TexX1 := 0;
+ Result.TexY1 := 0;
+ Result.TexX2 := 1;
+ Result.TexY2 := 1;
+
+ // 0.5.0
+ Result.Name := Name;
+end;
+
+procedure TTextureUnit.UnloadTexture(Name: string; FromCache: boolean);
+var
+ T: integer;
+ TexNum: GLuint;
+begin
+ T := FindTexture(Name);
+
+ if not FromCache then begin
+ TexNum := TextureDatabase.Texture[T].Texture.TexNum;
+ if TexNum >= 0 then begin
+ glDeleteTextures(1, @TexNum);
+ TextureDatabase.Texture[T].Texture.TexNum := -1;
+// Log.LogError('Unload texture no '+IntToStr(TexNum));
+ end;
+ end else begin
+ TexNum := TextureDatabase.Texture[T].TextureCache.TexNum;
+ if TexNum >= 0 then begin
+ glDeleteTextures(1, @TexNum);
+ TextureDatabase.Texture[T].TextureCache.TexNum := -1;
+// Log.LogError('Unload texture cache no '+IntToStr(TexNum));
+ end;
+ end;
+end;
+
+end.
diff --git a/Game/Code/Classes/UTime.pas b/Game/Code/Classes/UTime.pas
index 29e972ae..87d4f922 100644
--- a/Game/Code/Classes/UTime.pas
+++ b/Game/Code/Classes/UTime.pas
@@ -1,81 +1,131 @@
-unit UTime;
-
-interface
-
-type
- TTime = class
- constructor Create;
- function GetTime: real;
- end;
-
-procedure CountSkipTimeSet;
-procedure CountSkipTime;
-procedure CountMidTime;
-procedure TimeSleep(ms: real);
-
-var
- USTime: TTime;
-
- TimeFreq: int64;
- TimeNew: int64;
- TimeOld: int64;
- TimeSkip: real;
- TimeMid: real;
- TimeMidTemp: int64;
-
-implementation
-
-uses Windows;
-
-constructor TTime.Create;
-begin
- CountSkipTimeSet;
-end;
-
-procedure CountSkipTimeSet;
-begin
- QueryPerformanceFrequency(TimeFreq);
- QueryPerformanceCounter(TimeNew);
-end;
-
-procedure CountSkipTime;
-begin
- TimeOld := TimeNew;
- QueryPerformanceCounter(TimeNew);
- TimeSkip := (TimeNew-TimeOld)/TimeFreq;
-end;
-
-procedure CountMidTime;
-begin
- QueryPerformanceCounter(TimeMidTemp);
- TimeMid := (TimeMidTemp-TimeNew)/TimeFreq;
-end;
-
-procedure TimeSleep(ms: real);
-var
- TimeStart: int64;
- TimeHalf: int64;
- Time: real;
- Stop: boolean;
-begin
- QueryPerformanceCounter(TimeStart);
-
- Stop := false;
- while (not Stop) do begin
- QueryPerformanceCounter(TimeHalf);
- Time := 1000 * (TimeHalf-TimeStart)/TimeFreq;
- if Time > ms then Stop := true;
- end;
-
-end;
-
-function TTime.GetTime: real;
-var
- TimeTemp: int64;
-begin
- QueryPerformanceCounter(TimeTemp);
- Result := TimeTemp/TimeFreq;
-end;
-
-
-end.
+unit UTime;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+type
+ TTime = class
+ constructor Create;
+ function GetTime: real;
+ end;
+
+procedure CountSkipTimeSet;
+procedure CountSkipTime;
+procedure CountMidTime;
+procedure TimeSleep(ms: real);
+
+var
+ USTime: TTime;
+
+ TimeFreq: int64;
+ TimeNew: int64;
+ TimeOld: int64;
+ TimeSkip: real;
+ TimeMid: real;
+ TimeMidTemp: int64;
+
+implementation
+
+uses
+ {$IFDEF win32}
+ windows,
+ {$ELSE}
+ libc,
+ time,
+ {$ENDIF}
+ ucommon;
+
+
+// -- ON Linux it MAY Be better to use ... clock_gettime() instead of CurrentSec100OfDay
+// who knows how fast or slow that function is !
+// but this gets a compile for now .. :)
+
+constructor TTime.Create;
+begin
+ CountSkipTimeSet;
+end;
+
+procedure CountSkipTimeSet;
+begin
+ {$IFDEF win32}
+ QueryPerformanceFrequency(TimeFreq);
+ QueryPerformanceCounter(TimeNew);
+ {$ELSE}
+ TimeNew := CurrentSec100OfDay(); // TODO - JB_Linux will prob need looking at
+ TimeFreq := 0;
+ {$ENDIF}
+end;
+
+procedure CountSkipTime;
+begin
+ TimeOld := TimeNew;
+
+ {$IFDEF win32}
+ QueryPerformanceCounter(TimeNew);
+ {$ELSE}
+ TimeNew := CurrentSec100OfDay(); // TODO - JB_Linux will prob need looking at
+ {$ENDIF}
+
+ TimeSkip := (TimeNew-TimeOld)/TimeFreq;
+end;
+
+procedure CountMidTime;
+begin
+ {$IFDEF win32}
+ QueryPerformanceCounter(TimeMidTemp);
+ TimeMid := (TimeMidTemp-TimeNew)/TimeFreq;
+ {$ELSE}
+ TimeMidTemp := CurrentSec100OfDay();
+ TimeMid := (TimeMidTemp-TimeNew); // TODO - JB_Linux will prob need looking at
+ {$ENDIF}
+end;
+
+procedure TimeSleep(ms: real);
+var
+ TimeStart: int64;
+ TimeHalf: int64;
+ Time: real;
+ Stop: boolean;
+begin
+ {$IFDEF win32}
+ QueryPerformanceCounter(TimeStart);
+ {$ELSE}
+ TimeStart := CurrentSec100OfDay(); // TODO - JB_Linux will prob need looking at
+ {$ENDIF}
+
+
+ Stop := false;
+ while (not Stop) do
+ begin
+ {$IFDEF win32}
+ QueryPerformanceCounter(TimeHalf);
+ Time := 1000 * (TimeHalf-TimeStart)/TimeFreq;
+ {$ELSE}
+ TimeHalf := CurrentSec100OfDay();
+ Time := 1000 * (TimeHalf-TimeStart); // TODO - JB_Linux will prob need looking at
+ {$ENDIF}
+
+ if Time > ms then
+ Stop := true;
+ end;
+
+end;
+
+function TTime.GetTime: real;
+var
+ TimeTemp: int64;
+begin
+ {$IFDEF win32}
+ QueryPerformanceCounter(TimeTemp);
+ Result := TimeTemp / TimeFreq;
+ {$ELSE}
+ TimeTemp := CurrentSec100OfDay();
+ Result := TimeTemp; // TODO - JB_Linux will prob need looking at
+ {$ENDIF}
+end;
+
+
+end.
diff --git a/Game/Code/Menu/UDisplay.pas b/Game/Code/Menu/UDisplay.pas
index ed65d62d..6181fab1 100644
--- a/Game/Code/Menu/UDisplay.pas
+++ b/Game/Code/Menu/UDisplay.pas
@@ -1,460 +1,469 @@
-unit UDisplay;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-uses Windows,
- SDL,
- UMenu,
- OpenGL12,
- SysUtils;
-
-type
- TDisplay = class
- ActualScreen: PMenu;
- NextScreen: PMenu;
-
- //fade-to-black-hack
- BlackScreen: Boolean;
- //popup hack
- NextScreenWithCheck: Pmenu;
- CheckOK: Boolean;
-
- h_DC: HDC;
- h_RC: HGLRC;
-
- Fade: Real;
- // fade-mod
- doFade: Boolean;
- canFade: Boolean;
- myFade: integer;
- lastTime: Cardinal;
- pTexData : Pointer;
- pTex : array[1..2] of glUInt;
- // end
-
- //FPS Counter
- FPSCounter: Cardinal;
- LastFPS: Cardinal;
- NextFPSSwap:Cardinal;
-
- //For Debug OSD
- OSD_LastError: String;
-
- function Draw: Boolean;
- procedure PrintScreen;
- constructor Create;
- // fade mod
- destructor Destroy; override;
- // end
- procedure ScreenShot;
-
- procedure DrawDebugInformation;
- end;
-
-var
- Display: TDisplay;
-
-implementation
-
-uses
- {$IFDEF FPC}
- ulazjpeg,
- {$ELSE}
- JPEG,
- {$ENDIF}
- graphics,
- TextGL,
- // UFiles,
- UMain,
- UTexture,
- UIni,
- UGraphic,
- UTime,
- UCommandLine;
-
-constructor TDisplay.Create;
-var i: integer;
-begin
- inherited Create;
-
- //popup hack
- CheckOK:=False;
- NextScreen:=NIL;
- NextScreenWithCheck:=NIL;
- BlackScreen:=False;
-
- // fade mod
- myfade:=0;
-
- if Ini.ScreenFade=1 then
- doFade:=True
- else
- doFade:=False;
-
- canFade:=True;
- // generate texture for fading between screens
- GetMem(pTexData, 512*512*4);
- if pTexData <> NIL then
- for i:= 1 to 2 do
- begin
- glGenTextures(1, pTex[i]);
- if glGetError <> GL_NO_ERROR then canFade := False;
- glBindTexture(GL_TEXTURE_2D, pTex[i]);
- if glGetError <> GL_NO_ERROR then canFade := False;
- glTexImage2D(GL_TEXTURE_2D, 0, 4, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, pTexData);
- if glGetError <> GL_NO_ERROR then canFade := False;
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- if glGetError <> GL_NO_ERROR then canFade := False;
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- if glGetError <> GL_NO_ERROR then canFade := False;
- end
- else
- begin
- canFade:=False;
- end;
- FreeMem(pTexData);
- // end
-
- //Set LastError for OSD to No Error
- OSD_LastError := 'No Errors';
-end;
-
-// fade mod
-destructor TDisplay.Destroy;
-begin
- if canFade then
- glDeleteTextures(1,@pTex);
- inherited Destroy;
-end;
-// end
-
-function TDisplay.Draw: Boolean;
-var
- S: integer;
- Col: Real;
- // fade mod
- myFade2: Real;
- currentTime: Cardinal;
- glError: glEnum;
- glErrorStr: String;
- // end
-begin
- Result := True;
-
- Col := 1;
- {if (ParamStr(1) = '-black') or (ParamStr(1) = '-fsblack') then
- Col := 0; }
-
- glClearColor(Col, Col, Col , 0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
-
- for S := 1 to Screens do begin
- ScreenAct := S;
-
-// if Screens = 1 then ScreenX := 0;
-// if (Screens = 2) and (S = 1) then ScreenX := -1;
-// if (Screens = 2) and (S = 2) then ScreenX := 1;
- ScreenX := 0;
-
- if S = 2 then TimeSkip := 0 else;
- glViewPort((S-1) * ScreenW div Screens, 0, ScreenW div Screens, ScreenH);
-
- //popup hack
- // check was successful... move on
- if CheckOK then
- if assigned (NextScreenWithCheck)then
- begin
- NextScreen:=NextScreenWithCheck;
- NextScreenWithCheck := NIL;
- CheckOk:=False;
- end
- else
- BlackScreen:=True; // end of game - fade to black before exit
- //end popup hack
-
-// ActualScreen.SetAnimationProgress(1);
- if (not assigned (NextScreen)) and (not BlackScreen) then begin
- ActualScreen.Draw;
- //popup mod
- if ScreenPopupError <> NIL then if ScreenPopupError.Visible then ScreenPopupError.Draw else
- if ScreenPopupCheck <> NIL then if ScreenPopupCheck.Visible then ScreenPopupCheck.Draw;
- //popup end
- // fade mod
- myfade:=0;
- if (Ini.ScreenFade=1) and canFade then
- doFade:=True
- else if Ini.ScreenFade=0 then
- doFade:=False;
- // end
- end
- else
- begin
- // check if we had an initialization error (canfade=false, dofade=true)
- if doFade and not canFade then begin
- doFade:=False; //disable fading
-// ScreenPopupError.ShowPopup('Error initializing\nfade texture\n\nfading\ndisabled'); //show error message
- end;
- if doFade and canFade then
- begin
- // fade mod
- //Create Fading texture if we're just starting
- if myfade = 0 then
- begin
- glViewPort(0, 0, 512, 512);
- ActualScreen.Draw;
- glBindTexture(GL_TEXTURE_2D, pTex[S]);
- glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 512, 512, 0);
- glError:=glGetError;
- if glError <> GL_NO_ERROR then
- begin
- canFade := False;
- case glError of
- GL_INVALID_ENUM: glErrorStr:='INVALID_ENUM';
- GL_INVALID_VALUE: glErrorStr:='INVALID_VALUE';
- GL_INVALID_OPERATION: glErrorStr:='INVALID_OPERATION';
- GL_STACK_OVERFLOW: glErrorStr:='STACK_OVERFLOW';
- GL_STACK_UNDERFLOW: glErrorStr:='STACK_UNDERFLOW';
- GL_OUT_OF_MEMORY: glErrorStr:='OUT_OF_MEMORY';
- else glErrorStr:='unknown error';
- end;
-// ScreenPopupError.ShowPopup('Error copying\nfade texture\n('+glErrorStr+')\nfading\ndisabled'); //show error message
- end;
- glViewPort((S-1) * ScreenW div Screens, 0, ScreenW div Screens, ScreenH);
- // blackscreen-hack
- if not BlackScreen then
- NextScreen.onShow;
- lastTime:=GetTickCount;
- if (S=2) or (Screens = 1) then
- myfade:=myfade+1;
- end; // end texture creation in first fading step
-
- //do some time-based fading
- currentTime:=GetTickCount;
- if (currentTime > lastTime+30) and (S=1) then
- begin
- myfade:=myfade+4;
- lastTime:=currentTime;
- end;
-
-// LastFade := Fade; // whatever
-// Fade := Fade -0.999; // start fading out
-
-
-// ActualScreen.ShowFinish := false; // no purpose?
-
-// ActualScreen.SetAnimationProgress(Fade-1); // nop?
-
- // blackscreen-hack
- if not BlackScreen then
- NextScreen.Draw // draw next screen
- else if ScreenAct=1 then begin
- glClearColor(0, 0, 0 , 0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
- end;
-
- // and draw old screen over it... slowly fading out
- myfade2:=(myfade*myfade)/10000;
- glBindTexture(GL_TEXTURE_2D, pTex[S]);
- glColor4f(1, 1, 1, (1000-myfade*myfade)/1000); // strange calculation - alpha gets negative... but looks good this way
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glBegin(GL_QUADS);
- glTexCoord2f(0+myfade2,0+myfade2);glVertex2f(0, 600);
- glTexCoord2f(0+myfade2,1-myfade2);glVertex2f(0, 0);
- glTexCoord2f(1-myfade2,1-myfade2);glVertex2f(800, 0);
- glTexCoord2f(1-myfade2,0+myfade2);glVertex2f(800, 600);
- glEnd;
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- end
- else
- // blackscreen hack
- if not BlackScreen then
- NextScreen.OnShow;
-
-
- if ((myfade > 40) or (not doFade) or (not canFade)) And (S = 1) then begin // fade out complete...
- myFade:=0;
- ActualScreen.onHide;
- ActualScreen.ShowFinish:=False;
- ActualScreen:=NextScreen;
- NextScreen := nil;
- if not blackscreen then
- begin
- ActualScreen.onShowFinish;
- ActualScreen.ShowFinish := true;
- end
- else
- begin
- Result:=False;
- Break;
- end;
- // end of fade mod
- end;
- end; // if
-
- //Draw OSD only on first Screen if Debug Mode is enabled
- if ((Ini.Debug = 1) OR (Params.Debug)) AND (S=1) then
- DrawDebugInformation;
-
- end; // for
-// SwapBuffers(h_DC);
-end;
-
-{function TDisplay.Fade(FadeIn : Boolean; Steps : UInt8): UInt8;
-begin
- Self.FadeIn := FadeIn;
- FadeStep := (SizeOf(FadeStep) * $FF) div Steps;
- ActualStep := $FF;
- Result := $FF div FadeStep;
-end;}
-
-procedure TDisplay.PrintScreen;
-var
- Bitmap: TBitmap;
- Jpeg: TJpegImage;
- X, Y: integer;
- Num: integer;
- FileName: string;
-begin
- for Num := 1 to 9999 do begin
- FileName := IntToStr(Num);
- while Length(FileName) < 4 do FileName := '0' + FileName;
- FileName := ScreenshotsPath + 'screenshot' + FileName + '.jpg';
- if not FileExists(FileName) then break
- end;
-
- glReadPixels(0, 0, ScreenW, ScreenH, GL_RGBA, GL_UNSIGNED_BYTE, @PrintScreenData[0]);
- Bitmap := TBitmap.Create;
- Bitmap.Width := ScreenW;
- Bitmap.Height := ScreenH;
-
- for Y := 0 to ScreenH-1 do
- for X := 0 to ScreenW-1 do
- Bitmap.Canvas.Pixels[X, Y] := PrintScreenData[(ScreenH-1-Y) * ScreenW + X] and $00FFFFFF;
-
- Jpeg := TJpegImage.Create;
- Jpeg.Assign(Bitmap);
- Bitmap.Free;
- Jpeg.CompressionQuality := 95;//90;
- Jpeg.SaveToFile(FileName);
- Jpeg.Free;
-end;
-
-procedure TDisplay.ScreenShot;
- var F : file;
- FileInfo: BITMAPINFOHEADER;
- FileHeader : BITMAPFILEHEADER;
- pPicData:Pointer;
- FileName: String;
- Num: Integer;
-begin
- //bilddatei Suchen
- for Num := 1 to 9999 do begin
- FileName := IntToStr(Num);
- while Length(FileName) < 4 do FileName := '0' + FileName;
- FileName := ScreenshotsPath + FileName + '.BMP';
- if not FileExists(FileName) then break
- end;
-
- //Speicher für die Speicherung der Header-Informationen vorbereiten
- ZeroMemory(@FileHeader, SizeOf(BITMAPFILEHEADER));
- ZeroMemory(@FileInfo, SizeOf(BITMAPINFOHEADER));
-
- //Initialisieren der Daten des Headers
- FileHeader.bfType := 19778; //$4D42 = 'BM'
- FileHeader.bfOffBits := SizeOf(BITMAPINFOHEADER)+SizeOf(BITMAPFILEHEADER);
-
- //Schreiben der Bitmap-Informationen
- FileInfo.biSize := SizeOf(BITMAPINFOHEADER);
- FileInfo.biWidth := ScreenW;
- FileInfo.biHeight := ScreenH;
- FileInfo.biPlanes := 1;
- FileInfo.biBitCount := 32;
- FileInfo.biSizeImage := FileInfo.biWidth*FileInfo.biHeight*(FileInfo.biBitCount div 8);
-
- //Größenangabe auch in den Header übernehmen
- FileHeader.bfSize := FileHeader.bfOffBits + FileInfo.biSizeImage;
-
- //Speicher für die Bilddaten reservieren
- GetMem(pPicData, FileInfo.biSizeImage);
- try
- //Bilddaten von OpenGL anfordern (siehe oben)
- glReadPixels(0, 0, ScreenW, ScreenH, GL_BGRA, GL_UNSIGNED_BYTE, pPicData);
-
- //Und den ganzen Müll in die Datei schieben ;-)
- //Moderne Leute nehmen dafür auch Streams ...
- AssignFile(f, Filename);
- Rewrite( f,1 );
- try
- BlockWrite(F, FileHeader, SizeOf(BITMAPFILEHEADER));
- BlockWrite(F, FileInfo, SizeOf(BITMAPINFOHEADER));
- BlockWrite(F, pPicData^, FileInfo.biSizeImage );
- finally
- CloseFile(f);
- end;
- finally
- //Und den angeforderten Speicher wieder freigeben ...
- FreeMem(pPicData, FileInfo.biSizeImage);
- end;
-end;
-
-//------------
-// DrawDebugInformation - Procedure draw FPS and some other Informations on Screen
-//------------
-procedure TDisplay.DrawDebugInformation;
-var Ticks: Cardinal;
-begin
- //Some White Background for information
- glEnable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- glColor4f(1, 1, 1, 0.5);
- glBegin(GL_QUADS);
- glVertex2f(690, 44);
- glVertex2f(690, 0);
- glVertex2f(800, 0);
- glVertex2f(800, 44);
- glEnd;
- glDisable(GL_BLEND);
-
- //Set Font Specs
- SetFontStyle(0);
- SetFontSize(7);
- SetFontItalic(False);
- glColor4f(0, 0, 0, 1);
-
- //Calculate FPS
- Ticks := GetTickCount;
- if (Ticks >= NextFPSSwap) then
- begin
- LastFPS := FPSCounter * 4;
- FPSCounter := 0;
- NextFPSSwap := Ticks + 250;
- end;
-
- Inc(FPSCounter);
-
- //Draw Text
-
- //FPS
- SetFontPos(695, 0);
- glPrint (PChar('FPS: ' + InttoStr(LastFPS)));
-
- //RSpeed
- SetFontPos(695, 13);
- glPrint (PChar('RSpeed: ' + InttoStr(Round(1000 * TimeMid))));
-
- //LastError
- SetFontPos(695, 26);
- glColor4f(1, 0, 0, 1);
- glPrint (PChar(OSD_LastError));
-
- glColor4f(1, 1, 1, 1);
-end;
-
-end.
+unit UDisplay;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+uses {$IFDEF win32}
+ windows,
+ {$ELSE}
+ LCLType,
+ {$ENDIF}
+ ucommon,
+ SDL,
+ UMenu,
+ OpenGL12,
+ SysUtils;
+
+type
+ TDisplay = class
+ ActualScreen: PMenu;
+ NextScreen: PMenu;
+
+ //fade-to-black-hack
+ BlackScreen: Boolean;
+ //popup hack
+ NextScreenWithCheck: Pmenu;
+ CheckOK: Boolean;
+
+ h_DC: HDC;
+ h_RC: HGLRC;
+
+ Fade: Real;
+ // fade-mod
+ doFade: Boolean;
+ canFade: Boolean;
+ myFade: integer;
+ lastTime: Cardinal;
+ pTexData : Pointer;
+ pTex : array[1..2] of glUInt;
+ // end
+
+ //FPS Counter
+ FPSCounter: Cardinal;
+ LastFPS: Cardinal;
+ NextFPSSwap:Cardinal;
+
+ //For Debug OSD
+ OSD_LastError: String;
+
+ function Draw: Boolean;
+ procedure PrintScreen;
+ constructor Create;
+ // fade mod
+ destructor Destroy; override;
+ // end
+ procedure ScreenShot;
+
+ procedure DrawDebugInformation;
+ end;
+
+var
+ Display: TDisplay;
+
+implementation
+
+uses
+ {$IFDEF FPC}
+ ulazjpeg,
+ {$ELSE}
+ JPEG,
+ {$ENDIF}
+ {$IFNDEF win32}
+ lclintf,
+ {$ENDIF}
+ graphics,
+ TextGL,
+ // UFiles,
+ UMain,
+ UTexture,
+ UIni,
+ UGraphic,
+ UTime,
+ UCommandLine;
+
+constructor TDisplay.Create;
+var i: integer;
+begin
+ inherited Create;
+
+ //popup hack
+ CheckOK:=False;
+ NextScreen:=NIL;
+ NextScreenWithCheck:=NIL;
+ BlackScreen:=False;
+
+ // fade mod
+ myfade:=0;
+
+ if Ini.ScreenFade=1 then
+ doFade:=True
+ else
+ doFade:=False;
+
+ canFade:=True;
+ // generate texture for fading between screens
+ GetMem(pTexData, 512*512*4);
+ if pTexData <> NIL then
+ for i:= 1 to 2 do
+ begin
+ glGenTextures(1, pTex[i]);
+ if glGetError <> GL_NO_ERROR then canFade := False;
+ glBindTexture(GL_TEXTURE_2D, pTex[i]);
+ if glGetError <> GL_NO_ERROR then canFade := False;
+ glTexImage2D(GL_TEXTURE_2D, 0, 4, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, pTexData);
+ if glGetError <> GL_NO_ERROR then canFade := False;
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ if glGetError <> GL_NO_ERROR then canFade := False;
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ if glGetError <> GL_NO_ERROR then canFade := False;
+ end
+ else
+ begin
+ canFade:=False;
+ end;
+ FreeMem(pTexData);
+ // end
+
+ //Set LastError for OSD to No Error
+ OSD_LastError := 'No Errors';
+end;
+
+// fade mod
+destructor TDisplay.Destroy;
+begin
+ if canFade then
+ glDeleteTextures(1,@pTex);
+ inherited Destroy;
+end;
+// end
+
+function TDisplay.Draw: Boolean;
+var
+ S: integer;
+ Col: Real;
+ // fade mod
+ myFade2: Real;
+ currentTime: Cardinal;
+ glError: glEnum;
+ glErrorStr: String;
+ // end
+begin
+ Result := True;
+
+ Col := 1;
+ {if (ParamStr(1) = '-black') or (ParamStr(1) = '-fsblack') then
+ Col := 0; }
+
+ glClearColor(Col, Col, Col , 0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+
+ for S := 1 to Screens do begin
+ ScreenAct := S;
+
+// if Screens = 1 then ScreenX := 0;
+// if (Screens = 2) and (S = 1) then ScreenX := -1;
+// if (Screens = 2) and (S = 2) then ScreenX := 1;
+ ScreenX := 0;
+
+ if S = 2 then TimeSkip := 0 else;
+ glViewPort((S-1) * ScreenW div Screens, 0, ScreenW div Screens, ScreenH);
+
+ //popup hack
+ // check was successful... move on
+ if CheckOK then
+ if assigned (NextScreenWithCheck)then
+ begin
+ NextScreen:=NextScreenWithCheck;
+ NextScreenWithCheck := NIL;
+ CheckOk:=False;
+ end
+ else
+ BlackScreen:=True; // end of game - fade to black before exit
+ //end popup hack
+
+// ActualScreen.SetAnimationProgress(1);
+ if (not assigned (NextScreen)) and (not BlackScreen) then begin
+ ActualScreen.Draw;
+ //popup mod
+ if ScreenPopupError <> NIL then if ScreenPopupError.Visible then ScreenPopupError.Draw else
+ if ScreenPopupCheck <> NIL then if ScreenPopupCheck.Visible then ScreenPopupCheck.Draw;
+ //popup end
+ // fade mod
+ myfade:=0;
+ if (Ini.ScreenFade=1) and canFade then
+ doFade:=True
+ else if Ini.ScreenFade=0 then
+ doFade:=False;
+ // end
+ end
+ else
+ begin
+ // check if we had an initialization error (canfade=false, dofade=true)
+ if doFade and not canFade then begin
+ doFade:=False; //disable fading
+// ScreenPopupError.ShowPopup('Error initializing\nfade texture\n\nfading\ndisabled'); //show error message
+ end;
+ if doFade and canFade then
+ begin
+ // fade mod
+ //Create Fading texture if we're just starting
+ if myfade = 0 then
+ begin
+ glViewPort(0, 0, 512, 512);
+ ActualScreen.Draw;
+ glBindTexture(GL_TEXTURE_2D, pTex[S]);
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 512, 512, 0);
+ glError:=glGetError;
+ if glError <> GL_NO_ERROR then
+ begin
+ canFade := False;
+ case glError of
+ GL_INVALID_ENUM: glErrorStr:='INVALID_ENUM';
+ GL_INVALID_VALUE: glErrorStr:='INVALID_VALUE';
+ GL_INVALID_OPERATION: glErrorStr:='INVALID_OPERATION';
+ GL_STACK_OVERFLOW: glErrorStr:='STACK_OVERFLOW';
+ GL_STACK_UNDERFLOW: glErrorStr:='STACK_UNDERFLOW';
+ GL_OUT_OF_MEMORY: glErrorStr:='OUT_OF_MEMORY';
+ else glErrorStr:='unknown error';
+ end;
+// ScreenPopupError.ShowPopup('Error copying\nfade texture\n('+glErrorStr+')\nfading\ndisabled'); //show error message
+ end;
+ glViewPort((S-1) * ScreenW div Screens, 0, ScreenW div Screens, ScreenH);
+ // blackscreen-hack
+ if not BlackScreen then
+ NextScreen.onShow;
+
+ lastTime:=GetTickCount;
+ if (S=2) or (Screens = 1) then
+ myfade:=myfade+1;
+ end; // end texture creation in first fading step
+
+ //do some time-based fading
+ currentTime:=GetTickCount;
+ if (currentTime > lastTime+30) and (S=1) then
+ begin
+ myfade:=myfade+4;
+ lastTime:=currentTime;
+ end;
+
+// LastFade := Fade; // whatever
+// Fade := Fade -0.999; // start fading out
+
+
+// ActualScreen.ShowFinish := false; // no purpose?
+
+// ActualScreen.SetAnimationProgress(Fade-1); // nop?
+
+ // blackscreen-hack
+ if not BlackScreen then
+ NextScreen.Draw // draw next screen
+ else if ScreenAct=1 then begin
+ glClearColor(0, 0, 0 , 0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+ end;
+
+ // and draw old screen over it... slowly fading out
+ myfade2:=(myfade*myfade)/10000;
+ glBindTexture(GL_TEXTURE_2D, pTex[S]);
+ glColor4f(1, 1, 1, (1000-myfade*myfade)/1000); // strange calculation - alpha gets negative... but looks good this way
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glBegin(GL_QUADS);
+ glTexCoord2f(0+myfade2,0+myfade2);glVertex2f(0, 600);
+ glTexCoord2f(0+myfade2,1-myfade2);glVertex2f(0, 0);
+ glTexCoord2f(1-myfade2,1-myfade2);glVertex2f(800, 0);
+ glTexCoord2f(1-myfade2,0+myfade2);glVertex2f(800, 600);
+ glEnd;
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ end
+ else
+ // blackscreen hack
+ if not BlackScreen then
+ NextScreen.OnShow;
+
+
+ if ((myfade > 40) or (not doFade) or (not canFade)) And (S = 1) then begin // fade out complete...
+ myFade:=0;
+ ActualScreen.onHide;
+ ActualScreen.ShowFinish:=False;
+ ActualScreen:=NextScreen;
+ NextScreen := nil;
+ if not blackscreen then
+ begin
+ ActualScreen.onShowFinish;
+ ActualScreen.ShowFinish := true;
+ end
+ else
+ begin
+ Result:=False;
+ Break;
+ end;
+ // end of fade mod
+ end;
+ end; // if
+
+ //Draw OSD only on first Screen if Debug Mode is enabled
+ if ((Ini.Debug = 1) OR (Params.Debug)) AND (S=1) then
+ DrawDebugInformation;
+
+ end; // for
+// SwapBuffers(h_DC);
+end;
+
+{function TDisplay.Fade(FadeIn : Boolean; Steps : UInt8): UInt8;
+begin
+ Self.FadeIn := FadeIn;
+ FadeStep := (SizeOf(FadeStep) * $FF) div Steps;
+ ActualStep := $FF;
+ Result := $FF div FadeStep;
+end;}
+
+procedure TDisplay.PrintScreen;
+var
+ Bitmap: TBitmap;
+ Jpeg: TJpegImage;
+ X, Y: integer;
+ Num: integer;
+ FileName: string;
+begin
+ for Num := 1 to 9999 do begin
+ FileName := IntToStr(Num);
+ while Length(FileName) < 4 do FileName := '0' + FileName;
+ FileName := ScreenshotsPath + 'screenshot' + FileName + '.jpg';
+ if not FileExists(FileName) then break
+ end;
+
+ glReadPixels(0, 0, ScreenW, ScreenH, GL_RGBA, GL_UNSIGNED_BYTE, @PrintScreenData[0]);
+ Bitmap := TBitmap.Create;
+ Bitmap.Width := ScreenW;
+ Bitmap.Height := ScreenH;
+
+ for Y := 0 to ScreenH-1 do
+ for X := 0 to ScreenW-1 do
+ Bitmap.Canvas.Pixels[X, Y] := PrintScreenData[(ScreenH-1-Y) * ScreenW + X] and $00FFFFFF;
+
+ Jpeg := TJpegImage.Create;
+ Jpeg.Assign(Bitmap);
+ Bitmap.Free;
+ Jpeg.CompressionQuality := 95;//90;
+ Jpeg.SaveToFile(FileName);
+ Jpeg.Free;
+end;
+
+procedure TDisplay.ScreenShot;
+ var F : file;
+ FileInfo: BITMAPINFOHEADER;
+ FileHeader : BITMAPFILEHEADER;
+ pPicData:Pointer;
+ FileName: String;
+ Num: Integer;
+begin
+ //bilddatei Suchen
+ for Num := 1 to 9999 do begin
+ FileName := IntToStr(Num);
+ while Length(FileName) < 4 do FileName := '0' + FileName;
+ FileName := ScreenshotsPath + FileName + '.BMP';
+ if not FileExists(FileName) then break
+ end;
+
+ //Speicher für die Speicherung der Header-Informationen vorbereiten
+ ZeroMemory(@FileHeader, SizeOf(BITMAPFILEHEADER));
+ ZeroMemory(@FileInfo , SizeOf(BITMAPINFOHEADER));
+
+ //Initialisieren der Daten des Headers
+ FileHeader.bfType := 19778; //$4D42 = 'BM'
+ FileHeader.bfOffBits := SizeOf(BITMAPINFOHEADER)+SizeOf(BITMAPFILEHEADER);
+
+ //Schreiben der Bitmap-Informationen
+ FileInfo.biSize := SizeOf(BITMAPINFOHEADER);
+ FileInfo.biWidth := ScreenW;
+ FileInfo.biHeight := ScreenH;
+ FileInfo.biPlanes := 1;
+ FileInfo.biBitCount := 32;
+ FileInfo.biSizeImage := FileInfo.biWidth*FileInfo.biHeight*(FileInfo.biBitCount div 8);
+
+ //Größenangabe auch in den Header übernehmen
+ FileHeader.bfSize := FileHeader.bfOffBits + FileInfo.biSizeImage;
+
+ //Speicher für die Bilddaten reservieren
+ GetMem(pPicData, FileInfo.biSizeImage);
+ try
+ //Bilddaten von OpenGL anfordern (siehe oben)
+ glReadPixels(0, 0, ScreenW, ScreenH, GL_BGRA, GL_UNSIGNED_BYTE, pPicData);
+
+ //Und den ganzen Müll in die Datei schieben ;-)
+ //Moderne Leute nehmen dafür auch Streams ...
+ AssignFile(f, Filename);
+ Rewrite( f,1 );
+ try
+ BlockWrite(F, FileHeader, SizeOf(BITMAPFILEHEADER));
+ BlockWrite(F, FileInfo, SizeOf(BITMAPINFOHEADER));
+ BlockWrite(F, pPicData^, FileInfo.biSizeImage );
+ finally
+ CloseFile(f);
+ end;
+ finally
+ //Und den angeforderten Speicher wieder freigeben ...
+ FreeMem(pPicData, FileInfo.biSizeImage);
+ end;
+end;
+
+//------------
+// DrawDebugInformation - Procedure draw FPS and some other Informations on Screen
+//------------
+procedure TDisplay.DrawDebugInformation;
+var Ticks: Cardinal;
+begin
+ //Some White Background for information
+ glEnable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ glColor4f(1, 1, 1, 0.5);
+ glBegin(GL_QUADS);
+ glVertex2f(690, 44);
+ glVertex2f(690, 0);
+ glVertex2f(800, 0);
+ glVertex2f(800, 44);
+ glEnd;
+ glDisable(GL_BLEND);
+
+ //Set Font Specs
+ SetFontStyle(0);
+ SetFontSize(7);
+ SetFontItalic(False);
+ glColor4f(0, 0, 0, 1);
+
+ //Calculate FPS
+ Ticks := GetTickCount;
+ if (Ticks >= NextFPSSwap) then
+ begin
+ LastFPS := FPSCounter * 4;
+ FPSCounter := 0;
+ NextFPSSwap := Ticks + 250;
+ end;
+
+ Inc(FPSCounter);
+
+ //Draw Text
+
+ //FPS
+ SetFontPos(695, 0);
+ glPrint (PChar('FPS: ' + InttoStr(LastFPS)));
+
+ //RSpeed
+ SetFontPos(695, 13);
+ glPrint (PChar('RSpeed: ' + InttoStr(Round(1000 * TimeMid))));
+
+ //LastError
+ SetFontPos(695, 26);
+ glColor4f(1, 0, 0, 1);
+ glPrint (PChar(OSD_LastError));
+
+ glColor4f(1, 1, 1, 1);
+end;
+
+end.
diff --git a/Game/Code/Menu/UMenuButton.pas b/Game/Code/Menu/UMenuButton.pas
index f3b00830..af4f69ee 100644
--- a/Game/Code/Menu/UMenuButton.pas
+++ b/Game/Code/Menu/UMenuButton.pas
@@ -1,565 +1,572 @@
-unit UMenuButton;
-
-interface
-uses TextGL, UTexture, OpenGL12, UMenuText;
-
-type
- CButton = class of TButton;
- TButton = class
- protected
- SelectBool: Boolean;
-
- FadeProgress: Real;
- FadeLastTick: Cardinal;
-
- DeSelectW: Real;
- DeSelectH: Real;
- PosX: Real;
- PosY: Real;
-
- constructor Create(); overload;
-
- public
- Text: Array of TText;
- Texture: TTexture; // Button Screen position and size
- Texture2: TTexture; // second texture only used for fading full resolution covers
- //colorized hack
- Colorized: Boolean;
- DeSelectTexture: TTexture; // texture for colorized hack
-
- FadeTex: TTexture; //Texture for beautiful fading
- FadeTexPos: byte; //Pos of the FadeTexture (0: Top, 1: Left, 2: Bottom, 3: Right)
-// Texture2Blend: real; // blending factor for second texture (0=invisible, 1=visible)
- // now uses alpha
-
- DeselectType: integer; // not used yet
- Visible: boolean;
- //Reflection Mod
- Reflection: boolean;
- Reflectionspacing: Real;
- DeSelectReflectionspacing: Real;
-
- //Fade Mod
- Fade: Boolean;
- FadeText: Boolean;
-
- Selectable: boolean;
-
- //No of the Parent Collection, 0 if in no Collection
- Parent: Byte;
-
- SelectColR: real;
- SelectColG: real;
- SelectColB: real;
- SelectInt: real;
- SelectTInt: real;
- //Fade Mod
- SelectW: real;
- SelectH: real;
-
- DeselectColR: real;
- DeselectColG: real;
- DeselectColB: real;
- DeselectInt: real;
- DeselectTInt: real;
-
- procedure SetY(Value: real);
- procedure SetX(Value: real);
- procedure SetW(Value: real);
- procedure SetH(Value: real);
-
- procedure SetSelect(Value: Boolean); virtual;
- property X: real read PosX write SetX;
- property Y: real read PosY write SetY;
- property Z: real read Texture.z write Texture.z;
- property W: real read DeSelectW write SetW;
- property H: real read DeSelectH write SetH;
- property Selected: Boolean read SelectBool write SetSelect;
-
- procedure Draw; virtual;
-
- constructor Create(Textura: TTexture); overload;
- constructor Create(Textura, DSTexture: TTexture); overload;
- destructor Destroy; override;
- end;
-
-implementation
-uses UDrawTexture, SysUtils, windows;
-
-procedure TButton.SetX(Value: real);
-{var
- dx: real;
- T: integer; // text}
-begin
- {dY := Value - Texture.y;
-
- Texture.X := Value;
-
- for T := 0 to High(Text) do
- Text[T].X := Text[T].X + dY;}
-
- PosX := Value;
- if (FadeTex.TexNum = -1) then
- Texture.X := Value;
-
-end;
-
-procedure TButton.SetY(Value: real);
-{var
- dY: real;
- T: integer; // text}
-begin
- {dY := Value - PosY;
-
-
- for T := 0 to High(Text) do
- Text[T].Y := Text[T].Y + dY;}
-
- PosY := Value;
- if (FadeTex.TexNum = -1) then
- Texture.y := Value;
-end;
-
-procedure TButton.SetW(Value: real);
-begin
- if SelectW = DeSelectW then
- SelectW := Value;
-
- DeSelectW := Value;
-
- if Not Fade then
- begin
- if SelectBool then
- Texture.W := SelectW
- else
- Texture.W := DeSelectW;
- end;
-end;
-
-procedure TButton.SetH(Value: real);
-begin
- if SelectH = DeSelectH then
- SelectH := Value;
-
- DeSelectH := Value;
-
- if Not Fade then
- begin
- if SelectBool then
- Texture.H := SelectH
- else
- Texture.H := DeSelectH;
- end;
-end;
-
-procedure TButton.SetSelect(Value : Boolean);
-var
- T: integer;
-begin
- SelectBool := Value;
- if (Value) then begin
- Texture.ColR := SelectColR;
- Texture.ColG := SelectColG;
- Texture.ColB := SelectColB;
- Texture.Int := SelectInt;
-
- Texture2.ColR := SelectColR;
- Texture2.ColG := SelectColG;
- Texture2.ColB := SelectColB;
- Texture2.Int := SelectInt;
-
- for T := 0 to High(Text) do
- Text[T].Int := SelectTInt;
-
- //Fade Mod
- if Fade then
- begin
- if (FadeProgress <= 0) then
- FadeProgress := 0.125;
- end
- else
- begin
- Texture.W := SelectW;
- Texture.H := SelectH;
- end;
- end else begin
- Texture.ColR := DeselectColR;
- Texture.ColG := DeselectColG;
- Texture.ColB := DeselectColB;
- Texture.Int := DeselectInt;
-
- Texture2.ColR := DeselectColR;
- Texture2.ColG := DeselectColG;
- Texture2.ColB := DeselectColB;
- Texture2.Int := DeselectInt;
-
- for T := 0 to High(Text) do
- Text[T].Int := DeselectTInt;
-
- //Fade Mod
- if Fade then
- begin
- if (FadeProgress >= 1) then
- FadeProgress := 0.875;
- end
- else
- begin
- Texture.W := DeSelectW;
- Texture.H := DeSelectH;
- end;
- end;
-end;
-
-constructor TButton.Create();
-begin
- inherited Create;
- // We initialize all to 0, nil or false
- Visible := true;
- SelectBool := false;
- DeselectType := 0;
- Selectable := true;
- //Reflection Mod
- Reflection := true;
-
- //colorized hack
- Colorized:=False;
-
- // Default
-// SelectInt := 1;
-// DeselectInt := 0.5;
-
-{ SelectColR := 0.5;
- SelectColG := 0.75;
- SelectColB := 0;
- SelectInt := 1;
- SelectTInt := 1;
-
- DeselectColR := 1;
- DeselectColG := 1;
- DeselectColB := 1;
- DeselectInt := 0.5;
- DeselectTInt := 1;}
-
- SelectColR := 1;
- SelectColG := 1;
- SelectColB := 1;
- SelectInt := 1;
- SelectTInt := 1;
-
- DeselectColR := 1;
- DeselectColG := 1;
- DeselectColB := 1;
- DeselectInt := 0.5;
- DeselectTInt := 1;
-
- FadeTex.TexNum := -1;
-
- FadeProgress := 0;
- Fade := False;
- FadeText := False;
- SelectW := DeSelectW;
- SelectH := DeSelectH;
-
- PosX := 0;
- PosY := 0;
-
- Parent := 0;
-end;
-
-// ***** Public methods ****** //
-
-procedure TButton.Draw;
-var
- T: integer;
- Tick: Cardinal;
- Spacing: Real;
-begin
- if Visible then begin
- //Fade Mod
- T:=0;
- if Fade then
- begin
- if (FadeProgress < 1) and (FadeProgress > 0) then
- begin
- Tick := GetTickCount div 16;
- if (Tick <> FadeLastTick) then
- begin
- FadeLastTick := Tick;
- if SelectBool then
- FadeProgress := FadeProgress + 0.125
- else
- FadeProgress := FadeProgress - 0.125;
-
- if (FadeText) then
- begin
- For T := 0 to high(Text) do
- begin
- Text[T].MoveX := (SelectW - DeSelectW) * FadeProgress;
- Text[T].MoveY := (SelectH - DeSelectH) * FadeProgress;
- end;
- end;
- end;
- end;
- //Method without Fade Texture
- if (FadeTex.TexNum = -1) then
- begin
- Texture.W := DeSelectW + (SelectW - DeSelectW) * FadeProgress;
- Texture.H := DeSelectH + (SelectH - DeSelectH) * FadeProgress;
- DeselectTexture.W := Texture.W;
- DeselectTexture.H := Texture.H;
- end
- else //method with Fade Texture
- begin
- Texture.W := DeSelectW;
- Texture.H := DeSelectH;
- DeselectTexture.W := Texture.W;
- DeselectTexture.H := Texture.H;
-
- FadeTex.ColR := Texture.ColR;
- FadeTex.ColG := Texture.ColG;
- FadeTex.ColB := Texture.ColB;
- FadeTex.Int := Texture.Int;
-
- FadeTex.Z := Texture.Z;
-
- FadeTex.Alpha := Texture.Alpha;
- FadeTex.TexX1 := 0;
- FadeTex.TexX2 := 1;
- FadeTex.TexY1 := 0;
- FadeTex.TexY2 := 1;
-
- Case FadeTexPos of
- 0: //FadeTex on Top
- begin
- //Standard Texture
- Texture.X := PosX;
- Texture.Y := PosY + (SelectH - DeSelectH) * FadeProgress;
- DeselectTexture.X := Texture.X;
- DeselectTexture.Y := Texture.Y;
- //Fade Tex
- FadeTex.X := PosX;
- FadeTex.Y := PosY;
- FadeTex.W := Texture.W;
- FadeTex.H := (SelectH - DeSelectH) * FadeProgress;
- FadeTex.ScaleW := Texture.ScaleW;
- //Some Hack that Fixes a little Space between both Textures
- FadeTex.TexY2 := 0.9;
- end;
- 1: //FadeTex on Left
- begin
- //Standard Texture
- Texture.X := PosX + (SelectW - DeSelectW) * FadeProgress;
- Texture.Y := PosY;
- DeselectTexture.X := Texture.X;
- DeselectTexture.Y := Texture.Y;
- //Fade Tex
- FadeTex.X := PosX;
- FadeTex.Y := PosY;
- FadeTex.H := Texture.H;
- FadeTex.W := (SelectW - DeSelectW) * FadeProgress;
- FadeTex.ScaleH := Texture.ScaleH;
- //Some Hack that Fixes a little Space between both Textures
- FadeTex.TexX2 := 0.9;
- end;
- 2: //FadeTex on Bottom
- begin
- //Standard Texture
- Texture.X := PosX;
- Texture.Y := PosY;
- DeselectTexture.X := Texture.X;
- DeselectTexture.Y := Texture.Y;
- //Fade Tex
- FadeTex.X := PosX;
- FadeTex.Y := PosY + (SelectH - DeSelectH) * FadeProgress;;
- FadeTex.W := Texture.W;
- FadeTex.H := (SelectH - DeSelectH) * FadeProgress;
- FadeTex.ScaleW := Texture.ScaleW;
- //Some Hack that Fixes a little Space between both Textures
- FadeTex.TexY1 := 0.1;
- end;
- 3: //FadeTex on Right
- begin
- //Standard Texture
- Texture.X := PosX;
- Texture.Y := PosY;
- DeselectTexture.X := Texture.X;
- DeselectTexture.Y := Texture.Y;
- //Fade Tex
- FadeTex.X := PosX + (SelectW - DeSelectW) * FadeProgress;
- FadeTex.Y := PosY;
- FadeTex.H := Texture.H;
- FadeTex.W := (SelectW - DeSelectW) * FadeProgress;
- FadeTex.ScaleH := Texture.ScaleH;
- //Some Hack that Fixes a little Space between both Textures
- FadeTex.TexX1 := 0.1;
- end;
- end;
- end;
- end
- else if (FadeText) then
- begin
- Text[T].MoveX := (SelectW - DeSelectW);
- Text[T].MoveY := (SelectH - DeSelectH);
- end;
-
- if SelectBool or (FadeProgress > 0) or not Colorized then
- DrawTexture(Texture)
- else
- DrawTexture(DeselectTexture);
-
- //Draw FadeTex
- if (FadeTex.TexNum <> -1) then
- DrawTexture(FadeTex);
-
- if Texture2.Alpha > 0 then begin
- Texture2.ScaleW := Texture.ScaleW;
- Texture2.ScaleH := Texture.ScaleH;
-
- Texture2.X := Texture.X;
- Texture2.Y := Texture.Y;
- Texture2.W := Texture.W;
- Texture2.H := Texture.H;
-
- Texture2.ColR := Texture.ColR;
- Texture2.ColG := Texture.ColG;
- Texture2.ColB := Texture.ColB;
- Texture2.Int := Texture.Int;
-
- Texture2.Z := Texture.Z;
-
- DrawTexture(Texture2);
- end;
-
- //Reflection Mod
- if (Reflection) then // Draw Reflections
- begin
- if (FadeProgress <> 0) AND (FadeProgress <> 1) then
- begin
- Spacing := DeSelectReflectionspacing - (DeSelectReflectionspacing - Reflectionspacing) * FadeProgress;
- end
- else if SelectBool then
- Spacing := Reflectionspacing
- else
- Spacing := DeSelectReflectionspacing;
-
- if SelectBool or not Colorized then
- with Texture do
- begin
- //Bind Tex and GL Attributes
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
-
- glDepthRange(0, 10);
- glDepthFunc(GL_LEQUAL);
- glEnable(GL_DEPTH_TEST);
-
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, TexNum);
-
- //Draw
- glBegin(GL_QUADS);//Top Left
- glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
- glTexCoord2f(TexX1*TexW, TexY2*TexH);
- glVertex3f(x, y+h*scaleH+ Spacing, z);
-
- //Bottom Left
- glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
- glTexCoord2f(TexX1*TexW, TexY1+TexH*0.5);
- glVertex3f(x, y+h*scaleH + h*scaleH/2 + Spacing, z);
-
-
- //Bottom Right
- glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
- glTexCoord2f(TexX2*TexW, TexY1+TexH*0.5);
- glVertex3f(x+w*scaleW, y+h*scaleH + h*scaleH/2 + Spacing, z);
-
- //Top Right
- glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
- glTexCoord2f(TexX2*TexW, TexY2*TexH);
- glVertex3f(x+w*scaleW, y+h*scaleH + Spacing, z);
- glEnd;
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_BLEND);
- end else
- with DeselectTexture do
- begin
- //Bind Tex and GL Attributes
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
-
- glDepthRange(0, 10);
- glDepthFunc(GL_LEQUAL);
- glEnable(GL_DEPTH_TEST);
-
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, TexNum);
-
- //Draw
- glBegin(GL_QUADS);//Top Left
- glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
- glTexCoord2f(TexX1*TexW, TexY2*TexH);
- glVertex3f(x, y+h*scaleH+ Spacing, z);
-
- //Bottom Left
- glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
- glTexCoord2f(TexX1*TexW, TexY1+TexH*0.5);
- glVertex3f(x, y+h*scaleH + h*scaleH/2 + Spacing, z);
-
-
- //Bottom Right
- glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
- glTexCoord2f(TexX2*TexW, TexY1+TexH*0.5);
- glVertex3f(x+w*scaleW, y+h*scaleH + h*scaleH/2 + Spacing, z);
-
- //Top Right
- glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
- glTexCoord2f(TexX2*TexW, TexY2*TexH);
- glVertex3f(x+w*scaleW, y+h*scaleH + Spacing, z);
- glEnd;
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_BLEND);
- end;
- end;
-
- for T := 0 to High(Text) do begin
- Text[T].Draw;
- end;
- end;
-end;
-
-// ***** ****** //
-
-destructor TButton.Destroy;
-begin
- inherited;
-end;
-
-constructor TButton.Create(Textura: TTexture);
-begin
- Create();
- Texture := Textura;
- DeselectTexture:=Textura;
- Texture.ColR := 0;
- Texture.ColG := 0.5;
- Texture.ColB := 0;
- Texture.Int := 1;
- Colorized:=False;
-end;
-
-constructor TButton.Create(Textura, DSTexture: TTexture);
-begin
- Create();
- Texture := Textura;
- DeselectTexture := DSTexture;
- Texture.ColR := 1;
- Texture.ColG := 1;
- Texture.ColB := 1;
- Texture.Int := 1;
- Colorized:=True;
-end;
-
-end.
+unit UMenuButton;
+
+interface
+uses TextGL, UTexture, OpenGL12, UMenuText;
+
+type
+ CButton = class of TButton;
+ TButton = class
+ protected
+ SelectBool: Boolean;
+
+ FadeProgress: Real;
+ FadeLastTick: Cardinal;
+
+ DeSelectW: Real;
+ DeSelectH: Real;
+ PosX: Real;
+ PosY: Real;
+
+ constructor Create(); overload;
+
+ public
+ Text: Array of TText;
+ Texture: TTexture; // Button Screen position and size
+ Texture2: TTexture; // second texture only used for fading full resolution covers
+ //colorized hack
+ Colorized: Boolean;
+ DeSelectTexture: TTexture; // texture for colorized hack
+
+ FadeTex: TTexture; //Texture for beautiful fading
+ FadeTexPos: byte; //Pos of the FadeTexture (0: Top, 1: Left, 2: Bottom, 3: Right)
+// Texture2Blend: real; // blending factor for second texture (0=invisible, 1=visible)
+ // now uses alpha
+
+ DeselectType: integer; // not used yet
+ Visible: boolean;
+ //Reflection Mod
+ Reflection: boolean;
+ Reflectionspacing: Real;
+ DeSelectReflectionspacing: Real;
+
+ //Fade Mod
+ Fade: Boolean;
+ FadeText: Boolean;
+
+ Selectable: boolean;
+
+ //No of the Parent Collection, 0 if in no Collection
+ Parent: Byte;
+
+ SelectColR: real;
+ SelectColG: real;
+ SelectColB: real;
+ SelectInt: real;
+ SelectTInt: real;
+ //Fade Mod
+ SelectW: real;
+ SelectH: real;
+
+ DeselectColR: real;
+ DeselectColG: real;
+ DeselectColB: real;
+ DeselectInt: real;
+ DeselectTInt: real;
+
+ procedure SetY(Value: real);
+ procedure SetX(Value: real);
+ procedure SetW(Value: real);
+ procedure SetH(Value: real);
+
+ procedure SetSelect(Value: Boolean); virtual;
+ property X: real read PosX write SetX;
+ property Y: real read PosY write SetY;
+ property Z: real read Texture.z write Texture.z;
+ property W: real read DeSelectW write SetW;
+ property H: real read DeSelectH write SetH;
+ property Selected: Boolean read SelectBool write SetSelect;
+
+ procedure Draw; virtual;
+
+ constructor Create(Textura: TTexture); overload;
+ constructor Create(Textura, DSTexture: TTexture); overload;
+ destructor Destroy; override;
+ end;
+
+implementation
+
+uses SysUtils,
+ {$IFDEF win32}
+ windows,
+ {$ELSE}
+ lclintf,
+ {$ENDIF}
+ UDrawTexture;
+
+procedure TButton.SetX(Value: real);
+{var
+ dx: real;
+ T: integer; // text}
+begin
+ {dY := Value - Texture.y;
+
+ Texture.X := Value;
+
+ for T := 0 to High(Text) do
+ Text[T].X := Text[T].X + dY;}
+
+ PosX := Value;
+ if (FadeTex.TexNum = -1) then
+ Texture.X := Value;
+
+end;
+
+procedure TButton.SetY(Value: real);
+{var
+ dY: real;
+ T: integer; // text}
+begin
+ {dY := Value - PosY;
+
+
+ for T := 0 to High(Text) do
+ Text[T].Y := Text[T].Y + dY;}
+
+ PosY := Value;
+ if (FadeTex.TexNum = -1) then
+ Texture.y := Value;
+end;
+
+procedure TButton.SetW(Value: real);
+begin
+ if SelectW = DeSelectW then
+ SelectW := Value;
+
+ DeSelectW := Value;
+
+ if Not Fade then
+ begin
+ if SelectBool then
+ Texture.W := SelectW
+ else
+ Texture.W := DeSelectW;
+ end;
+end;
+
+procedure TButton.SetH(Value: real);
+begin
+ if SelectH = DeSelectH then
+ SelectH := Value;
+
+ DeSelectH := Value;
+
+ if Not Fade then
+ begin
+ if SelectBool then
+ Texture.H := SelectH
+ else
+ Texture.H := DeSelectH;
+ end;
+end;
+
+procedure TButton.SetSelect(Value : Boolean);
+var
+ T: integer;
+begin
+ SelectBool := Value;
+ if (Value) then begin
+ Texture.ColR := SelectColR;
+ Texture.ColG := SelectColG;
+ Texture.ColB := SelectColB;
+ Texture.Int := SelectInt;
+
+ Texture2.ColR := SelectColR;
+ Texture2.ColG := SelectColG;
+ Texture2.ColB := SelectColB;
+ Texture2.Int := SelectInt;
+
+ for T := 0 to High(Text) do
+ Text[T].Int := SelectTInt;
+
+ //Fade Mod
+ if Fade then
+ begin
+ if (FadeProgress <= 0) then
+ FadeProgress := 0.125;
+ end
+ else
+ begin
+ Texture.W := SelectW;
+ Texture.H := SelectH;
+ end;
+ end else begin
+ Texture.ColR := DeselectColR;
+ Texture.ColG := DeselectColG;
+ Texture.ColB := DeselectColB;
+ Texture.Int := DeselectInt;
+
+ Texture2.ColR := DeselectColR;
+ Texture2.ColG := DeselectColG;
+ Texture2.ColB := DeselectColB;
+ Texture2.Int := DeselectInt;
+
+ for T := 0 to High(Text) do
+ Text[T].Int := DeselectTInt;
+
+ //Fade Mod
+ if Fade then
+ begin
+ if (FadeProgress >= 1) then
+ FadeProgress := 0.875;
+ end
+ else
+ begin
+ Texture.W := DeSelectW;
+ Texture.H := DeSelectH;
+ end;
+ end;
+end;
+
+constructor TButton.Create();
+begin
+ inherited Create;
+ // We initialize all to 0, nil or false
+ Visible := true;
+ SelectBool := false;
+ DeselectType := 0;
+ Selectable := true;
+ //Reflection Mod
+ Reflection := true;
+
+ //colorized hack
+ Colorized:=False;
+
+ // Default
+// SelectInt := 1;
+// DeselectInt := 0.5;
+
+{ SelectColR := 0.5;
+ SelectColG := 0.75;
+ SelectColB := 0;
+ SelectInt := 1;
+ SelectTInt := 1;
+
+ DeselectColR := 1;
+ DeselectColG := 1;
+ DeselectColB := 1;
+ DeselectInt := 0.5;
+ DeselectTInt := 1;}
+
+ SelectColR := 1;
+ SelectColG := 1;
+ SelectColB := 1;
+ SelectInt := 1;
+ SelectTInt := 1;
+
+ DeselectColR := 1;
+ DeselectColG := 1;
+ DeselectColB := 1;
+ DeselectInt := 0.5;
+ DeselectTInt := 1;
+
+ FadeTex.TexNum := -1;
+
+ FadeProgress := 0;
+ Fade := False;
+ FadeText := False;
+ SelectW := DeSelectW;
+ SelectH := DeSelectH;
+
+ PosX := 0;
+ PosY := 0;
+
+ Parent := 0;
+end;
+
+// ***** Public methods ****** //
+
+procedure TButton.Draw;
+var
+ T: integer;
+ Tick: Cardinal;
+ Spacing: Real;
+begin
+ if Visible then begin
+ //Fade Mod
+ T:=0;
+ if Fade then
+ begin
+ if (FadeProgress < 1) and (FadeProgress > 0) then
+ begin
+ Tick := GetTickCount div 16;
+ if (Tick <> FadeLastTick) then
+ begin
+ FadeLastTick := Tick;
+ if SelectBool then
+ FadeProgress := FadeProgress + 0.125
+ else
+ FadeProgress := FadeProgress - 0.125;
+
+ if (FadeText) then
+ begin
+ For T := 0 to high(Text) do
+ begin
+ Text[T].MoveX := (SelectW - DeSelectW) * FadeProgress;
+ Text[T].MoveY := (SelectH - DeSelectH) * FadeProgress;
+ end;
+ end;
+ end;
+ end;
+ //Method without Fade Texture
+ if (FadeTex.TexNum = -1) then
+ begin
+ Texture.W := DeSelectW + (SelectW - DeSelectW) * FadeProgress;
+ Texture.H := DeSelectH + (SelectH - DeSelectH) * FadeProgress;
+ DeselectTexture.W := Texture.W;
+ DeselectTexture.H := Texture.H;
+ end
+ else //method with Fade Texture
+ begin
+ Texture.W := DeSelectW;
+ Texture.H := DeSelectH;
+ DeselectTexture.W := Texture.W;
+ DeselectTexture.H := Texture.H;
+
+ FadeTex.ColR := Texture.ColR;
+ FadeTex.ColG := Texture.ColG;
+ FadeTex.ColB := Texture.ColB;
+ FadeTex.Int := Texture.Int;
+
+ FadeTex.Z := Texture.Z;
+
+ FadeTex.Alpha := Texture.Alpha;
+ FadeTex.TexX1 := 0;
+ FadeTex.TexX2 := 1;
+ FadeTex.TexY1 := 0;
+ FadeTex.TexY2 := 1;
+
+ Case FadeTexPos of
+ 0: //FadeTex on Top
+ begin
+ //Standard Texture
+ Texture.X := PosX;
+ Texture.Y := PosY + (SelectH - DeSelectH) * FadeProgress;
+ DeselectTexture.X := Texture.X;
+ DeselectTexture.Y := Texture.Y;
+ //Fade Tex
+ FadeTex.X := PosX;
+ FadeTex.Y := PosY;
+ FadeTex.W := Texture.W;
+ FadeTex.H := (SelectH - DeSelectH) * FadeProgress;
+ FadeTex.ScaleW := Texture.ScaleW;
+ //Some Hack that Fixes a little Space between both Textures
+ FadeTex.TexY2 := 0.9;
+ end;
+ 1: //FadeTex on Left
+ begin
+ //Standard Texture
+ Texture.X := PosX + (SelectW - DeSelectW) * FadeProgress;
+ Texture.Y := PosY;
+ DeselectTexture.X := Texture.X;
+ DeselectTexture.Y := Texture.Y;
+ //Fade Tex
+ FadeTex.X := PosX;
+ FadeTex.Y := PosY;
+ FadeTex.H := Texture.H;
+ FadeTex.W := (SelectW - DeSelectW) * FadeProgress;
+ FadeTex.ScaleH := Texture.ScaleH;
+ //Some Hack that Fixes a little Space between both Textures
+ FadeTex.TexX2 := 0.9;
+ end;
+ 2: //FadeTex on Bottom
+ begin
+ //Standard Texture
+ Texture.X := PosX;
+ Texture.Y := PosY;
+ DeselectTexture.X := Texture.X;
+ DeselectTexture.Y := Texture.Y;
+ //Fade Tex
+ FadeTex.X := PosX;
+ FadeTex.Y := PosY + (SelectH - DeSelectH) * FadeProgress;;
+ FadeTex.W := Texture.W;
+ FadeTex.H := (SelectH - DeSelectH) * FadeProgress;
+ FadeTex.ScaleW := Texture.ScaleW;
+ //Some Hack that Fixes a little Space between both Textures
+ FadeTex.TexY1 := 0.1;
+ end;
+ 3: //FadeTex on Right
+ begin
+ //Standard Texture
+ Texture.X := PosX;
+ Texture.Y := PosY;
+ DeselectTexture.X := Texture.X;
+ DeselectTexture.Y := Texture.Y;
+ //Fade Tex
+ FadeTex.X := PosX + (SelectW - DeSelectW) * FadeProgress;
+ FadeTex.Y := PosY;
+ FadeTex.H := Texture.H;
+ FadeTex.W := (SelectW - DeSelectW) * FadeProgress;
+ FadeTex.ScaleH := Texture.ScaleH;
+ //Some Hack that Fixes a little Space between both Textures
+ FadeTex.TexX1 := 0.1;
+ end;
+ end;
+ end;
+ end
+ else if (FadeText) then
+ begin
+ Text[T].MoveX := (SelectW - DeSelectW);
+ Text[T].MoveY := (SelectH - DeSelectH);
+ end;
+
+ if SelectBool or (FadeProgress > 0) or not Colorized then
+ DrawTexture(Texture)
+ else
+ DrawTexture(DeselectTexture);
+
+ //Draw FadeTex
+ if (FadeTex.TexNum <> -1) then
+ DrawTexture(FadeTex);
+
+ if Texture2.Alpha > 0 then begin
+ Texture2.ScaleW := Texture.ScaleW;
+ Texture2.ScaleH := Texture.ScaleH;
+
+ Texture2.X := Texture.X;
+ Texture2.Y := Texture.Y;
+ Texture2.W := Texture.W;
+ Texture2.H := Texture.H;
+
+ Texture2.ColR := Texture.ColR;
+ Texture2.ColG := Texture.ColG;
+ Texture2.ColB := Texture.ColB;
+ Texture2.Int := Texture.Int;
+
+ Texture2.Z := Texture.Z;
+
+ DrawTexture(Texture2);
+ end;
+
+ //Reflection Mod
+ if (Reflection) then // Draw Reflections
+ begin
+ if (FadeProgress <> 0) AND (FadeProgress <> 1) then
+ begin
+ Spacing := DeSelectReflectionspacing - (DeSelectReflectionspacing - Reflectionspacing) * FadeProgress;
+ end
+ else if SelectBool then
+ Spacing := Reflectionspacing
+ else
+ Spacing := DeSelectReflectionspacing;
+
+ if SelectBool or not Colorized then
+ with Texture do
+ begin
+ //Bind Tex and GL Attributes
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+
+ glDepthRange(0, 10);
+ glDepthFunc(GL_LEQUAL);
+ glEnable(GL_DEPTH_TEST);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, TexNum);
+
+ //Draw
+ glBegin(GL_QUADS);//Top Left
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
+ glTexCoord2f(TexX1*TexW, TexY2*TexH);
+ glVertex3f(x, y+h*scaleH+ Spacing, z);
+
+ //Bottom Left
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
+ glTexCoord2f(TexX1*TexW, TexY1+TexH*0.5);
+ glVertex3f(x, y+h*scaleH + h*scaleH/2 + Spacing, z);
+
+
+ //Bottom Right
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
+ glTexCoord2f(TexX2*TexW, TexY1+TexH*0.5);
+ glVertex3f(x+w*scaleW, y+h*scaleH + h*scaleH/2 + Spacing, z);
+
+ //Top Right
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
+ glTexCoord2f(TexX2*TexW, TexY2*TexH);
+ glVertex3f(x+w*scaleW, y+h*scaleH + Spacing, z);
+ glEnd;
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_BLEND);
+ end else
+ with DeselectTexture do
+ begin
+ //Bind Tex and GL Attributes
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+
+ glDepthRange(0, 10);
+ glDepthFunc(GL_LEQUAL);
+ glEnable(GL_DEPTH_TEST);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, TexNum);
+
+ //Draw
+ glBegin(GL_QUADS);//Top Left
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
+ glTexCoord2f(TexX1*TexW, TexY2*TexH);
+ glVertex3f(x, y+h*scaleH+ Spacing, z);
+
+ //Bottom Left
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
+ glTexCoord2f(TexX1*TexW, TexY1+TexH*0.5);
+ glVertex3f(x, y+h*scaleH + h*scaleH/2 + Spacing, z);
+
+
+ //Bottom Right
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, 0);
+ glTexCoord2f(TexX2*TexW, TexY1+TexH*0.5);
+ glVertex3f(x+w*scaleW, y+h*scaleH + h*scaleH/2 + Spacing, z);
+
+ //Top Right
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3);
+ glTexCoord2f(TexX2*TexW, TexY2*TexH);
+ glVertex3f(x+w*scaleW, y+h*scaleH + Spacing, z);
+ glEnd;
+
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_BLEND);
+ end;
+ end;
+
+ for T := 0 to High(Text) do begin
+ Text[T].Draw;
+ end;
+ end;
+end;
+
+// ***** ****** //
+
+destructor TButton.Destroy;
+begin
+ inherited;
+end;
+
+constructor TButton.Create(Textura: TTexture);
+begin
+ Create();
+ Texture := Textura;
+ DeselectTexture:=Textura;
+ Texture.ColR := 0;
+ Texture.ColG := 0.5;
+ Texture.ColB := 0;
+ Texture.Int := 1;
+ Colorized:=False;
+end;
+
+constructor TButton.Create(Textura, DSTexture: TTexture);
+begin
+ Create();
+ Texture := Textura;
+ DeselectTexture := DSTexture;
+ Texture.ColR := 1;
+ Texture.ColG := 1;
+ Texture.ColB := 1;
+ Texture.Int := 1;
+ Colorized:=True;
+end;
+
+end.
diff --git a/Game/Code/Menu/UMenuText.pas b/Game/Code/Menu/UMenuText.pas
index cba237b8..d1c8b7b1 100644
--- a/Game/Code/Menu/UMenuText.pas
+++ b/Game/Code/Menu/UMenuText.pas
@@ -1,329 +1,339 @@
-unit UMenuText;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-uses TextGL, UTexture, OpenGL12, SysUtils;
-
-type
- TText = class
- private
- SelectBool: boolean;
- TextString: String;
- TextTiles: Array of String;
-
- STicks: Cardinal;
- SelectBlink: Boolean;
- public
- X: real;
- Y: real;
- MoveX: real; //Some Modifier for X - Position that don't Affect the Real Y
- MoveY: real; //Some Modifier for Y - Position that don't Affect the Real Y
- W: real; // if text is wider than W then it is breaked
-// H: real;
- Size: real;
- ColR: real;
- ColG: real;
- ColB: real;
- Alpha: real;
- Int: real;
- Style: integer;
- Visible: boolean;
- Align: integer; // 0 = left, 1 = center, 2 = right
-
- procedure SetSelect(Value: Boolean);
- property Selected: Boolean read SelectBool write SetSelect;
-
- procedure SetText(Value: String);
- property Text: String read TextString write SetText;
-
- procedure DeleteLastL; //Procedure to Delete Last Letter
-
- procedure Draw;
- constructor Create; overload;
- constructor Create(X, Y: real; Tekst: string); overload;
- constructor Create(ParX, ParY, ParW: real; ParStyle: integer; ParSize, ParColR, ParColG, ParColB: real; ParAlign: integer; ParTekst: string); overload;
- end;
-
-implementation
-uses UGraphic, StrUtils, Windows;
-
-procedure TText.SetSelect(Value: Boolean);
-begin
- SelectBool := Value;
-
- //Set Cursor Visible
- SelectBlink := True;
- STicks := GettickCount div 550;
-end;
-
-procedure TText.SetText(Value: String);
-var
- NextPos: Cardinal; //NextPos of a Space etc.
- LastPos: Cardinal; //LastPos "
- LastBreak: Cardinal; //Last Break
- isBreak: Boolean; //True if the Break is not Caused because the Text is out of the area
- FirstWord: Word; //Is First Word after Break?
- Len: Word; //Length of the Tiles Array
- Function Smallest(const A, B: Cardinal):Cardinal;
- begin
- if (A < B) then
- Result := A
- else
- Result := B;
- end;
-
- Function GetNextPos: Boolean;
- var
- T1, T2, T3: Cardinal;
- begin
- LastPos := NextPos;
-
- //Next Space (If Width is given)
- if (W > 0) then
- T1 := PosEx(' ', Value, LastPos + 1)
- else T1 := Length(Value);
-
- {//Next -
- T2 := PosEx('-', Value, LastPos + 1);}
-
- //Next Break
- T3 := PosEx('\n', Value, LastPos + 1);
-
- if T1 = 0 then
- T1 := Length(Value);
- {if T2 = 0 then
- T2 := Length(Value); }
- if T3 = 0 then
- T3 := Length(Value);
-
- //Get Nearest Pos
- NextPos := Smallest(T1, T3{Smallest(T2, T3)});
-
- if (LastPos = Length(Value)) then
- NextPos := 0;
-
- isBreak := (NextPos = T3) AND (NextPos <> Length(Value));
- Result := (NextPos <> 0);
- end;
- procedure AddBreak(const From, bTo: Cardinal);
- begin
- if (isBreak) OR (bTo - From >= 1) then
- begin
- Inc(Len);
- SetLength (TextTiles, Len);
- TextTiles[Len-1] := Trim(Copy(Value, From, bTo - From));
-
- if isBreak then
- LastBreak := bTo + 2
- else
- LastBreak := bTo + 1;
- FirstWord := 0;
- end;
- end;
-begin
- //Set TExtstring
- TextString := Value;
-
- //Set Cursor Visible
- SelectBlink := True;
- STicks := GettickCount div 550;
-
- //Exit if there is no Need to Create Tiles
- If (W <= 0) and (Pos('\n', Value) = 0) then
- begin
- SetLength (TextTiles, 1);
- TextTiles[0] := Value;
- Exit;
- end;
-
- //Create Tiles
- //Reset Text Array
- SetLength (TextTiles, 0);
- Len := 0;
-
- //Reset Counter Vars
- LastPos := 1;
- NextPos := 1;
- LastBreak := 1;
- FirstWord := 1;
-
-
- if (W > 0) then
- begin
- //Set Font Propertys
- SetFontStyle(Style);
- SetFontSize(Size);
- end;
-
- //go Through Text
- While (GetNextPos) do
- begin
- //Break in Text
- if isBreak then
- begin
- //Look for Break before the Break
- if (glTextWidth(PChar(Copy(Value, LastBreak, NextPos - LastBreak + 1))) > W) AND (NextPos-LastPos > 1) then
- begin
- isBreak := False;
- //Not the First word after Break, so we don't have to break within a word
- if (FirstWord > 1) then
- begin
- //Add Break before actual Position, because there the Text fits the Area
- AddBreak(LastBreak, LastPos);
- end
- else //First Word after Break Break within the Word
- begin
- //ToDo
- //AddBreak(LastBreak, LastBreak + 155);
- end;
- end;
-
- isBreak := True;
- //Add Break from Text
- AddBreak(LastBreak, NextPos);
- end
- //Text comes out of the Text Area -> CreateBreak
- else if (glTextWidth(PChar(Copy(Value, LastBreak, NextPos - LastBreak + 1))) > W) then
- begin
- //Not the First word after Break, so we don't have to break within a word
- if (FirstWord > 1) then
- begin
- //Add Break before actual Position, because there the Text fits the Area
- AddBreak(LastBreak, LastPos);
- end
- else //First Word after Break -> Break within the Word
- begin
- //ToDo
- //AddBreak(LastBreak, LastBreak + 155);
- end;
- end;
- //end;
- Inc(FirstWord)
- end;
- //Add Ending
- AddBreak(LastBreak, Length(Value)+1);
-end;
-
-Procedure TText.DeleteLastL;
-var
- S: String;
- L: Integer;
-begin
- S := TextString;
- L := Length(S);
- if (L > 0) then
- SetLength(S, L-1);
-
- SetText(S);
-end;
-
-procedure TText.Draw;
-var
- X2, Y2: real;
- Text2: string;
- I: Integer;
-begin
- if Visible then begin
- SetFontStyle(Style);
- SetFontSize(Size);
- SetFontItalic(False);
- glColor4f(ColR*Int, ColG*Int, ColB*Int, Alpha);
-
- //If Selected Set Blink...
- if SelectBool then
- begin
- I := Gettickcount div 550;
- if I <> STicks then
- begin //Change Visability
- STicks := I;
- SelectBlink := Not SelectBlink;
- end;
- end;
-
- {if (False) then //No Width set Draw as one Long String
- begin
- if not (SelectBool AND SelectBlink) then
- Text2 := Text
- else
- Text2 := Text + '|';
-
- case Align of
- 0: X2 := X;
- 1: X2 := X - glTextWidth(pchar(Text2))/2;
- 2: X2 := X - glTextWidth(pchar(Text2));
- end;
-
- SetFontPos(X2, Y);
- glPrint(PChar(Text2));
- SetFontStyle(0); // reset to default
- end
- else
- begin}
- //Now Use allways:
- //Draw Text as Many Strings
- Y2 := Y + MoveY;
- for I := 0 to high(TextTiles) do
- begin
- if (not (SelectBool AND SelectBlink)) OR (I <> high(TextTiles)) then
- Text2 := TextTiles[I]
- else
- Text2 := TextTiles[I] + '|';
-
- case Align of
- 0: X2 := X + MoveX;
- 1: X2 := X + MoveX - glTextWidth(pchar(Text2))/2;
- 2: X2 := X + MoveX - glTextWidth(pchar(Text2));
- end;
-
- SetFontPos(X2, Y2);
- glPrint(PChar(Text2));
-
- {if Size >= 10 then
- Y2 := Y2 + Size * 2.8
- else}
- if (Style = 1) then
- Y2 := Y2 + Size * 2.8
- else
- Y2 := Y2 + Size * 2.15;
- end;
- SetFontStyle(0); // reset to default
-
- //end;
- end;
-end;
-
-constructor TText.Create;
-begin
- Create(0, 0, '');
-end;
-
-constructor TText.Create(X, Y: real; Tekst: string);
-begin
- Create(X, Y, 0, 0, 10, 0, 0, 0, 0, Tekst);
-end;
-
-constructor TText.Create(ParX, ParY, ParW: real; ParStyle: integer; ParSize, ParColR, ParColG, ParColB: real; ParAlign: integer; ParTekst: string);
-begin
- inherited Create;
- Alpha := 1;
- X := ParX;
- Y := ParY;
- W := ParW;
- Style := ParStyle;
- Size := ParSize;
- Text := ParTekst;
- ColR := ParColR;
- ColG := ParColG;
- ColB := ParColB;
- Int := 1;
- Align := ParAlign;
- SelectBool := false;
- Visible := true;
-end;
-
-
-end.
+unit UMenuText;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+uses TextGL,
+ UTexture,
+ OpenGL12,
+ SysUtils;
+
+type
+ TText = class
+ private
+ SelectBool: boolean;
+ TextString: String;
+ TextTiles: Array of String;
+
+ STicks: Cardinal;
+ SelectBlink: Boolean;
+ public
+ X: real;
+ Y: real;
+ MoveX: real; //Some Modifier for X - Position that don't Affect the Real Y
+ MoveY: real; //Some Modifier for Y - Position that don't Affect the Real Y
+ W: real; // if text is wider than W then it is breaked
+// H: real;
+ Size: real;
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ Alpha: real;
+ Int: real;
+ Style: integer;
+ Visible: boolean;
+ Align: integer; // 0 = left, 1 = center, 2 = right
+
+ procedure SetSelect(Value: Boolean);
+ property Selected: Boolean read SelectBool write SetSelect;
+
+ procedure SetText(Value: String);
+ property Text: String read TextString write SetText;
+
+ procedure DeleteLastL; //Procedure to Delete Last Letter
+
+ procedure Draw;
+ constructor Create; overload;
+ constructor Create(X, Y: real; Tekst: string); overload;
+ constructor Create(ParX, ParY, ParW: real; ParStyle: integer; ParSize, ParColR, ParColG, ParColB: real; ParAlign: integer; ParTekst: string); overload;
+ end;
+
+implementation
+
+uses UGraphic,
+ {$IFDEF win32}
+ windows,
+ {$ELSE}
+ lclintf,
+ {$ENDIF}
+ StrUtils;
+
+procedure TText.SetSelect(Value: Boolean);
+begin
+ SelectBool := Value;
+
+ //Set Cursor Visible
+ SelectBlink := True;
+ STicks := GettickCount div 550;
+end;
+
+procedure TText.SetText(Value: String);
+var
+ NextPos: Cardinal; //NextPos of a Space etc.
+ LastPos: Cardinal; //LastPos "
+ LastBreak: Cardinal; //Last Break
+ isBreak: Boolean; //True if the Break is not Caused because the Text is out of the area
+ FirstWord: Word; //Is First Word after Break?
+ Len: Word; //Length of the Tiles Array
+ Function Smallest(const A, B: Cardinal):Cardinal;
+ begin
+ if (A < B) then
+ Result := A
+ else
+ Result := B;
+ end;
+
+ Function GetNextPos: Boolean;
+ var
+ T1, T2, T3: Cardinal;
+ begin
+ LastPos := NextPos;
+
+ //Next Space (If Width is given)
+ if (W > 0) then
+ T1 := PosEx(' ', Value, LastPos + 1)
+ else T1 := Length(Value);
+
+ {//Next -
+ T2 := PosEx('-', Value, LastPos + 1);}
+
+ //Next Break
+ T3 := PosEx('\n', Value, LastPos + 1);
+
+ if T1 = 0 then
+ T1 := Length(Value);
+ {if T2 = 0 then
+ T2 := Length(Value); }
+ if T3 = 0 then
+ T3 := Length(Value);
+
+ //Get Nearest Pos
+ NextPos := Smallest(T1, T3{Smallest(T2, T3)});
+
+ if (LastPos = Length(Value)) then
+ NextPos := 0;
+
+ isBreak := (NextPos = T3) AND (NextPos <> Length(Value));
+ Result := (NextPos <> 0);
+ end;
+ procedure AddBreak(const From, bTo: Cardinal);
+ begin
+ if (isBreak) OR (bTo - From >= 1) then
+ begin
+ Inc(Len);
+ SetLength (TextTiles, Len);
+ TextTiles[Len-1] := Trim(Copy(Value, From, bTo - From));
+
+ if isBreak then
+ LastBreak := bTo + 2
+ else
+ LastBreak := bTo + 1;
+ FirstWord := 0;
+ end;
+ end;
+begin
+ //Set TExtstring
+ TextString := Value;
+
+ //Set Cursor Visible
+ SelectBlink := True;
+ STicks := GettickCount div 550;
+
+ //Exit if there is no Need to Create Tiles
+ If (W <= 0) and (Pos('\n', Value) = 0) then
+ begin
+ SetLength (TextTiles, 1);
+ TextTiles[0] := Value;
+ Exit;
+ end;
+
+ //Create Tiles
+ //Reset Text Array
+ SetLength (TextTiles, 0);
+ Len := 0;
+
+ //Reset Counter Vars
+ LastPos := 1;
+ NextPos := 1;
+ LastBreak := 1;
+ FirstWord := 1;
+
+
+ if (W > 0) then
+ begin
+ //Set Font Propertys
+ SetFontStyle(Style);
+ SetFontSize(Size);
+ end;
+
+ //go Through Text
+ While (GetNextPos) do
+ begin
+ //Break in Text
+ if isBreak then
+ begin
+ //Look for Break before the Break
+ if (glTextWidth(PChar(Copy(Value, LastBreak, NextPos - LastBreak + 1))) > W) AND (NextPos-LastPos > 1) then
+ begin
+ isBreak := False;
+ //Not the First word after Break, so we don't have to break within a word
+ if (FirstWord > 1) then
+ begin
+ //Add Break before actual Position, because there the Text fits the Area
+ AddBreak(LastBreak, LastPos);
+ end
+ else //First Word after Break Break within the Word
+ begin
+ //ToDo
+ //AddBreak(LastBreak, LastBreak + 155);
+ end;
+ end;
+
+ isBreak := True;
+ //Add Break from Text
+ AddBreak(LastBreak, NextPos);
+ end
+ //Text comes out of the Text Area -> CreateBreak
+ else if (glTextWidth(PChar(Copy(Value, LastBreak, NextPos - LastBreak + 1))) > W) then
+ begin
+ //Not the First word after Break, so we don't have to break within a word
+ if (FirstWord > 1) then
+ begin
+ //Add Break before actual Position, because there the Text fits the Area
+ AddBreak(LastBreak, LastPos);
+ end
+ else //First Word after Break -> Break within the Word
+ begin
+ //ToDo
+ //AddBreak(LastBreak, LastBreak + 155);
+ end;
+ end;
+ //end;
+ Inc(FirstWord)
+ end;
+ //Add Ending
+ AddBreak(LastBreak, Length(Value)+1);
+end;
+
+Procedure TText.DeleteLastL;
+var
+ S: String;
+ L: Integer;
+begin
+ S := TextString;
+ L := Length(S);
+ if (L > 0) then
+ SetLength(S, L-1);
+
+ SetText(S);
+end;
+
+procedure TText.Draw;
+var
+ X2, Y2: real;
+ Text2: string;
+ I: Integer;
+begin
+ if Visible then begin
+ SetFontStyle(Style);
+ SetFontSize(Size);
+ SetFontItalic(False);
+ glColor4f(ColR*Int, ColG*Int, ColB*Int, Alpha);
+
+ //If Selected Set Blink...
+ if SelectBool then
+ begin
+ I := Gettickcount div 550;
+ if I <> STicks then
+ begin //Change Visability
+ STicks := I;
+ SelectBlink := Not SelectBlink;
+ end;
+ end;
+
+ {if (False) then //No Width set Draw as one Long String
+ begin
+ if not (SelectBool AND SelectBlink) then
+ Text2 := Text
+ else
+ Text2 := Text + '|';
+
+ case Align of
+ 0: X2 := X;
+ 1: X2 := X - glTextWidth(pchar(Text2))/2;
+ 2: X2 := X - glTextWidth(pchar(Text2));
+ end;
+
+ SetFontPos(X2, Y);
+ glPrint(PChar(Text2));
+ SetFontStyle(0); // reset to default
+ end
+ else
+ begin}
+ //Now Use allways:
+ //Draw Text as Many Strings
+ Y2 := Y + MoveY;
+ for I := 0 to high(TextTiles) do
+ begin
+ if (not (SelectBool AND SelectBlink)) OR (I <> high(TextTiles)) then
+ Text2 := TextTiles[I]
+ else
+ Text2 := TextTiles[I] + '|';
+
+ case Align of
+ 0: X2 := X + MoveX;
+ 1: X2 := X + MoveX - glTextWidth(pchar(Text2))/2;
+ 2: X2 := X + MoveX - glTextWidth(pchar(Text2));
+ end;
+
+ SetFontPos(X2, Y2);
+ glPrint(PChar(Text2));
+
+ {if Size >= 10 then
+ Y2 := Y2 + Size * 2.8
+ else}
+ if (Style = 1) then
+ Y2 := Y2 + Size * 2.8
+ else
+ Y2 := Y2 + Size * 2.15;
+ end;
+ SetFontStyle(0); // reset to default
+
+ //end;
+ end;
+end;
+
+constructor TText.Create;
+begin
+ Create(0, 0, '');
+end;
+
+constructor TText.Create(X, Y: real; Tekst: string);
+begin
+ Create(X, Y, 0, 0, 10, 0, 0, 0, 0, Tekst);
+end;
+
+constructor TText.Create(ParX, ParY, ParW: real; ParStyle: integer; ParSize, ParColR, ParColG, ParColB: real; ParAlign: integer; ParTekst: string);
+begin
+ inherited Create;
+ Alpha := 1;
+ X := ParX;
+ Y := ParY;
+ W := ParW;
+ Style := ParStyle;
+ Size := ParSize;
+ Text := ParTekst;
+ ColR := ParColR;
+ ColG := ParColG;
+ ColB := ParColB;
+ Int := 1;
+ Align := ParAlign;
+ SelectBool := false;
+ Visible := true;
+end;
+
+
+end.
diff --git a/Game/Code/Screens/UScreenCredits.pas b/Game/Code/Screens/UScreenCredits.pas
index 3b1efc6e..b931f461 100644
--- a/Game/Code/Screens/UScreenCredits.pas
+++ b/Game/Code/Screens/UScreenCredits.pas
@@ -1,1092 +1,1105 @@
-unit UScreenCredits;
-
-interface
-
-uses
- UMenu, SDL, UDisplay, UTexture, OpenGL12, UMusic, UFiles, SysUtils, UThemes, ULCD, ULight, UGraphicClasses;
-
-type
- TCreditsStages=(InitialDelay,Intro,MainPart,Outro);
-
- TScreenCredits = class(TMenu)
- public
-
- Credits_X: Real;
- Credits_Time: Cardinal;
- Credits_Alpha: Cardinal;
- CTime: Cardinal;
- CTime_hold: Cardinal;
- ESC_Alpha: Integer;
-
- credits_entry_tex: TTexture;
- credits_entry_dx_tex: TTexture;
- credits_bg_tex: TTexture;
- credits_bg_ovl: TTexture;
-// credits_bg_logo: TTexture;
- credits_bg_scrollbox_left: TTexture;
- credits_blindguard: TTexture;
- credits_blindy: TTexture;
- credits_canni: TTexture;
- credits_commandio: TTexture;
- credits_lazyjoker: TTexture;
- credits_mog: TTexture;
- credits_mota: TTexture;
- credits_skillmaster: TTexture;
- credits_whiteshark: TTexture;
- intro_layer01: TTexture;
- intro_layer02: TTexture;
- intro_layer03: TTexture;
- intro_layer04: TTexture;
- intro_layer05: TTexture;
- intro_layer06: TTexture;
- intro_layer07: TTexture;
- intro_layer08: TTexture;
- intro_layer09: TTexture;
- outro_bg: TTexture;
- outro_esc: TTexture;
- outro_exd: TTexture;
-
- deluxe_slidein: cardinal;
-
- CurrentScrollText: String;
- NextScrollUpdate: Real;
- EndofLastScrollingPart: Cardinal;
- CurrentScrollStart, CurrentScrollEnd: Integer;
-
- CRDTS_Stage: TCreditsStages;
-
- myTex: glUint;
-
- Fadeout: boolean;
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
- function Draw: boolean; override;
- procedure onShow; override;
- procedure onHide; override;
- procedure DrawCredits;
- procedure Draw_FunkyText;
- end;
-
-const
- Funky_Text: AnsiString =
- 'Grandma Deluxe has arrived! Thanks to Corvus5 for the massive work on UltraStar, Wome for the nice tune you´re hearing, '+
- 'all the people who put massive effort and work in new songs (don´t forget UltraStar w/o songs would be nothing), ppl from '+
- 'irc helping us - eBandit and Gabari, scene ppl who really helped instead of compiling and running away. Greetings to DennisTheMenace for betatesting, '+
- 'Demoscene.tv, pouet.net, KakiArts, Sourceforge,..';
-
-
- Timings: array[0..21] of Cardinal=(
- 20, // 0 Delay vor Start
-
- 149, // 1 Ende erster Intro Zoom
- 155, // 2 Start 2. Action im Intro
- 170, // 3 Ende Separation im Intro
- 271, // 4 Anfang Zoomout im Intro
- 0, // 5 unused
- 261, // 6 Start fade-to-white im Intro
-
- 271, // 7 Start Main Part
- 280, // 8 Start On-Beat-Sternchen Main Part
-
- 396, // 9 Start BlindGuard
- 666, // 10 Start blindy
- 936, // 11 Start Canni
- 1206, // 12 Start Commandio
- 1476, // 13 Start LazyJoker
- 1746, // 14 Start Mog
- 2016, // 15 Start Mota
- 2286, // 16 Start SkillMaster
- 2556, // 17 Start WhiteShark
- 2826, // 18 Ende Whiteshark
- 3096, // 19 Start FadeOut Mainscreen
- 3366, // 20 Ende Credits Tune
- 60); // 21 start flare im intro
-
-implementation
-
-uses Windows,
- UGraphic,
- UMain,
- UIni,
- USongs,
- Textgl,
- ULanguage,
- UCommon,
- Math;
-
-
-function TScreenCredits.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- case PressedKey of
-
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- FadeTo(@ScreenMain);
- Music.PlayBack;
- end;
-{ SDLK_SPACE:
- begin
- setlength(CTime_hold,length(CTime_hold)+1);
- CTime_hold[high(CTime_hold)]:=CTime;
- end;
-}
- end;//esac
- end; //fi
-end;
-
-constructor TScreenCredits.Create;
-begin
- inherited Create;
- credits_bg_tex := Texture.LoadTexture(true, 'CRDTS_BG', 'PNG', 'Plain', 0);
- credits_bg_ovl := Texture.LoadTexture(true, 'CRDTS_OVL', 'PNG', 'Transparent', 0);
-
- credits_blindguard := Texture.LoadTexture(true, 'CRDTS_blindguard', 'PNG', 'Font Black', 0);
- credits_blindy := Texture.LoadTexture(true, 'CRDTS_blindy', 'PNG', 'Font Black', 0);
- credits_canni := Texture.LoadTexture(true, 'CRDTS_canni', 'PNG', 'Font Black', 0);
- credits_commandio := Texture.LoadTexture(true, 'CRDTS_commandio', 'PNG', 'Font Black', 0);
- credits_lazyjoker := Texture.LoadTexture(true, 'CRDTS_lazyjoker', 'PNG', 'Font Black', 0);
- credits_mog := Texture.LoadTexture(true, 'CRDTS_mog', 'PNG', 'Font Black', 0);
- credits_mota := Texture.LoadTexture(true, 'CRDTS_mota', 'PNG', 'Font Black', 0);
- credits_skillmaster := Texture.LoadTexture(true, 'CRDTS_skillmaster', 'PNG', 'Font Black', 0);
- credits_whiteshark := Texture.LoadTexture(true, 'CRDTS_whiteshark', 'PNG', 'Font Black', 0);
-
- intro_layer01 := Texture.LoadTexture(true, 'INTRO_L01', 'PNG', 'Transparent', 0);
- intro_layer02 := Texture.LoadTexture(true, 'INTRO_L02', 'PNG', 'Transparent', 0);
- intro_layer03 := Texture.LoadTexture(true, 'INTRO_L03', 'PNG', 'Transparent', 0);
- intro_layer04 := Texture.LoadTexture(true, 'INTRO_L04', 'PNG', 'Transparent', 0);
- intro_layer05 := Texture.LoadTexture(true, 'INTRO_L05', 'PNG', 'Transparent', 0);
- intro_layer06 := Texture.LoadTexture(true, 'INTRO_L06', 'PNG', 'Transparent', 0);
- intro_layer07 := Texture.LoadTexture(true, 'INTRO_L07', 'PNG', 'Transparent', 0);
- intro_layer08 := Texture.LoadTexture(true, 'INTRO_L08', 'PNG', 'Transparent', 0);
- intro_layer09 := Texture.LoadTexture(true, 'INTRO_L09', 'PNG', 'Transparent', 0);
-
- outro_bg := Texture.LoadTexture(true, 'OUTRO_BG', 'PNG', 'Plain', 0);
- outro_esc := Texture.LoadTexture(true, 'OUTRO_ESC', 'PNG', 'Transparent', 0);
- outro_exd := Texture.LoadTexture(true, 'OUTRO_EXD', 'PNG', 'Transparent', 0);
-
- CRDTS_Stage:=InitialDelay;
-end;
-
-function TScreenCredits.Draw: boolean;
-begin
- DrawCredits;
- Draw:=true;
-end;
-
-procedure TScreenCredits.onShow;
-begin
- CRDTS_Stage:=InitialDelay;
- Credits_X := 580;
- deluxe_slidein := 0;
- Credits_Alpha := 0;
- //Music.SetLoop(true); Loop looped ned, so ne scheisse
- Music.Open(soundpath + 'wome-credits-tune.mp3'); //danke kleinster liebster weeeetüüüüü!!
-// Music.Play;
- CTime:=0;
-// setlength(CTime_hold,0);
-end;
-
-procedure TScreenCredits.onHide;
-begin
- Music.Stop;
-end;
-
-Procedure TScreenCredits.Draw_FunkyText;
-var
- S: Integer;
- X,Y,A: Real;
- visibleText: PChar;
-begin
- SetFontSize(10);
- //Init ScrollingText
- if (CTime = Timings[7]) then
- begin
- //Set Position of Text
- Credits_X := 600;
- CurrentScrollStart:=1;
- CurrentScrollEnd:=1;
- end;
-
- if (CTime > Timings[7]) and (CurrentScrollStart < length(Funky_Text)) then
- begin
- X:=0;
- visibleText:=pchar(Copy(Funky_Text, CurrentScrollStart, CurrentScrollEnd));
- for S := 0 to length(visibleText)-1 do begin
- Y:=abs(sin((Credits_X+X)*0.93{*(((Credits_X+X))/1200)}/100*pi));
- SetFontPos(Credits_X+X,538-Y*(Credits_X+X)*(Credits_X+X)*(Credits_X+X)/1000000);
- A:=0;
- if (Credits_X+X < 15) then A:=0;
- if (Credits_X+X >=15) then A:=Credits_X+X-15;
- if Credits_X+X > 32 then A:=17;
- glColor4f( 230/255-40/255+Y*(Credits_X+X)/900, 200/255-30/255+Y*(Credits_X+X)/1000, 155/255-20/255+Y*(Credits_X+X)/1100, A/17);
- glPrintLetter(visibleText[S]);
- X := X + Fonts[ActFont].Width[Ord(visibleText[S])] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW;
- end;
- if (Credits_X<0) and (CurrentScrollStart < length(Funky_Text)) then begin
- Credits_X:=Credits_X + Fonts[ActFont].Width[Ord(Funky_Text[CurrentScrollStart])] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW;
- inc(CurrentScrollStart);
- end;
- visibleText:=pchar(Copy(Funky_Text, CurrentScrollStart, CurrentScrollEnd));
- if (Credits_X+glTextWidth(visibleText) < 600) and (CurrentScrollEnd < length(Funky_Text)) then begin
- inc(CurrentScrollEnd);
- end;
- end;
-{ // timing hack
- X:=5;
- SetFontStyle (2);
- SetFontItalic(False);
- SetFontSize(9);
- glColor4f(1, 1, 1, 1);
- for S:=0 to high(CTime_hold) do begin
- visibleText:=pchar(inttostr(CTime_hold[S]));
- SetFontPos (500, X);
- glPrint (Addr(visibleText[0]));
- X:=X+20;
- end;}
-end;
-
-procedure Start3D;
-begin
- glMatrixMode(GL_PROJECTION);
- glPushMatrix;
- glLoadIdentity;
- glFrustum(-0.3*4/3,0.3*4/3,-0.3,0.3,1,1000);
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity;
-end;
-procedure End3D;
-begin
- glMatrixMode(GL_PROJECTION);
- glPopMatrix;
- glMatrixMode(GL_MODELVIEW);
-end;
-
-procedure TScreenCredits.DrawCredits;
-var
- T,I: Cardinal;
- X: Real;
- Ver: PChar;
- RuntimeStr: AnsiString;
- Data: TFFTData;
- j,k,l:cardinal;
- f,g,h: Real;
- STime:cardinal;
- Delay:cardinal;
-
- myPixel: longword;
- myColor: Cardinal;
- myScale: Real;
- myAngle: Real;
-
-
-const myLogoCoords: Array[0..27,0..1] of Cardinal = ((39,32),(84,32),(100,16),(125,24),
- (154,31),(156,58),(168,32),(203,36),
- (258,34),(251,50),(274,93),(294,84),
- (232,54),(278,62),(319,34),(336,92),
- (347,23),(374,32),(377,58),(361,83),
- (385,91),(405,91),(429,35),(423,51),
- (450,32),(485,34),(444,91),(486,93));
-
-begin
-//dis does teh muiwk y0r
-Data := Music.GetFFTData;
-
-
-
- T := GetTickCount div 33;
- if T <> Credits_Time then
- begin
- Credits_Time := T;
- inc(CTime);
- inc(CTime_hold);
- Credits_X := Credits_X-2;
- if (CRDTS_Stage=InitialDelay) and (CTime=Timings[0]) then
- begin
-// CTime:=Timings[20];
-// CRDTS_Stage:=Outro;
-
- CRDTS_Stage:=Intro;
- CTime:=0;
- Music.Play;
-
- end;
- if (CRDTS_Stage=Intro) and (CTime=Timings[7]) then
- begin
- CRDTS_Stage:=MainPart;
- end;
- if (CRDTS_Stage=MainPart) and (CTime=Timings[20]) then
- begin
- CRDTS_Stage:=Outro;
- end;
- end;
-
- //draw background
- if CRDTS_Stage=InitialDelay then
- begin
- glClearColor(0,0,0,0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
- end
- else
- if CRDTS_Stage=Intro then
- begin
- Start3D;
- glPushMatrix;
-
- glClearColor(0,0,0,0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
-
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- if CTime < Timings[1] then begin
- myScale:= 0.5+0.5*(Timings[1]-CTime)/(Timings[1]); // slowly move layers together
- myAngle:=cos((CTime)*pi/((Timings[1])*2)); // and make logo face towards camera
- end else begin // this is the part when the logo stands still
- myScale:=0.5;
- myAngle:=0;
- end;
- if CTime > Timings[2] then begin
- myScale:= 0.5+0.5*(CTime-Timings[2])/(Timings[3]-Timings[2]); // get some space between layers
- myAngle:=0;
- end;
-// if CTime > Timings[3] then myScale:=1; // keep the space between layers
- glTranslatef(0,0,-5+0.5*myScale);
- if CTime > Timings[3] then myScale:=1; // keep the space between layers
- if CTime > Timings[3] then begin // make logo rotate left and grow
-// myScale:=(CTime-Timings[4])/(Timings[7]-Timings[4]);
- glRotatef(20*sqr(CTime-Timings[3])/sqr((Timings[7]-Timings[3])/2),0,0,1);
- glScalef(1+sqr(CTime-Timings[3])/(32*(Timings[7]-Timings[3])),1+sqr(CTime-Timings[3])/(32*(Timings[7]-Timings[3])),1);
- end;
- if CTime < Timings[2] then
- glRotatef(30*myAngle,0.5*myScale+myScale,1+myScale,0);
-// glScalef(0.5,0.5,0.5);
- glScalef(4/3,-1,1);
- glColor4f(1, 1, 1, 1);
-
- glBindTexture(GL_TEXTURE_2D, intro_layer01.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, -0.4 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, -0.4 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, -0.4 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, -0.4 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer02.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, -0.3 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, -0.3 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, -0.3 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, -0.3 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer03.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, -0.2 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, -0.2 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, -0.2 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, -0.2 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer04.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, -0.1 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, -0.1 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, -0.1 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, -0.1 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer05.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, 0 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, 0 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, 0 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, 0 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer06.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, 0.1 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, 0.1 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, 0.1 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, 0.1 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer07.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, 0.2 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, 0.2 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, 0.2 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, 0.2 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer08.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, 0.3 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, 0.3 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, 0.3 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, 0.3 * myScale);
- glEnd;
- glBindTexture(GL_TEXTURE_2D, intro_layer09.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex3f(-1, -1, 0.22 * myScale);
- glTexCoord2f(0,1);glVertex3f(-1, 1, 0.22 * myScale);
- glTexCoord2f(1,1); glVertex3f(1, 1, 0.22 * myScale);
- glTexCoord2f(1,0);glVertex3f(1, -1, 0.22 * myScale);
- glEnd;
- gldisable(gl_texture_2d);
- glDisable(GL_BLEND);
-
- glPopMatrix;
- End3D;
-
- // do some sparkling effects
- if (CTime < Timings[1]) and (CTime > Timings[21]) then
- begin
- for k:=1 to 3 do begin
- l:=410+floor((CTime-Timings[21])/(Timings[1]-Timings[21])*(536-410))+RandomRange(-5,5);
- j:=floor((Timings[1]-CTime)/22)+RandomRange(285,301);
- GoldenRec.Spawn(l, j, 1, 16, 0, -1, Flare, 0);
- end;
- end;
-
- // fade to white at end
- if Ctime > Timings[6] then
- begin
- glColor4f(1,1,1,sqr(Ctime-Timings[6])*(Ctime-Timings[6])/sqr(Timings[7]-Timings[6]));
- glEnable(GL_BLEND);
- glBegin(GL_QUADS);
- glVertex2f(0,0);
- glVertex2f(0,600);
- glVertex2f(800,600);
- glVertex2f(800,0);
- glEnd;
- glDisable(GL_BLEND);
- end;
-
- end;
- if (CRDTS_Stage=MainPart) then
- // main credits screen background, scroller, logo and girl
- begin
-
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- glColor4f(1, 1, 1, 1);
- glBindTexture(GL_TEXTURE_2D, credits_bg_tex.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(0, 0);
- glTexCoord2f(0,600/1024);glVertex2f(0, 600);
- glTexCoord2f(800/1024,600/1024); glVertex2f(800, 600);
- glTexCoord2f(800/1024,0);glVertex2f(800, 0);
- glEnd;
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- // draw scroller
- Draw_FunkyText;
-
-//#########################################################################
-// draw credits names
-
-// BlindGuard (von links oben reindrehen, nach rechts unten rausdrehen)
- STime:=Timings[9]-10;
- Delay:=Timings[10]-Timings[9];
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
- for j:=0 to 40 do
- if Data[j]>=Data[k] then k:=j;
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+10) and (CTime<=STime+12) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(0,329,0);
- if CTime <= STime+10 then begin glrotatef((CTime-STime)*9+270,0,0,1);end;
- gltranslatef(223,0,0);
- if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
- gltranslatef(223,0,0);
- glrotatef((integer(CTime)-(integer(STime+Delay)-10))*-9,0,0,1);
- gltranslatef(-223,0,0);
- end;
- glBindTexture(GL_TEXTURE_2D, credits_blindguard.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163, -129);
- glTexCoord2f(0,1);glVertex2f(-163, 129);
- glTexCoord2f(1,1); glVertex2f(163, 129);
- glTexCoord2f(1,0);glVertex2f(163, -129);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// Blindy (zoom von 0 auf volle grösse und drehung, zoom auf doppelte grösse und nach rechts oben schieben)
- STime:=Timings[10]-10;
- Delay:=Timings[11]-Timings[10]+5;
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
- for j:=0 to 40 do
- if Data[j]>=Data[k] then k:=j;
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+20) and (CTime<=STime+22) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(223,329,0);
- if CTime <= STime+20 then begin
- j:=CTime-Stime;
- glscalef(j*j/400,j*j/400,j*j/400);
- glrotatef(j*18.0,0,0,1);
- end;
- if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
- j:=CTime-(STime+Delay-10);
- f:=j*10.0;
- gltranslatef(f*3,-f,0);
- glscalef(1+j/10,1+j/10,1+j/10);
- glrotatef(j*9.0,0,0,1);
- end;
- glBindTexture(GL_TEXTURE_2D, credits_blindy.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163, -129);
- glTexCoord2f(0,1);glVertex2f(-163, 129);
- glTexCoord2f(1,1); glVertex2f(163, 129);
- glTexCoord2f(1,0);glVertex2f(163, -129);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// Canni (von links reinschieben, nach rechts oben rausschieben)
- STime:=Timings[11]-10;
- Delay:=Timings[12]-Timings[11]+5;
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
- for j:=0 to 40 do
- if Data[j]>=Data[k] then k:=j;
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+10) and (CTime<=STime+12) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(223,329,0);
- if CTime <= STime+10 then begin
- gltranslatef(((CTime-STime)*21.0)-210,0,0);
- end;
- if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
- j:=(CTime-(STime+Delay-10))*21;
- gltranslatef(j,-j/2,0);
- end;
- glBindTexture(GL_TEXTURE_2D, credits_canni.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163, -129);
- glTexCoord2f(0,1);glVertex2f(-163, 129);
- glTexCoord2f(1,1); glVertex2f(163, 129);
- glTexCoord2f(1,0);glVertex2f(163, -129);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// Commandio (von unten reinklappen, nach rechts oben rausklappen)
- STime:=Timings[12]-10;
- Delay:=Timings[13]-Timings[12];
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
- for j:=0 to 40 do
- if Data[j]>=Data[k] then k:=j;
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+10) and (CTime<=STime+12) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(223,329,0);
- if CTime <= STime+10 then
- f:=258.0-25.8*(CTime-STime)
- else
- f:=0;
- g:=0;
- if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
- j:=CTime-(STime+Delay-10);
- g:=32.6*j;
- end;
- glBindTexture(GL_TEXTURE_2D, credits_commandio.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163+g-f*1.5, -129+f*1.5-g/2);
- glTexCoord2f(0,1);glVertex2f(-163+g*1.5, 129-(g*1.5*258/326));
- glTexCoord2f(1,1); glVertex2f(163+g, 129+g/4);
- glTexCoord2f(1,0);glVertex2f(163+f*1.5+g/4, -129+f*1.5-g/4);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// lazy joker (just scrolls from left to right, no twinkling stars, no on-beat flashing)
- STime:=Timings[13]-35;
- Delay:=Timings[14]-Timings[13]+5;
- if CTime > STime then
- begin
- k:=0;
- for j:=0 to 40 do
- if Data[j]>=Data[k] then k:=j;
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)>10) and ((CTime-STime)<20) then ESC_Alpha:=20;
- ESC_Alpha:=10;
- f:=CTime-STime;
- if CTime <=STime+40 then j:=CTime-STime else j:=40;
- if (CTime >=STime+Delay-40) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j*j/1600);
-
- glPushMatrix;
- gltranslatef(180+(f-70),329,0);
- glBindTexture(GL_TEXTURE_2D, credits_lazyjoker.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163, -129);
- glTexCoord2f(0,1);glVertex2f(-163, 129);
- glTexCoord2f(1,1); glVertex2f(163, 129);
- glTexCoord2f(1,0);glVertex2f(163, -129);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// Mog (von links reinklappen, nach rechts unten rausklappen)
- STime:=Timings[14]-10;
- Delay:=Timings[15]-Timings[14]+5;
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
- for j:=0 to 40 do
- if Data[j]>=Data[k] then k:=j;
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+10) and (CTime<=STime+12) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(223,329,0);
- if CTime <= STime+10 then
- f:=326.0-32.6*(CTime-STime)
- else
- f:=0;
-
- g:=0;
- if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
- j:=CTime-(STime+Delay-10);
- g:=32.6*j;
- end;
- glBindTexture(GL_TEXTURE_2D, credits_mog.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163+g*1.5, -129+g*1.5);
- glTexCoord2f(0,1);glVertex2f(-163+g*1.2, 129+g);
- glTexCoord2f(1,1); glVertex2f(163-f+g/2, 129+f*1.5+g/4);
- glTexCoord2f(1,0);glVertex2f(163-f+g*1.5, -129-f*1.5);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// Mota (von rechts oben reindrehen, nach links unten rausschieben und verkleinern und dabei drehen)
- STime:=Timings[15]-10;
- Delay:=Timings[16]-Timings[15]+5;
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
- for j:=0 to 40 do
- if Data[j]>=Data[k] then k:=j;
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+10) and (CTime<=STime+12) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(223,329,0);
- if CTime <= STime+10 then begin
- gltranslatef(223,0,0);
- glrotatef((10-(CTime-STime))*9,0,0,1);
- gltranslatef(-223,0,0);
- end;
- if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
- j:=CTime-(STime+Delay-10);
- f:=j*10.0;
- gltranslatef(-f*2,-f,0);
- glscalef(1-j/10,1-j/10,1-j/10);
- glrotatef(-j*9.0,0,0,1);
- end;
- glBindTexture(GL_TEXTURE_2D, credits_mota.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163, -129);
- glTexCoord2f(0,1);glVertex2f(-163, 129);
- glTexCoord2f(1,1); glVertex2f(163, 129);
- glTexCoord2f(1,0);glVertex2f(163, -129);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// Skillmaster (von rechts unten reinschieben, nach rechts oben rausdrehen)
- STime:=Timings[16]-10;
- Delay:=Timings[17]-Timings[16]+5;
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
- for j:=0 to 40 do
- if Data[j]>=Data[k] then k:=j;
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+10) and (CTime<=STime+12) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(223,329,0);
- if CTime <= STime+10 then begin
- j:=STime+10-CTime;
- f:=j*10.0;
- gltranslatef(+f*2,+f/2,0);
- end;
- if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
- j:=CTime-(STime+Delay-10);
- gltranslatef(0,-223,0);
- glrotatef(integer(j)*-9,0,0,1);
- gltranslatef(0,223,0);
- glrotatef(j*9,0,0,1);
- end;
- glBindTexture(GL_TEXTURE_2D, credits_skillmaster.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163, -129);
- glTexCoord2f(0,1);glVertex2f(-163, 129);
- glTexCoord2f(1,1); glVertex2f(163, 129);
- glTexCoord2f(1,0);glVertex2f(163, -129);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-// WhiteShark (von links unten reinklappen, nach rechts oben rausklappen)
- STime:=Timings[17]-10;
- Delay:=Timings[18]-Timings[17];
- if CTime > STime then
- begin
- k:=0;
- ESC_Alpha:=20;
- for j:=0 to 40 do
- if Data[j]>=Data[k] then k:=j;
- if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
- if ESC_Alpha >20 then ESC_Alpha:=20;
- if ((CTime-STime)<20) then ESC_Alpha:=20;
- if CTime <=STime+10 then j:=CTime-STime else j:=10;
- if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
- glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
-
- if (CTime >= STime+10) and (CTime<=STime+12) then begin
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
- GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
- end;
-
- glPushMatrix;
- gltranslatef(223,329,0);
- if CTime <= STime+10 then
- f:=326.0-32.6*(CTime-STime)
- else
- f:=0;
-
- if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
- j:=CTime-(STime+Delay-10);
- g:=32.6*j;
- end else
- g:=0;
- glBindTexture(GL_TEXTURE_2D, credits_whiteshark.TexNum);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glEnable(GL_TEXTURE_2D);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(-163-f+g, -129+f/4-g/2);
- glTexCoord2f(0,1);glVertex2f(-163-f/4+g, 129+g/2+f/4);
- glTexCoord2f(1,1); glVertex2f(163-f*1.2+g/4, 129+f/2-g/4);
- glTexCoord2f(1,0);glVertex2f(163-f*1.5+g/4, -129+f*1.5+g/4);
- glEnd;
- gldisable(gl_texture_2d);
- gldisable(GL_BLEND);
- glPopMatrix;
- end;
-
-
-// ####################################################################
-// do some twinkle stuff (kinda on beat)
- if (CTime>Timings[8]) and (CTime < Timings[19]) then begin
- k:=0;
- for j:=0 to 40 do
- if Data[j]>=Data[k] then k:=j;
- if Data[k]>0.2 then begin
- l:=RandomRange(6,16);
- j:=RandomRange(0,27);
- GoldenRec.Spawn(myLogoCoords[j,0], myLogoCoords[j,1], 16-l, l, 0, -1, PerfectNote, 0);
- end;
- end;
-
-//#################################################
-// draw the rest of the main screen (girl and logo
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glColor4f(1, 1, 1, 1);
- glBindTexture(GL_TEXTURE_2D, credits_bg_ovl.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(800-393, 0);
- glTexCoord2f(0,600/1024);glVertex2f(800-393, 600);
- glTexCoord2f(393/512,600/1024); glVertex2f(800, 600);
- glTexCoord2f(393/512,0);glVertex2f(800, 0);
- glEnd;
-{ glBindTexture(GL_TEXTURE_2D, credits_bg_logo.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(0, 0);
- glTexCoord2f(0,112/128);glVertex2f(0, 112);
- glTexCoord2f(497/512,112/128); glVertex2f(497, 112);
- glTexCoord2f(497/512,0);glVertex2f(497, 0);
- glEnd;
-}
- gldisable(gl_texture_2d);
- glDisable(GL_BLEND);
-
- // fade out at end of main part
- if Ctime > Timings[19] then
- begin
- glColor4f(0,0,0,(Ctime-Timings[19])/(Timings[20]-Timings[19]));
- glEnable(GL_BLEND);
- glBegin(GL_QUADS);
- glVertex2f(0,0);
- glVertex2f(0,600);
- glVertex2f(800,600);
- glVertex2f(800,0);
- glEnd;
- glDisable(GL_BLEND);
- end;
- end
- else
- if (CRDTS_Stage=Outro) then
- begin
- if CTime=Timings[20] then begin
- CTime_hold:=0;
- Music.Stop;
- Music.Open(soundpath + 'credits-outro-tune.mp3');
- Music.Play;
- Music.SetVolume(20);
- Music.SetLoop(True);
- end;
- if CTime_hold > 231 then begin
- Music.Play;
- Ctime_hold:=0;
- end;
- glClearColor(0,0,0,0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
-
- // do something useful
- // outro background
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- glColor4f(1, 1, 1, 1);
- glBindTexture(GL_TEXTURE_2D, outro_bg.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(0, 0);
- glTexCoord2f(0,600/1024);glVertex2f(0, 600);
- glTexCoord2f(800/1024,600/1024); glVertex2f(800, 600);
- glTexCoord2f(800/1024,0);glVertex2f(800, 0);
- glEnd;
-
- //outro overlays
- glColor4f(1, 1, 1, (1+sin(CTime/15))/3+1/3);
- glBindTexture(GL_TEXTURE_2D, outro_esc.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(0, 0);
- glTexCoord2f(0,223/256);glVertex2f(0, 223);
- glTexCoord2f(487/512,223/256); glVertex2f(487, 223);
- glTexCoord2f(487/512,0);glVertex2f(487, 0);
- glEnd;
-
- ESC_Alpha:=20;
- if (RandomRange(0,20) > 18) and (ESC_Alpha=20) then
- ESC_Alpha:=0
- else inc(ESC_Alpha);
- if ESC_Alpha > 20 then ESC_Alpha:=20;
- glColor4f(1, 1, 1, ESC_Alpha/20);
- glBindTexture(GL_TEXTURE_2D, outro_exd.TexNum);
- glbegin(gl_quads);
- glTexCoord2f(0,0);glVertex2f(800-310, 600-247);
- glTexCoord2f(0,247/256);glVertex2f(800-310, 600);
- glTexCoord2f(310/512,247/256); glVertex2f(800, 600);
- glTexCoord2f(310/512,0);glVertex2f(800, 600-247);
- glEnd;
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- // outro scrollers?
- // ...
- end;
-
-{ // draw credits runtime counter
- SetFontStyle (2);
- SetFontItalic(False);
- SetFontSize(9);
- SetFontPos (5, 5);
- glColor4f(1, 1, 1, 1);
-// RuntimeStr:='CTime: '+inttostr(floor(CTime/30.320663991914489602156136106092))+'.'+inttostr(floor(CTime/3.0320663991914489602156136106092)-floor(CTime/30.320663991914489602156136106092)*10);
- RuntimeStr:='CTime: '+inttostr(CTime);
- glPrint (Addr(RuntimeStr[1]));
-}
- // make the stars shine
- GoldenRec.Draw;
-end;
-
-end.
+unit UScreenCredits;
+
+interface
+
+uses
+ UMenu,
+ SDL,
+ UDisplay,
+ UTexture,
+ OpenGL12,
+ UMusic,
+ UFiles,
+ SysUtils,
+ UThemes,
+ ULCD,
+ ULight,
+ UGraphicClasses;
+
+type
+ TCreditsStages=(InitialDelay,Intro,MainPart,Outro);
+
+ TScreenCredits = class(TMenu)
+ public
+
+ Credits_X: Real;
+ Credits_Time: Cardinal;
+ Credits_Alpha: Cardinal;
+ CTime: Cardinal;
+ CTime_hold: Cardinal;
+ ESC_Alpha: Integer;
+
+ credits_entry_tex: TTexture;
+ credits_entry_dx_tex: TTexture;
+ credits_bg_tex: TTexture;
+ credits_bg_ovl: TTexture;
+// credits_bg_logo: TTexture;
+ credits_bg_scrollbox_left: TTexture;
+ credits_blindguard: TTexture;
+ credits_blindy: TTexture;
+ credits_canni: TTexture;
+ credits_commandio: TTexture;
+ credits_lazyjoker: TTexture;
+ credits_mog: TTexture;
+ credits_mota: TTexture;
+ credits_skillmaster: TTexture;
+ credits_whiteshark: TTexture;
+ intro_layer01: TTexture;
+ intro_layer02: TTexture;
+ intro_layer03: TTexture;
+ intro_layer04: TTexture;
+ intro_layer05: TTexture;
+ intro_layer06: TTexture;
+ intro_layer07: TTexture;
+ intro_layer08: TTexture;
+ intro_layer09: TTexture;
+ outro_bg: TTexture;
+ outro_esc: TTexture;
+ outro_exd: TTexture;
+
+ deluxe_slidein: cardinal;
+
+ CurrentScrollText: String;
+ NextScrollUpdate: Real;
+ EndofLastScrollingPart: Cardinal;
+ CurrentScrollStart, CurrentScrollEnd: Integer;
+
+ CRDTS_Stage: TCreditsStages;
+
+ myTex: glUint;
+
+ Fadeout: boolean;
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+ procedure onShow; override;
+ procedure onHide; override;
+ procedure DrawCredits;
+ procedure Draw_FunkyText;
+ end;
+
+const
+ Funky_Text: AnsiString =
+ 'Grandma Deluxe has arrived! Thanks to Corvus5 for the massive work on UltraStar, Wome for the nice tune you´re hearing, '+
+ 'all the people who put massive effort and work in new songs (don´t forget UltraStar w/o songs would be nothing), ppl from '+
+ 'irc helping us - eBandit and Gabari, scene ppl who really helped instead of compiling and running away. Greetings to DennisTheMenace for betatesting, '+
+ 'Demoscene.tv, pouet.net, KakiArts, Sourceforge,..';
+
+
+ Timings: array[0..21] of Cardinal=(
+ 20, // 0 Delay vor Start
+
+ 149, // 1 Ende erster Intro Zoom
+ 155, // 2 Start 2. Action im Intro
+ 170, // 3 Ende Separation im Intro
+ 271, // 4 Anfang Zoomout im Intro
+ 0, // 5 unused
+ 261, // 6 Start fade-to-white im Intro
+
+ 271, // 7 Start Main Part
+ 280, // 8 Start On-Beat-Sternchen Main Part
+
+ 396, // 9 Start BlindGuard
+ 666, // 10 Start blindy
+ 936, // 11 Start Canni
+ 1206, // 12 Start Commandio
+ 1476, // 13 Start LazyJoker
+ 1746, // 14 Start Mog
+ 2016, // 15 Start Mota
+ 2286, // 16 Start SkillMaster
+ 2556, // 17 Start WhiteShark
+ 2826, // 18 Ende Whiteshark
+ 3096, // 19 Start FadeOut Mainscreen
+ 3366, // 20 Ende Credits Tune
+ 60); // 21 start flare im intro
+
+implementation
+
+uses {$IFDEF win32}
+ windows,
+ {$ELSE}
+ lclintf,
+ {$ENDIF}
+ UGraphic,
+ UMain,
+ UIni,
+ USongs,
+ Textgl,
+ ULanguage,
+ UCommon,
+ Math;
+
+
+function TScreenCredits.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ FadeTo(@ScreenMain);
+ Music.PlayBack;
+ end;
+{ SDLK_SPACE:
+ begin
+ setlength(CTime_hold,length(CTime_hold)+1);
+ CTime_hold[high(CTime_hold)]:=CTime;
+ end;
+}
+ end;//esac
+ end; //fi
+end;
+
+constructor TScreenCredits.Create;
+begin
+ inherited Create;
+ credits_bg_tex := Texture.LoadTexture(true, 'CRDTS_BG', 'PNG', 'Plain', 0);
+ credits_bg_ovl := Texture.LoadTexture(true, 'CRDTS_OVL', 'PNG', 'Transparent', 0);
+
+ credits_blindguard := Texture.LoadTexture(true, 'CRDTS_blindguard', 'PNG', 'Font Black', 0);
+ credits_blindy := Texture.LoadTexture(true, 'CRDTS_blindy', 'PNG', 'Font Black', 0);
+ credits_canni := Texture.LoadTexture(true, 'CRDTS_canni', 'PNG', 'Font Black', 0);
+ credits_commandio := Texture.LoadTexture(true, 'CRDTS_commandio', 'PNG', 'Font Black', 0);
+ credits_lazyjoker := Texture.LoadTexture(true, 'CRDTS_lazyjoker', 'PNG', 'Font Black', 0);
+ credits_mog := Texture.LoadTexture(true, 'CRDTS_mog', 'PNG', 'Font Black', 0);
+ credits_mota := Texture.LoadTexture(true, 'CRDTS_mota', 'PNG', 'Font Black', 0);
+ credits_skillmaster := Texture.LoadTexture(true, 'CRDTS_skillmaster', 'PNG', 'Font Black', 0);
+ credits_whiteshark := Texture.LoadTexture(true, 'CRDTS_whiteshark', 'PNG', 'Font Black', 0);
+
+ intro_layer01 := Texture.LoadTexture(true, 'INTRO_L01', 'PNG', 'Transparent', 0);
+ intro_layer02 := Texture.LoadTexture(true, 'INTRO_L02', 'PNG', 'Transparent', 0);
+ intro_layer03 := Texture.LoadTexture(true, 'INTRO_L03', 'PNG', 'Transparent', 0);
+ intro_layer04 := Texture.LoadTexture(true, 'INTRO_L04', 'PNG', 'Transparent', 0);
+ intro_layer05 := Texture.LoadTexture(true, 'INTRO_L05', 'PNG', 'Transparent', 0);
+ intro_layer06 := Texture.LoadTexture(true, 'INTRO_L06', 'PNG', 'Transparent', 0);
+ intro_layer07 := Texture.LoadTexture(true, 'INTRO_L07', 'PNG', 'Transparent', 0);
+ intro_layer08 := Texture.LoadTexture(true, 'INTRO_L08', 'PNG', 'Transparent', 0);
+ intro_layer09 := Texture.LoadTexture(true, 'INTRO_L09', 'PNG', 'Transparent', 0);
+
+ outro_bg := Texture.LoadTexture(true, 'OUTRO_BG', 'PNG', 'Plain', 0);
+ outro_esc := Texture.LoadTexture(true, 'OUTRO_ESC', 'PNG', 'Transparent', 0);
+ outro_exd := Texture.LoadTexture(true, 'OUTRO_EXD', 'PNG', 'Transparent', 0);
+
+ CRDTS_Stage:=InitialDelay;
+end;
+
+function TScreenCredits.Draw: boolean;
+begin
+ DrawCredits;
+ Draw:=true;
+end;
+
+procedure TScreenCredits.onShow;
+begin
+ CRDTS_Stage:=InitialDelay;
+ Credits_X := 580;
+ deluxe_slidein := 0;
+ Credits_Alpha := 0;
+ //Music.SetLoop(true); Loop looped ned, so ne scheisse
+ Music.Open(soundpath + 'wome-credits-tune.mp3'); //danke kleinster liebster weeeetüüüüü!!
+// Music.Play;
+ CTime:=0;
+// setlength(CTime_hold,0);
+end;
+
+procedure TScreenCredits.onHide;
+begin
+ Music.Stop;
+end;
+
+Procedure TScreenCredits.Draw_FunkyText;
+var
+ S: Integer;
+ X,Y,A: Real;
+ visibleText: PChar;
+begin
+ SetFontSize(10);
+ //Init ScrollingText
+ if (CTime = Timings[7]) then
+ begin
+ //Set Position of Text
+ Credits_X := 600;
+ CurrentScrollStart:=1;
+ CurrentScrollEnd:=1;
+ end;
+
+ if (CTime > Timings[7]) and (CurrentScrollStart < length(Funky_Text)) then
+ begin
+ X:=0;
+ visibleText:=pchar(Copy(Funky_Text, CurrentScrollStart, CurrentScrollEnd));
+ for S := 0 to length(visibleText)-1 do begin
+ Y:=abs(sin((Credits_X+X)*0.93{*(((Credits_X+X))/1200)}/100*pi));
+ SetFontPos(Credits_X+X,538-Y*(Credits_X+X)*(Credits_X+X)*(Credits_X+X)/1000000);
+ A:=0;
+ if (Credits_X+X < 15) then A:=0;
+ if (Credits_X+X >=15) then A:=Credits_X+X-15;
+ if Credits_X+X > 32 then A:=17;
+ glColor4f( 230/255-40/255+Y*(Credits_X+X)/900, 200/255-30/255+Y*(Credits_X+X)/1000, 155/255-20/255+Y*(Credits_X+X)/1100, A/17);
+ glPrintLetter(visibleText[S]);
+ X := X + Fonts[ActFont].Width[Ord(visibleText[S])] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW;
+ end;
+ if (Credits_X<0) and (CurrentScrollStart < length(Funky_Text)) then begin
+ Credits_X:=Credits_X + Fonts[ActFont].Width[Ord(Funky_Text[CurrentScrollStart])] * Fonts[ActFont].Tex.H / 30 * Fonts[ActFont].AspectW;
+ inc(CurrentScrollStart);
+ end;
+ visibleText:=pchar(Copy(Funky_Text, CurrentScrollStart, CurrentScrollEnd));
+ if (Credits_X+glTextWidth(visibleText) < 600) and (CurrentScrollEnd < length(Funky_Text)) then begin
+ inc(CurrentScrollEnd);
+ end;
+ end;
+{ // timing hack
+ X:=5;
+ SetFontStyle (2);
+ SetFontItalic(False);
+ SetFontSize(9);
+ glColor4f(1, 1, 1, 1);
+ for S:=0 to high(CTime_hold) do begin
+ visibleText:=pchar(inttostr(CTime_hold[S]));
+ SetFontPos (500, X);
+ glPrint (Addr(visibleText[0]));
+ X:=X+20;
+ end;}
+end;
+
+procedure Start3D;
+begin
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix;
+ glLoadIdentity;
+ glFrustum(-0.3*4/3,0.3*4/3,-0.3,0.3,1,1000);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity;
+end;
+procedure End3D;
+begin
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix;
+ glMatrixMode(GL_MODELVIEW);
+end;
+
+procedure TScreenCredits.DrawCredits;
+var
+ T,I: Cardinal;
+ X: Real;
+ Ver: PChar;
+ RuntimeStr: AnsiString;
+ Data: TFFTData;
+ j,k,l:cardinal;
+ f,g,h: Real;
+ STime:cardinal;
+ Delay:cardinal;
+
+ myPixel: longword;
+ myColor: Cardinal;
+ myScale: Real;
+ myAngle: Real;
+
+
+const myLogoCoords: Array[0..27,0..1] of Cardinal = ((39,32),(84,32),(100,16),(125,24),
+ (154,31),(156,58),(168,32),(203,36),
+ (258,34),(251,50),(274,93),(294,84),
+ (232,54),(278,62),(319,34),(336,92),
+ (347,23),(374,32),(377,58),(361,83),
+ (385,91),(405,91),(429,35),(423,51),
+ (450,32),(485,34),(444,91),(486,93));
+
+begin
+ //dis does teh muiwk y0r
+ Data := Music.GetFFTData;
+
+ T := GetTickCount div 33;
+ if T <> Credits_Time then
+ begin
+ Credits_Time := T;
+ inc(CTime);
+ inc(CTime_hold);
+ Credits_X := Credits_X-2;
+ if (CRDTS_Stage=InitialDelay) and (CTime=Timings[0]) then
+ begin
+// CTime:=Timings[20];
+// CRDTS_Stage:=Outro;
+
+ CRDTS_Stage:=Intro;
+ CTime:=0;
+ Music.Play;
+
+ end;
+ if (CRDTS_Stage=Intro) and (CTime=Timings[7]) then
+ begin
+ CRDTS_Stage:=MainPart;
+ end;
+ if (CRDTS_Stage=MainPart) and (CTime=Timings[20]) then
+ begin
+ CRDTS_Stage:=Outro;
+ end;
+ end;
+
+ //draw background
+ if CRDTS_Stage=InitialDelay then
+ begin
+ glClearColor(0,0,0,0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+ end
+ else
+ if CRDTS_Stage=Intro then
+ begin
+ Start3D;
+ glPushMatrix;
+
+ glClearColor(0,0,0,0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ if CTime < Timings[1] then begin
+ myScale:= 0.5+0.5*(Timings[1]-CTime)/(Timings[1]); // slowly move layers together
+ myAngle:=cos((CTime)*pi/((Timings[1])*2)); // and make logo face towards camera
+ end else begin // this is the part when the logo stands still
+ myScale:=0.5;
+ myAngle:=0;
+ end;
+ if CTime > Timings[2] then begin
+ myScale:= 0.5+0.5*(CTime-Timings[2])/(Timings[3]-Timings[2]); // get some space between layers
+ myAngle:=0;
+ end;
+// if CTime > Timings[3] then myScale:=1; // keep the space between layers
+ glTranslatef(0,0,-5+0.5*myScale);
+ if CTime > Timings[3] then myScale:=1; // keep the space between layers
+ if CTime > Timings[3] then begin // make logo rotate left and grow
+// myScale:=(CTime-Timings[4])/(Timings[7]-Timings[4]);
+ glRotatef(20*sqr(CTime-Timings[3])/sqr((Timings[7]-Timings[3])/2),0,0,1);
+ glScalef(1+sqr(CTime-Timings[3])/(32*(Timings[7]-Timings[3])),1+sqr(CTime-Timings[3])/(32*(Timings[7]-Timings[3])),1);
+ end;
+ if CTime < Timings[2] then
+ glRotatef(30*myAngle,0.5*myScale+myScale,1+myScale,0);
+// glScalef(0.5,0.5,0.5);
+ glScalef(4/3,-1,1);
+ glColor4f(1, 1, 1, 1);
+
+ glBindTexture(GL_TEXTURE_2D, intro_layer01.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, -0.4 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, -0.4 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, -0.4 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, -0.4 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer02.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, -0.3 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, -0.3 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, -0.3 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, -0.3 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer03.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, -0.2 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, -0.2 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, -0.2 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, -0.2 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer04.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, -0.1 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, -0.1 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, -0.1 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, -0.1 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer05.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, 0 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, 0 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, 0 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, 0 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer06.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, 0.1 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, 0.1 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, 0.1 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, 0.1 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer07.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, 0.2 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, 0.2 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, 0.2 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, 0.2 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer08.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, 0.3 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, 0.3 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, 0.3 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, 0.3 * myScale);
+ glEnd;
+ glBindTexture(GL_TEXTURE_2D, intro_layer09.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex3f(-1, -1, 0.22 * myScale);
+ glTexCoord2f(0,1);glVertex3f(-1, 1, 0.22 * myScale);
+ glTexCoord2f(1,1); glVertex3f(1, 1, 0.22 * myScale);
+ glTexCoord2f(1,0);glVertex3f(1, -1, 0.22 * myScale);
+ glEnd;
+ gldisable(gl_texture_2d);
+ glDisable(GL_BLEND);
+
+ glPopMatrix;
+ End3D;
+
+ // do some sparkling effects
+ if (CTime < Timings[1]) and (CTime > Timings[21]) then
+ begin
+ for k:=1 to 3 do begin
+ l:=410+floor((CTime-Timings[21])/(Timings[1]-Timings[21])*(536-410))+RandomRange(-5,5);
+ j:=floor((Timings[1]-CTime)/22)+RandomRange(285,301);
+ GoldenRec.Spawn(l, j, 1, 16, 0, -1, Flare, 0);
+ end;
+ end;
+
+ // fade to white at end
+ if Ctime > Timings[6] then
+ begin
+ glColor4f(1,1,1,sqr(Ctime-Timings[6])*(Ctime-Timings[6])/sqr(Timings[7]-Timings[6]));
+ glEnable(GL_BLEND);
+ glBegin(GL_QUADS);
+ glVertex2f(0,0);
+ glVertex2f(0,600);
+ glVertex2f(800,600);
+ glVertex2f(800,0);
+ glEnd;
+ glDisable(GL_BLEND);
+ end;
+
+ end;
+ if (CRDTS_Stage=MainPart) then
+ // main credits screen background, scroller, logo and girl
+ begin
+
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ glColor4f(1, 1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, credits_bg_tex.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(0, 0);
+ glTexCoord2f(0,600/1024);glVertex2f(0, 600);
+ glTexCoord2f(800/1024,600/1024); glVertex2f(800, 600);
+ glTexCoord2f(800/1024,0);glVertex2f(800, 0);
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+ // draw scroller
+ Draw_FunkyText;
+
+//#########################################################################
+// draw credits names
+
+// BlindGuard (von links oben reindrehen, nach rechts unten rausdrehen)
+ STime:=Timings[9]-10;
+ Delay:=Timings[10]-Timings[9];
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+ for j:=0 to 40 do
+ if Data[j]>=Data[k] then k:=j;
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(0,329,0);
+ if CTime <= STime+10 then begin glrotatef((CTime-STime)*9+270,0,0,1);end;
+ gltranslatef(223,0,0);
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ gltranslatef(223,0,0);
+ glrotatef((integer(CTime)-(integer(STime+Delay)-10))*-9,0,0,1);
+ gltranslatef(-223,0,0);
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_blindguard.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Blindy (zoom von 0 auf volle grösse und drehung, zoom auf doppelte grösse und nach rechts oben schieben)
+ STime:=Timings[10]-10;
+ Delay:=Timings[11]-Timings[10]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+ for j:=0 to 40 do
+ if Data[j]>=Data[k] then k:=j;
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+20) and (CTime<=STime+22) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+20 then begin
+ j:=CTime-Stime;
+ glscalef(j*j/400,j*j/400,j*j/400);
+ glrotatef(j*18.0,0,0,1);
+ end;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ f:=j*10.0;
+ gltranslatef(f*3,-f,0);
+ glscalef(1+j/10,1+j/10,1+j/10);
+ glrotatef(j*9.0,0,0,1);
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_blindy.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Canni (von links reinschieben, nach rechts oben rausschieben)
+ STime:=Timings[11]-10;
+ Delay:=Timings[12]-Timings[11]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+ for j:=0 to 40 do
+ if Data[j]>=Data[k] then k:=j;
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then begin
+ gltranslatef(((CTime-STime)*21.0)-210,0,0);
+ end;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=(CTime-(STime+Delay-10))*21;
+ gltranslatef(j,-j/2,0);
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_canni.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Commandio (von unten reinklappen, nach rechts oben rausklappen)
+ STime:=Timings[12]-10;
+ Delay:=Timings[13]-Timings[12];
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+ for j:=0 to 40 do
+ if Data[j]>=Data[k] then k:=j;
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then
+ f:=258.0-25.8*(CTime-STime)
+ else
+ f:=0;
+ g:=0;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ g:=32.6*j;
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_commandio.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163+g-f*1.5, -129+f*1.5-g/2);
+ glTexCoord2f(0,1);glVertex2f(-163+g*1.5, 129-(g*1.5*258/326));
+ glTexCoord2f(1,1); glVertex2f(163+g, 129+g/4);
+ glTexCoord2f(1,0);glVertex2f(163+f*1.5+g/4, -129+f*1.5-g/4);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// lazy joker (just scrolls from left to right, no twinkling stars, no on-beat flashing)
+ STime:=Timings[13]-35;
+ Delay:=Timings[14]-Timings[13]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ for j:=0 to 40 do
+ if Data[j]>=Data[k] then k:=j;
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)>10) and ((CTime-STime)<20) then ESC_Alpha:=20;
+ ESC_Alpha:=10;
+ f:=CTime-STime;
+ if CTime <=STime+40 then j:=CTime-STime else j:=40;
+ if (CTime >=STime+Delay-40) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j*j/1600);
+
+ glPushMatrix;
+ gltranslatef(180+(f-70),329,0);
+ glBindTexture(GL_TEXTURE_2D, credits_lazyjoker.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Mog (von links reinklappen, nach rechts unten rausklappen)
+ STime:=Timings[14]-10;
+ Delay:=Timings[15]-Timings[14]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+ for j:=0 to 40 do
+ if Data[j]>=Data[k] then k:=j;
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then
+ f:=326.0-32.6*(CTime-STime)
+ else
+ f:=0;
+
+ g:=0;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ g:=32.6*j;
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_mog.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163+g*1.5, -129+g*1.5);
+ glTexCoord2f(0,1);glVertex2f(-163+g*1.2, 129+g);
+ glTexCoord2f(1,1); glVertex2f(163-f+g/2, 129+f*1.5+g/4);
+ glTexCoord2f(1,0);glVertex2f(163-f+g*1.5, -129-f*1.5);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Mota (von rechts oben reindrehen, nach links unten rausschieben und verkleinern und dabei drehen)
+ STime:=Timings[15]-10;
+ Delay:=Timings[16]-Timings[15]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+ for j:=0 to 40 do
+ if Data[j]>=Data[k] then k:=j;
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then begin
+ gltranslatef(223,0,0);
+ glrotatef((10-(CTime-STime))*9,0,0,1);
+ gltranslatef(-223,0,0);
+ end;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ f:=j*10.0;
+ gltranslatef(-f*2,-f,0);
+ glscalef(1-j/10,1-j/10,1-j/10);
+ glrotatef(-j*9.0,0,0,1);
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_mota.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// Skillmaster (von rechts unten reinschieben, nach rechts oben rausdrehen)
+ STime:=Timings[16]-10;
+ Delay:=Timings[17]-Timings[16]+5;
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+ for j:=0 to 40 do
+ if Data[j]>=Data[k] then k:=j;
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then begin
+ j:=STime+10-CTime;
+ f:=j*10.0;
+ gltranslatef(+f*2,+f/2,0);
+ end;
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ gltranslatef(0,-223,0);
+ glrotatef(integer(j)*-9,0,0,1);
+ gltranslatef(0,223,0);
+ glrotatef(j*9,0,0,1);
+ end;
+ glBindTexture(GL_TEXTURE_2D, credits_skillmaster.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163, -129);
+ glTexCoord2f(0,1);glVertex2f(-163, 129);
+ glTexCoord2f(1,1); glVertex2f(163, 129);
+ glTexCoord2f(1,0);glVertex2f(163, -129);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+// WhiteShark (von links unten reinklappen, nach rechts oben rausklappen)
+ STime:=Timings[17]-10;
+ Delay:=Timings[18]-Timings[17];
+ if CTime > STime then
+ begin
+ k:=0;
+ ESC_Alpha:=20;
+ for j:=0 to 40 do
+ if Data[j]>=Data[k] then k:=j;
+ if Data[k]>0.25 then ESC_Alpha:=5 else inc(ESC_Alpha);
+ if ESC_Alpha >20 then ESC_Alpha:=20;
+ if ((CTime-STime)<20) then ESC_Alpha:=20;
+ if CTime <=STime+10 then j:=CTime-STime else j:=10;
+ if (CTime >=STime+Delay-10) then if (CTime <=STime+Delay) then j:=(STime+Delay)-CTime else j:=0;
+ glColor4f(1, 1, 1, ESC_Alpha/20*j/10);
+
+ if (CTime >= STime+10) and (CTime<=STime+12) then begin
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 0);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 1);
+ GoldenRec.Spawn(RandomRange(65,390), RandomRange(200,460), 1, 16, 0, -1, PerfectLineTwinkle, 5);
+ end;
+
+ glPushMatrix;
+ gltranslatef(223,329,0);
+ if CTime <= STime+10 then
+ f:=326.0-32.6*(CTime-STime)
+ else
+ f:=0;
+
+ if CTime >=STime+Delay-10 then if CTime <=STime+Delay then begin
+ j:=CTime-(STime+Delay-10);
+ g:=32.6*j;
+ end else
+ g:=0;
+ glBindTexture(GL_TEXTURE_2D, credits_whiteshark.TexNum);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(-163-f+g, -129+f/4-g/2);
+ glTexCoord2f(0,1);glVertex2f(-163-f/4+g, 129+g/2+f/4);
+ glTexCoord2f(1,1); glVertex2f(163-f*1.2+g/4, 129+f/2-g/4);
+ glTexCoord2f(1,0);glVertex2f(163-f*1.5+g/4, -129+f*1.5+g/4);
+ glEnd;
+ gldisable(gl_texture_2d);
+ gldisable(GL_BLEND);
+ glPopMatrix;
+ end;
+
+
+// ####################################################################
+// do some twinkle stuff (kinda on beat)
+ if (CTime>Timings[8]) and (CTime < Timings[19]) then begin
+ k:=0;
+ for j:=0 to 40 do
+ if Data[j]>=Data[k] then k:=j;
+ if Data[k]>0.2 then begin
+ l:=RandomRange(6,16);
+ j:=RandomRange(0,27);
+ GoldenRec.Spawn(myLogoCoords[j,0], myLogoCoords[j,1], 16-l, l, 0, -1, PerfectNote, 0);
+ end;
+ end;
+
+//#################################################
+// draw the rest of the main screen (girl and logo
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glColor4f(1, 1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, credits_bg_ovl.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(800-393, 0);
+ glTexCoord2f(0,600/1024);glVertex2f(800-393, 600);
+ glTexCoord2f(393/512,600/1024); glVertex2f(800, 600);
+ glTexCoord2f(393/512,0);glVertex2f(800, 0);
+ glEnd;
+{ glBindTexture(GL_TEXTURE_2D, credits_bg_logo.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(0, 0);
+ glTexCoord2f(0,112/128);glVertex2f(0, 112);
+ glTexCoord2f(497/512,112/128); glVertex2f(497, 112);
+ glTexCoord2f(497/512,0);glVertex2f(497, 0);
+ glEnd;
+}
+ gldisable(gl_texture_2d);
+ glDisable(GL_BLEND);
+
+ // fade out at end of main part
+ if Ctime > Timings[19] then
+ begin
+ glColor4f(0,0,0,(Ctime-Timings[19])/(Timings[20]-Timings[19]));
+ glEnable(GL_BLEND);
+ glBegin(GL_QUADS);
+ glVertex2f(0,0);
+ glVertex2f(0,600);
+ glVertex2f(800,600);
+ glVertex2f(800,0);
+ glEnd;
+ glDisable(GL_BLEND);
+ end;
+ end
+ else
+ if (CRDTS_Stage=Outro) then
+ begin
+ if CTime=Timings[20] then begin
+ CTime_hold:=0;
+ Music.Stop;
+ Music.Open(soundpath + 'credits-outro-tune.mp3');
+ Music.Play;
+ Music.SetVolume(20);
+ Music.SetLoop(True);
+ end;
+ if CTime_hold > 231 then begin
+ Music.Play;
+ Ctime_hold:=0;
+ end;
+ glClearColor(0,0,0,0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+
+ // do something useful
+ // outro background
+ glEnable(GL_TEXTURE_2D);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+
+ glColor4f(1, 1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, outro_bg.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(0, 0);
+ glTexCoord2f(0,600/1024);glVertex2f(0, 600);
+ glTexCoord2f(800/1024,600/1024); glVertex2f(800, 600);
+ glTexCoord2f(800/1024,0);glVertex2f(800, 0);
+ glEnd;
+
+ //outro overlays
+ glColor4f(1, 1, 1, (1+sin(CTime/15))/3+1/3);
+ glBindTexture(GL_TEXTURE_2D, outro_esc.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(0, 0);
+ glTexCoord2f(0,223/256);glVertex2f(0, 223);
+ glTexCoord2f(487/512,223/256); glVertex2f(487, 223);
+ glTexCoord2f(487/512,0);glVertex2f(487, 0);
+ glEnd;
+
+ ESC_Alpha:=20;
+ if (RandomRange(0,20) > 18) and (ESC_Alpha=20) then
+ ESC_Alpha:=0
+ else inc(ESC_Alpha);
+ if ESC_Alpha > 20 then ESC_Alpha:=20;
+ glColor4f(1, 1, 1, ESC_Alpha/20);
+ glBindTexture(GL_TEXTURE_2D, outro_exd.TexNum);
+ glbegin(gl_quads);
+ glTexCoord2f(0,0);glVertex2f(800-310, 600-247);
+ glTexCoord2f(0,247/256);glVertex2f(800-310, 600);
+ glTexCoord2f(310/512,247/256); glVertex2f(800, 600);
+ glTexCoord2f(310/512,0);glVertex2f(800, 600-247);
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+
+ // outro scrollers?
+ // ...
+ end;
+
+{ // draw credits runtime counter
+ SetFontStyle (2);
+ SetFontItalic(False);
+ SetFontSize(9);
+ SetFontPos (5, 5);
+ glColor4f(1, 1, 1, 1);
+// RuntimeStr:='CTime: '+inttostr(floor(CTime/30.320663991914489602156136106092))+'.'+inttostr(floor(CTime/3.0320663991914489602156136106092)-floor(CTime/30.320663991914489602156136106092)*10);
+ RuntimeStr:='CTime: '+inttostr(CTime);
+ glPrint (Addr(RuntimeStr[1]));
+}
+ // make the stars shine
+ GoldenRec.Draw;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenMain.pas b/Game/Code/Screens/UScreenMain.pas
index 5af3d4a6..7bcc9e65 100644
--- a/Game/Code/Screens/UScreenMain.pas
+++ b/Game/Code/Screens/UScreenMain.pas
@@ -1,276 +1,278 @@
-unit UScreenMain;
-
-interface
-
-uses
- UMenu,
- SDL,
- UDisplay,
- UMusic,
- UFiles,
- SysUtils,
- UThemes,
- ULCD,
- ULight;
-
-type
- TScreenMain = class(TMenu)
- public
- TextDescription: integer;
- TextDescriptionLong: integer;
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure InteractNext; override;
- procedure InteractPrev; override;
- procedure InteractInc; override;
- procedure InteractDec; override;
- procedure UpdateLCD;
- procedure SetAnimationProgress(Progress: real); override;
- //function Draw: boolean; override;
- end;
-
-implementation
-
-uses Windows,
- UGraphic,
- UMain,
- UIni,
- UTexture,
- USongs,
- Textgl,
-// opengl,
- ULanguage,
- UParty,
- UDLLManager,
- UScreenCredits,
- USkins;
-
-
-function TScreenMain.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
-var
-I: Integer;
-SDL_ModState: Word;
-begin
- Result := true;
-
- SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
- + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT);
-
- //Deactivate Credits when Key is pressed
-// if Credits_Visible then
-// begin
-// Credits_Visible := False;
-// exit;
-// end;
-
- If (PressedDown) Then
- begin // Key Down
- case PressedKey of
- SDLK_Q:
- begin
- Result := false;
- end;
-
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- Result := False;
- end;
-
- SDLK_C:
- begin
- if (SDL_ModState = KMOD_LALT) then
- begin
- //Credits_Y := 600;
- //Credits_Alpha := 0;
- //Credits_Visible := True;
- Music.PlayStart;
- FadeTo(@ScreenCredits);
- end;
- end;
- SDLK_M:
- begin
- if (Ini.Players >= 1) AND (Length(DLLMan.Plugins)>=1) then
- begin
- Music.PlayStart;
- FadeTo(@ScreenPartyOptions);
- end;
- end;
-
- SDLK_S:
- begin
- Music.PlayStart;
- FadeTo(@ScreenStatMain);
- end;
-
- SDLK_E:
- begin
- Music.PlayStart;
- FadeTo(@ScreenEdit);
- end;
-
- SDLK_RETURN:
- begin
- //Solo
- if (Interaction = 0) then
- begin
- if (Length(Songs.Song) >= 1) then
- begin
- Music.PlayStart;
- if (Ini.Players >= 0) and (Ini.Players <= 3) then PlayersPlay := Ini.Players + 1;
- if (Ini.Players = 4) then PlayersPlay := 6;
-
- ScreenName.Goto_SingScreen := False;
- FadeTo(@ScreenName);
- end
- else //show error message
- ScreenPopupError.ShowPopup(Language.Translate('ERROR_NO_SONGS'));
- end;
-
- //Multi
- if Interaction = 1 then begin
- if (Length(Songs.Song) >= 1) then
- begin
- if (Length(DLLMan.Plugins)>=1) then
- begin
- Music.PlayStart;
- FadeTo(@ScreenPartyOptions);
- end
- else //show error message, No Plugins Loaded
- ScreenPopupError.ShowPopup(Language.Translate('ERROR_NO_PLUGINS'));
- end
- else //show error message, No Songs Loaded
- ScreenPopupError.ShowPopup(Language.Translate('ERROR_NO_SONGS'));
- end;
-
- //Stats
- if Interaction = 2 then begin
- Music.PlayStart;
- FadeTo(@ScreenStatMain);
- end;
-
- //Editor
- if Interaction = 3 then begin
- Music.PlayStart;
- FadeTo(@ScreenEdit);
- end;
-
- //Options
- if Interaction = 4 then begin
- Music.PlayStart;
- FadeTo(@ScreenOptions);
- end;
-
- //Exit
- if Interaction = 5 then begin
- Result := false;
- end;
- end;
- // Up and Down could be done at the same time,
- // but I don't want to declare variables inside
- // functions like this one, called so many times
- SDLK_DOWN: InteractInc;
- SDLK_UP: InteractDec;
- SDLK_RIGHT: InteractNext;
- SDLK_LEFT: InteractPrev;
- end;
- end
- else // Key Up
- case PressedKey of
- SDLK_RETURN :
- begin
- end;
- end;
-end;
-
-constructor TScreenMain.Create;
-var
- I: integer;
-begin
- inherited Create;
-
- //----------------
- //Attention ^^:
- //New Creation Order needed because of LoadFromTheme
- //and Button Collections.
- //At First Custom Texts and Statics
- //Then LoadFromTheme
- //after LoadFromTheme the Buttons and Selects
- //----------------
-
-
- TextDescription := AddText(Theme.Main.TextDescription);
- TextDescriptionLong := AddText(Theme.Main.TextDescriptionLong);
-
- LoadFromTheme(Theme.Main);
-
- AddButton(Theme.Main.ButtonSolo);
- AddButton(Theme.Main.ButtonMulti);
- AddButton(Theme.Main.ButtonStat);
- AddButton(Theme.Main.ButtonEditor);
- AddButton(Theme.Main.ButtonOptions);
- AddButton(Theme.Main.ButtonExit);
-
- Interaction := 0;
-end;
-
-procedure TScreenMain.onShow;
-begin
- LCD.WriteText(1, ' Choose mode: ');
- UpdateLCD;
-end;
-
-procedure TScreenMain.InteractNext;
-begin
- inherited InteractNext;
- Text[TextDescription].Text := Theme.Main.Description[Interaction];
- Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
- UpdateLCD;
- Light.LightOne(1, 200);
-end;
-
-procedure TScreenMain.InteractPrev;
-begin
- inherited InteractPrev;
- Text[TextDescription].Text := Theme.Main.Description[Interaction];
- Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
- UpdateLCD;
- Light.LightOne(0, 200);
-end;
-
-procedure TScreenMain.InteractDec;
-begin
- inherited InteractDec;
- Text[TextDescription].Text := Theme.Main.Description[Interaction];
- Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
- UpdateLCD;
- Light.LightOne(0, 200);
-end;
-
-procedure TScreenMain.InteractInc;
-begin
- inherited InteractInc;
- Text[TextDescription].Text := Theme.Main.Description[Interaction];
- Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
- UpdateLCD;
- Light.LightOne(1, 200);
-end;
-
-procedure TScreenMain.UpdateLCD;
-begin
- case Interaction of
- 0: LCD.WriteText(2, ' sing ');
- 1: LCD.WriteText(2, ' editor ');
- 2: LCD.WriteText(2, ' options ');
- 3: LCD.WriteText(2, ' exit ');
- end
-end;
-
-procedure TScreenMain.SetAnimationProgress(Progress: real);
-begin
- Static[0].Texture.ScaleW := Progress;
- Static[0].Texture.ScaleH := Progress;
-end;
-end.
+unit UScreenMain;
+
+interface
+
+uses
+ UMenu,
+ SDL,
+ UDisplay,
+ UMusic,
+ UFiles,
+ SysUtils,
+ UThemes,
+ ULCD,
+ ULight;
+
+type
+ TScreenMain = class(TMenu)
+ public
+ TextDescription: integer;
+ TextDescriptionLong: integer;
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure InteractNext; override;
+ procedure InteractPrev; override;
+ procedure InteractInc; override;
+ procedure InteractDec; override;
+ procedure UpdateLCD;
+ procedure SetAnimationProgress(Progress: real); override;
+ //function Draw: boolean; override;
+ end;
+
+implementation
+
+uses {$IFDEF win32}
+ windows,
+ {$ENDIF}
+ UGraphic,
+ UMain,
+ UIni,
+ UTexture,
+ USongs,
+ Textgl,
+// opengl,
+ ULanguage,
+ UParty,
+ UDLLManager,
+ UScreenCredits,
+ USkins;
+
+
+function TScreenMain.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+var
+I: Integer;
+SDL_ModState: Word;
+begin
+ Result := true;
+
+ SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT);
+
+ //Deactivate Credits when Key is pressed
+// if Credits_Visible then
+// begin
+// Credits_Visible := False;
+// exit;
+// end;
+
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ Result := False;
+ end;
+
+ SDLK_C:
+ begin
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ //Credits_Y := 600;
+ //Credits_Alpha := 0;
+ //Credits_Visible := True;
+ Music.PlayStart;
+ FadeTo(@ScreenCredits);
+ end;
+ end;
+ SDLK_M:
+ begin
+ if (Ini.Players >= 1) AND (Length(DLLMan.Plugins)>=1) then
+ begin
+ Music.PlayStart;
+ FadeTo(@ScreenPartyOptions);
+ end;
+ end;
+
+ SDLK_S:
+ begin
+ Music.PlayStart;
+ FadeTo(@ScreenStatMain);
+ end;
+
+ SDLK_E:
+ begin
+ Music.PlayStart;
+ FadeTo(@ScreenEdit);
+ end;
+
+ SDLK_RETURN:
+ begin
+ //Solo
+ if (Interaction = 0) then
+ begin
+ if (Length(Songs.Song) >= 1) then
+ begin
+ Music.PlayStart;
+ if (Ini.Players >= 0) and (Ini.Players <= 3) then PlayersPlay := Ini.Players + 1;
+ if (Ini.Players = 4) then PlayersPlay := 6;
+
+ ScreenName.Goto_SingScreen := False;
+ FadeTo(@ScreenName);
+ end
+ else //show error message
+ ScreenPopupError.ShowPopup(Language.Translate('ERROR_NO_SONGS'));
+ end;
+
+ //Multi
+ if Interaction = 1 then begin
+ if (Length(Songs.Song) >= 1) then
+ begin
+ if (Length(DLLMan.Plugins)>=1) then
+ begin
+ Music.PlayStart;
+ FadeTo(@ScreenPartyOptions);
+ end
+ else //show error message, No Plugins Loaded
+ ScreenPopupError.ShowPopup(Language.Translate('ERROR_NO_PLUGINS'));
+ end
+ else //show error message, No Songs Loaded
+ ScreenPopupError.ShowPopup(Language.Translate('ERROR_NO_SONGS'));
+ end;
+
+ //Stats
+ if Interaction = 2 then begin
+ Music.PlayStart;
+ FadeTo(@ScreenStatMain);
+ end;
+
+ //Editor
+ if Interaction = 3 then begin
+ Music.PlayStart;
+ FadeTo(@ScreenEdit);
+ end;
+
+ //Options
+ if Interaction = 4 then begin
+ Music.PlayStart;
+ FadeTo(@ScreenOptions);
+ end;
+
+ //Exit
+ if Interaction = 5 then begin
+ Result := false;
+ end;
+ end;
+ // Up and Down could be done at the same time,
+ // but I don't want to declare variables inside
+ // functions like this one, called so many times
+ SDLK_DOWN: InteractInc;
+ SDLK_UP: InteractDec;
+ SDLK_RIGHT: InteractNext;
+ SDLK_LEFT: InteractPrev;
+ end;
+ end
+ else // Key Up
+ case PressedKey of
+ SDLK_RETURN :
+ begin
+ end;
+ end;
+end;
+
+constructor TScreenMain.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ //----------------
+ //Attention ^^:
+ //New Creation Order needed because of LoadFromTheme
+ //and Button Collections.
+ //At First Custom Texts and Statics
+ //Then LoadFromTheme
+ //after LoadFromTheme the Buttons and Selects
+ //----------------
+
+
+ TextDescription := AddText(Theme.Main.TextDescription);
+ TextDescriptionLong := AddText(Theme.Main.TextDescriptionLong);
+
+ LoadFromTheme(Theme.Main);
+
+ AddButton(Theme.Main.ButtonSolo);
+ AddButton(Theme.Main.ButtonMulti);
+ AddButton(Theme.Main.ButtonStat);
+ AddButton(Theme.Main.ButtonEditor);
+ AddButton(Theme.Main.ButtonOptions);
+ AddButton(Theme.Main.ButtonExit);
+
+ Interaction := 0;
+end;
+
+procedure TScreenMain.onShow;
+begin
+ LCD.WriteText(1, ' Choose mode: ');
+ UpdateLCD;
+end;
+
+procedure TScreenMain.InteractNext;
+begin
+ inherited InteractNext;
+ Text[TextDescription].Text := Theme.Main.Description[Interaction];
+ Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
+ UpdateLCD;
+ Light.LightOne(1, 200);
+end;
+
+procedure TScreenMain.InteractPrev;
+begin
+ inherited InteractPrev;
+ Text[TextDescription].Text := Theme.Main.Description[Interaction];
+ Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
+ UpdateLCD;
+ Light.LightOne(0, 200);
+end;
+
+procedure TScreenMain.InteractDec;
+begin
+ inherited InteractDec;
+ Text[TextDescription].Text := Theme.Main.Description[Interaction];
+ Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
+ UpdateLCD;
+ Light.LightOne(0, 200);
+end;
+
+procedure TScreenMain.InteractInc;
+begin
+ inherited InteractInc;
+ Text[TextDescription].Text := Theme.Main.Description[Interaction];
+ Text[TextDescriptionLong].Text := Theme.Main.DescriptionLong[Interaction];
+ UpdateLCD;
+ Light.LightOne(1, 200);
+end;
+
+procedure TScreenMain.UpdateLCD;
+begin
+ case Interaction of
+ 0: LCD.WriteText(2, ' sing ');
+ 1: LCD.WriteText(2, ' editor ');
+ 2: LCD.WriteText(2, ' options ');
+ 3: LCD.WriteText(2, ' exit ');
+ end
+end;
+
+procedure TScreenMain.SetAnimationProgress(Progress: real);
+begin
+ Static[0].Texture.ScaleW := Progress;
+ Static[0].Texture.ScaleH := Progress;
+end;
+end.
diff --git a/Game/Code/Screens/UScreenSing.pas b/Game/Code/Screens/UScreenSing.pas
index 1dd31ae9..343a2e6d 100644
--- a/Game/Code/Screens/UScreenSing.pas
+++ b/Game/Code/Screens/UScreenSing.pas
@@ -1,1236 +1,1256 @@
-unit UScreenSing;
-
-interface
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-
-uses UMenu, UMusic, SDL, SysUtils, UFiles, UTime, USongs, UIni, ULog, UTexture, ULyrics,
- TextGL, OpenGL12, BASS, UThemes, ULCD, UGraphicClasses, UVideo;
-
-type
- TScreenSing = class(TMenu)
- protected
- paused: boolean; //Pause Mod
- PauseTime: Real;
- NumEmptySentences: integer;
- public
- //TextTime: integer;
-
- //TimeBar mod
- StaticTimeProgress: integer;
- TextTimeText: integer;
- //eoa TimeBar mod
-
- StaticP1: integer;
- StaticP1ScoreBG: integer;
- TextP1: integer;
- TextP1Score: integer;
-
- //moveable singbar mod
- StaticP1SingBar: integer;
- StaticP1ThreePSingBar: integer;
- StaticP1TwoPSingBar: integer;
- StaticP2RSingBar: integer;
- StaticP2MSingBar: integer;
- StaticP3SingBar: integer;
- //eoa moveable singbar
-
- //Added for ps3 skin
- //shown when game is in 2/4 player modus
- StaticP1TwoP: integer;
- StaticP1TwoPScoreBG: integer;
- TextP1TwoP: integer;
- TextP1TwoPScore: integer;
- //shown when game is in 3/6 player modus
- StaticP1ThreeP: integer;
- StaticP1ThreePScoreBG: integer;
- TextP1ThreeP: integer;
- TextP1ThreePScore: integer;
- //eoa
-
- StaticP2R: integer;
- StaticP2RScoreBG: integer;
- TextP2R: integer;
- TextP2RScore: integer;
-
- StaticP2M: integer;
- StaticP2MScoreBG: integer;
- TextP2M: integer;
- TextP2MScore: integer;
-
- StaticP3R: integer;
- StaticP3RScoreBG: integer;
- TextP3R: integer;
- TextP3RScore: integer;
-
- Tex_Background: TTexture;
- FadeOut: boolean;
- LyricMain: TLyric;
- LyricSub: TLyric;
-
- constructor Create; override;
- procedure onShow; override;
- procedure onShowFinish; override;
- function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
- function Draw: boolean; override;
- procedure Finish; virtual;
- procedure UpdateLCD;
- procedure Pause; //Pause Mod(Toggles Pause)
-
- //OnSentenceEnd for LineBonus + Singbar
- procedure onSentenceEnd(S: Cardinal);
- //OnSentenceChange (for Golden Notes)
- procedure onSentenceChange(S: Cardinal);
- end;
-
-implementation
-uses UGraphic, UDraw, UMain, Classes, URecord, ULanguage, math;
-
-// Method for input parsing. If False is returned, GetNextWindow
-// should be checked to know the next window to load;
-function TScreenSing.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- case PressedKey of
- SDLK_Q:
- begin
- //When not ask before Exit then Finish now
- if (Ini.AskbeforeDel <> 1) then
- Finish
- //else just Pause and let the Popup make the Work
- else if not paused then
- Pause;
-
- Result := false;
- end;
-
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- //Record Sound Hack:
- //Sound[0].BufferLong
-
- Finish;
- Music.PlayBack;
- FadeTo(@ScreenScore);
- end;
-
- SDLK_P://Pause Mod
- begin
- Pause;
- end;
-
- SDLK_RETURN:
- begin
- end;
-
- // Up and Down could be done at the same time,
- // but I don't want to declare variables inside
- // functions like this one, called so many times
- SDLK_DOWN :
- begin
- end;
- SDLK_UP :
- begin
- end;
- end;
- end;
-end;
-
-//Pause Mod
-procedure TScreenSing.Pause;
-begin
- if not paused then //Pause einschalten
- begin
- // pause Time
- PauseTime := Czas.Teraz;
- Paused := true;
-
- // pause Music
- Music.Pause;
-
- // pause Video
- if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then
- FFmpegTogglePause;
- end
- else //Pause ausschalten
- begin
- Czas.Teraz := PauseTime; //Position of Notes
-
- // Position of Music
- Music.MoveTo (PauseTime);
- // Play Music
- Music.Play;
-
- // Video
- if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then
- FFmpegTogglePause;
- //SkipSmpeg(PauseTime);
-
- Paused := false;
- end;
-end;
-//Pause Mod End
-
-constructor TScreenSing.Create;
-var
- I: integer;
- P: integer;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.Sing);
-
- //TimeBar
- StaticTimeProgress := AddStatic(Theme.Sing.StaticTimeProgress);
- TextTimeText := AddText(Theme.Sing.TextTimeText);
-
-// 1 player | P1
- StaticP1 := AddStatic(Theme.Sing.StaticP1);
- StaticP1ScoreBG := AddStatic(Theme.Sing.StaticP1ScoreBG);
- TextP1 := AddText(Theme.Sing.TextP1);
- TextP1Score := AddText(Theme.Sing.TextP1Score);
- StaticP1SingBar := AddStatic(Theme.Sing.StaticP1SingBar);
-
-// 2 or 4 players | P1
- StaticP1TwoP := AddStatic(Theme.Sing.StaticP1TwoP);
- StaticP1TwoPScoreBG := AddStatic(Theme.Sing.StaticP1TwoPScoreBG);
- TextP1TwoP := AddText(Theme.Sing.TextP1TwoP);
- TextP1TwoPScore := AddText(Theme.Sing.TextP1TwoPScore);
- StaticP1TwoPSingBar := AddStatic(Theme.Sing.StaticP2RSingBar);
-
- // | P2
- StaticP2R := AddStatic(Theme.Sing.StaticP2R);
- StaticP2RScoreBG := AddStatic(Theme.Sing.StaticP2RScoreBG);
- TextP2R := AddText(Theme.Sing.TextP2R);
- TextP2RScore := AddText(Theme.Sing.TextP2RScore);
- StaticP2RSingBar := AddStatic(Theme.Sing.StaticP2RSingBar);
-
-// 3 or 6 players | P1
- StaticP1ThreeP := AddStatic(Theme.Sing.StaticP1ThreeP);
- StaticP1ThreePScoreBG := AddStatic(Theme.Sing.StaticP1ThreePScoreBG);
- TextP1ThreeP := AddText(Theme.Sing.TextP1ThreeP);
- TextP1ThreePScore := AddText(Theme.Sing.TextP1ThreePScore);
- StaticP1ThreePSingBar := AddStatic(Theme.Sing.StaticP1ThreePSingBar);
-
- // | P2
- StaticP2M := AddStatic(Theme.Sing.StaticP2M);
- StaticP2MScoreBG := AddStatic(Theme.Sing.StaticP2MScoreBG);
- TextP2M := AddText(Theme.Sing.TextP2M);
- TextP2MScore := AddText(Theme.Sing.TextP2MScore);
- StaticP2MSingBar := AddStatic(Theme.Sing.StaticP2MSingBar);
-
- // | P3
- StaticP3R := AddStatic(Theme.Sing.StaticP3R);
- StaticP3RScoreBG := AddStatic(Theme.Sing.StaticP3RScoreBG);
- TextP3R := AddText(Theme.Sing.TextP3R);
- TextP3RScore := AddText(Theme.Sing.TextP3RScore);
- StaticP3SingBar := AddStatic(Theme.Sing.StaticP3SingBar);
-
- if ScreenAct = 2 then begin
- // katze und affe
-
- end;
-
- LyricMain := TLyric.Create;
- LyricSub := TLyric.Create;
-
- UVideo.Init;
-end;
-
-procedure TScreenSing.onShow;
-var
- P: integer;
- V1: boolean;
- V1TwoP: boolean; //added for ps3 skin
- V1ThreeP: boolean; //added for ps3 skin
- V2R: boolean;
- V2M: boolean;
- V3R: boolean;
- NR: TRecR; //Line Bonus Mod
-begin
- Log.LogStatus('Begin', 'onShow');
- FadeOut := false; // 0.5.0: early 0.5.0 problems were by this line commented
-
- // prepare players
- SetLength(Player, PlayersPlay);
-// Player[0].ScoreTotalI := 0;
-
- case PlayersPlay of
- 1: begin
- V1 := true;
- V1TwoP := false;
- V1ThreeP := false;
- V2R := false;
- V2M := false;
- V3R := false;
- end;
- 2: begin
- V1 := false;
- V1TwoP := true;
- V1ThreeP := false;
- V2R := true;
- V2M := false;
- V3R := false;
- end;
- 3: begin
- V1 := false;
- V1TwoP := false;
- V1ThreeP := true;
- V2R := false;
- V2M := true;
- V3R := true;
- end;
- 4: begin // double screen
- V1 := false;
- V1TwoP := true;
- V1ThreeP := false;
- V2R := true;
- V2M := false;
- V3R := false;
- end;
- 6: begin // double screen
- V1 := false;
- V1TwoP := false;
- V1ThreeP := true;
- V2R := false;
- V2M := true;
- V3R := true;
- end;
-
- end;
-
- //This one is shown in 1P mode
- Static[StaticP1].Visible := V1;
- Static[StaticP1ScoreBG].Visible := V1;
- Text[TextP1].Visible := V1;
- Text[TextP1Score].Visible := V1;
-
-
- //This one is shown in 2/4P mode
- Static[StaticP1TwoP].Visible := V1TwoP;
- Static[StaticP1TwoPScoreBG].Visible := V1TwoP;
- Text[TextP1TwoP].Visible := V1TwoP;
- Text[TextP1TwoPScore].Visible := V1TwoP;
-
- Static[StaticP2R].Visible := V2R;
- Static[StaticP2RScoreBG].Visible := V2R;
- Text[TextP2R].Visible := V2R;
- Text[TextP2RScore].Visible := V2R;
-
-
- //This one is shown in 3/6P mode
- Static[StaticP1ThreeP].Visible := V1ThreeP;
- Static[StaticP1ThreePScoreBG].Visible := V1ThreeP;
- Text[TextP1ThreeP].Visible := V1ThreeP;
- Text[TextP1ThreePScore].Visible := V1ThreeP;
-
- Static[StaticP2M].Visible := V2M;
- Static[StaticP2MScoreBG].Visible := V2M;
- Text[TextP2M].Visible := V2M;
- Text[TextP2MScore].Visible := V2M;
-
- Static[StaticP3R].Visible := V3R;
- Static[StaticP3RScoreBG].Visible := V3R;
- Text[TextP3R].Visible := V3R;
- Text[TextP3RScore].Visible := V3R;
-
- // load notes
- ResetSingTemp;
-// Log.LogWarning(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName, '!!!');
- AktSong := CatSongs.Song[CatSongs.Selected];
- try
- if not LoadSong(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName) then
- begin
- //Error Loading Song -> Go back to Song Screen and Show some Error Message
- FadeTo(@ScreenSong);
- //Select New Song in Party Mode
- if ScreenSong.Mode = 1 then
- ScreenSong.SelectRandomSong;
- ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG'));
- Exit;
- end;
- except
- //Error Loading Song -> Go back to Song Screen and Show some Error Message
- FadeTo(@ScreenSong);
- //Select New Song in Party Mode
- if ScreenSong.Mode = 1 then
- ScreenSong.SelectRandomSong;
- ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG'));
- Exit;
- end;
- AktSong.Path := CatSongs.Song[CatSongs.Selected].Path;
-// AktSong.GAP := AktSong.GAP + 40 {4096 = 100ms for buffer} + 20 {microphone} + 60000 / AktSong.BPM[0].BPM / 2; // temporary until UMain will be fixed
-
- // set movie
- if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then begin
-(* OpenSmpeg(AktSong.Path + AktSong.Video);
- SkipSmpeg(AktSong.VideoGAP + AktSong.Start);*)
-
- // todo: VideoGap and Start time verwursten
- FFmpegOpenFile(pAnsiChar(AktSong.Path + AktSong.Video));
- FFmpegSkip(AktSong.VideoGAP + AktSong.Start);
- AktSong.VideoLoaded := true;
- end;
-
- // set background
- if (AktSong.Background <> '') and (AktSong.VideoLoaded = false) then
- try
- Tex_Background := Texture.LoadTexture(AktSong.Path + AktSong.Background);
- except
- log.LogError('Background could not be loaded: ' + AktSong.Path + AktSong.Background);
- Tex_Background.TexNum := -1;
- end
- else
- Tex_Background.TexNum := -1;
-
-
-
- // play music (I)
- Music.CaptureStart;
- Music.MoveTo(AktSong.Start);
-// Music.Play;
-
- // prepare timer (I)
-// CountSkipTimeSet;
- Czas.Teraz := AktSong.Start;
- Czas.Razem := Music.Length;
- if (AktSong.Finish > 0) then Czas.Razem := AktSong.Finish / 1000;
- Czas.OldBeat := -1;
- for P := 0 to High(Player) do
- ClearScores(P);
-
- // main text
- LyricMain.Clear;
- LyricMain.X := 400;
- LyricMain.Y := Skin_LyricsT;
- LyricMain.Scale := 1.4; //1.4
- LyricMain.Align := 1;
-
- // sub text
- LyricSub.Clear;
- LyricSub.X := 400;
- LyricSub.Y := Skin_LyricsT + 35; //42 //40
- LyricSub.Align := 1;
-
- // set custom options
- case Ini.LyricsFont of
- 0:
- begin
- LyricMain.FontStyle := 0;
- LyricSub.FontStyle := 0;
- LyricMain.Size := 14; // 13
- LyricSub.Size := 14; // 13
- LyricMain.ColR := Skin_FontR;
- LyricMain.ColG := Skin_FontG;
- LyricMain.ColB := Skin_FontB; //Change für Crazy Joker
- {LyricMain.ColSR := Skin_FontHighlightR;
- LyricMain.ColSG := Skin_FontHighlightG;
- LyricMain.ColSB := Skin_FontHighlightB;1aa5dc}
- LyricMain.ColSR := 5/255; //26
- LyricMain.ColSG := 163/255; //165
- LyricMain.ColSB := 210/255; //220
-
- LyricSub.ColR := 0.4; //0.6
- LyricSub.ColG := 0.4; //0.6
- LyricSub.ColB := 0.4; //0.6
- end;
- 1:
- begin
- LyricMain.FontStyle := 2;
- LyricSub.FontStyle := 2;
- LyricMain.Size := 14;
- LyricSub.Size := 14;
- LyricMain.ColR := 0.75;
- LyricMain.ColG := 0.75;
- LyricMain.ColB := 1;
- LyricMain.ColSR := 0.5;
- LyricMain.ColSG := 0.5;
- LyricMain.ColSB := 1;
- LyricSub.ColR := 0.8;
- LyricSub.ColG := 0.8;
- LyricSub.ColB := 0.8;
- end;
- 2:
- begin
- LyricMain.FontStyle := 3;
- LyricSub.FontStyle := 3;
- LyricMain.Size := 12;
- LyricSub.Size := 12;
- LyricMain.ColR := 0.75;
- LyricMain.ColG := 0.75;
- LyricMain.ColB := 1;
- LyricMain.ColSR := 0.5;
- LyricMain.ColSG := 0.5;
- LyricMain.ColSB := 1;
- LyricSub.ColR := 0.8;
- LyricSub.ColG := 0.8;
- LyricSub.ColB := 0.8;
- end;
- end; // case
-
- case Ini.LyricsEffect of
- 0: LyricMain.Style := 1; // 0 - one selected, 1 - selected all to the current
- 1: LyricMain.Style := 2;
- 2: LyricMain.Style := 3;
- 3: LyricMain.Style := 4;
- end; // case
-
- // fill texts
- LyricMain.AddCzesc(0);
- LyricMain.Selected := -1;
- LyricSub.AddCzesc(1);
- LyricSub.Selected := -1;
-
- UpdateLCD;
-
- //Deactivate Pause
- Paused := False;
-
- //Kill all Stars not Killed yet
- //GoldenStarsTwinkle Mod
- GoldenRec.SentenceChange;
- //GoldenStarsTwinkle Mod End
-
- //Set Position of Line Bonus - PhrasenBonus
- if (Ini.LineBonus = 1) then //Show Line Bonus at Scores
- begin
- Case PlayersPlay of
- 1: begin
- Player[0].LineBonus_TargetX := Theme.Sing.StaticP1ScoreBG.x;
- Player[0].LineBonus_TargetY := Theme.Sing.TextP1Score.Y;
- Player[0].LineBonus_StartX := Theme.Sing.StaticP1ScoreBG.x;
- Player[0].LineBonus_StartY := Theme.Sing.TextP1Score.Y + 65;
- end;
-
- 2: begin
- //P1
- Player[0].LineBonus_TargetX := Theme.Sing.StaticP1TwoPScoreBG.x;
- Player[0].LineBonus_TargetY := Theme.Sing.TextP1TwoPScore.Y;
- Player[0].LineBonus_StartX := Theme.Sing.StaticP1TwoPScoreBG.X;
- Player[0].LineBonus_StartY := Theme.Sing.TextP1TwoPScore.Y + 65;
-
- //P2
- Player[1].LineBonus_TargetX := Theme.Sing.StaticP2RScoreBG.X;
- Player[1].LineBonus_TargetY := Theme.Sing.TextP2RScore.Y;
- Player[1].LineBonus_StartX := Theme.Sing.StaticP2RScoreBG.X;
- Player[1].LineBonus_StartY := Theme.Sing.TextP2RScore.Y + 65;
- end;
-
- 3: begin
- //P1
- Player[0].LineBonus_TargetX := Theme.Sing.StaticP1ThreePScoreBG.x;
- Player[0].LineBonus_TargetY := Theme.Sing.TextP1ThreePScore.Y;
- Player[0].LineBonus_StartX := Theme.Sing.StaticP1ThreePScoreBG.x;
- Player[0].LineBonus_StartY := Theme.Sing.TextP1ThreePScore.Y + 65;
-
- //P2
- Player[1].LineBonus_TargetX := Theme.Sing.StaticP2MScoreBG.x;
- Player[1].LineBonus_TargetY := Theme.Sing.TextP2MScore.Y;
- Player[1].LineBonus_StartX := Theme.Sing.StaticP2MScoreBG.x;
- Player[1].LineBonus_StartY := Theme.Sing.TextP2MScore.Y + 65;
-
- //P3
- Player[2].LineBonus_TargetX := Theme.Sing.StaticP3RScoreBG.x;
- Player[2].LineBonus_TargetY := Theme.Sing.TextP3RScore.Y;
- Player[2].LineBonus_StartX := Theme.Sing.StaticP3RScoreBG.x;
- Player[2].LineBonus_StartY := Theme.Sing.TextP3RScore.Y + 65;
- end;
-
- 4: begin
- //P1
- Player[0].LineBonus_TargetX := Theme.Sing.StaticP1TwoPScoreBG.x;
- Player[0].LineBonus_TargetY := Theme.Sing.TextP1TwoPScore.Y;
- Player[0].LineBonus_StartX := Theme.Sing.StaticP1TwoPScoreBG.x;
- Player[0].LineBonus_StartY := Theme.Sing.TextP1TwoPScore.Y + 65;
-
- //P2
- Player[1].LineBonus_TargetX := Theme.Sing.StaticP2RScoreBG.x;
- Player[1].LineBonus_TargetY := Theme.Sing.TextP2RScore.Y;
- Player[1].LineBonus_StartX := Theme.Sing.StaticP2RScoreBG.x;
- Player[1].LineBonus_StartY := Theme.Sing.TextP2RScore.Y + 65;
-
- //P3
- Player[2].LineBonus_TargetX := Theme.Sing.StaticP1TwoPScoreBG.x;
- Player[2].LineBonus_TargetY := Theme.Sing.TextP1TwoPScore.Y;
- Player[2].LineBonus_StartX := Theme.Sing.StaticP1TwoPScoreBG.x;
- Player[2].LineBonus_StartY := Theme.Sing.TextP1TwoPScore.Y + 65;
-
- //P4
- Player[3].LineBonus_TargetX := Theme.Sing.StaticP2RScoreBG.x;
- Player[3].LineBonus_TargetY := Theme.Sing.TextP2RScore.Y;
- Player[3].LineBonus_StartX := Theme.Sing.StaticP2RScoreBG.x;
- Player[3].LineBonus_StartY := Theme.Sing.TextP2RScore.Y + 65;
- end;
-
- 6: begin
- //P1
- Player[0].LineBonus_TargetX := Theme.Sing.StaticP1ThreePScoreBG.x;
- Player[0].LineBonus_TargetY := Theme.Sing.TextP1ThreePScore.Y;
- Player[0].LineBonus_StartX := Theme.Sing.StaticP1ThreePScoreBG.x;
- Player[0].LineBonus_StartY := Theme.Sing.TextP1ThreePScore.Y + 65;
-
- //P2
- Player[1].LineBonus_TargetX := Theme.Sing.StaticP2MScoreBG.x;
- Player[1].LineBonus_TargetY := Theme.Sing.TextP2MScore.Y;
- Player[1].LineBonus_StartX := Theme.Sing.StaticP2MScoreBG.x;
- Player[1].LineBonus_StartY := Theme.Sing.TextP2MScore.Y + 65;
-
- //P3
- Player[2].LineBonus_TargetX := Theme.Sing.StaticP3RScoreBG.x;
- Player[2].LineBonus_TargetY := Theme.Sing.TextP3RScore.Y;
- Player[2].LineBonus_StartX := Theme.Sing.StaticP3RScoreBG.x;
- Player[2].LineBonus_StartY := Theme.Sing.TextP3RScore.Y + 65;
-
- //P4
- Player[3].LineBonus_TargetX := Theme.Sing.StaticP1ThreePScoreBG.x;
- Player[3].LineBonus_TargetY := Theme.Sing.TextP1ThreePScore.Y;
- Player[3].LineBonus_StartX := Theme.Sing.StaticP1ThreePScoreBG.x;
- Player[3].LineBonus_StartY := Theme.Sing.TextP1ThreePScore.Y + 65;
-
- //P5
- Player[4].LineBonus_TargetX := Theme.Sing.StaticP2MScoreBG.x;
- Player[4].LineBonus_TargetY := Theme.Sing.TextP2MScore.Y;
- Player[4].LineBonus_StartX := Theme.Sing.StaticP2MScoreBG.x;
- Player[4].LineBonus_StartY := Theme.Sing.TextP2MScore.Y + 65;
-
- //P6
- Player[5].LineBonus_TargetX := Theme.Sing.StaticP3RScoreBG.x;
- Player[5].LineBonus_TargetY := Theme.Sing.TextP3RScore.Y;
- Player[5].LineBonus_StartX := Theme.Sing.StaticP3RScoreBG.x;
- Player[5].LineBonus_StartY := Theme.Sing.TextP3RScore.Y + 65;
- end;
- end;
- end
- else if (Ini.LineBonus = 2) then //Show Line Bonus at Notes
- begin
-
- // positions
- if Ini.SingWindow = 0 then begin
- NR.Left := 120;
- end else begin
- NR.Left := 20;
- end;
- NR.Right := 780;
-
- NR.Width := NR.Right - NR.Left;
- NR.WMid := NR.Width / 2;
- NR.Mid := NR.Left + NR.WMid;
-
- Case PlayersPlay of
- 1: begin
- Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65;
- Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_StartY := Skin_P2_NotesB - 105;
- end;
-
- 2: begin
- //P1
- Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
- Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
-
- //P2
- Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
- Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
- end;
-
- 3: begin
- //P1
- Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_TargetY := 120 - 65 + 28;
- Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_StartY := 120 + 28;
-
- //P2
- Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_TargetY := 245 - 65 + 28;
- Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_StartY := 245 + 28;
-
- //P3
- Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[2].LineBonus_TargetY := 370 - 65 + 28;
- Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[2].LineBonus_StartY := 370 + 28;
- end;
-
- 4: begin
- //P1
- Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
- Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
-
- //P2
- Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
- Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
-
- //P3
- Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[2].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
- Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[2].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
-
- //P4
- Player[3].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[3].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
- Player[3].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[3].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
- end;
-
- 6: begin
- //P1
- Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_TargetY := 120 - 65 + 28;
- Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[0].LineBonus_StartY := 120 + 28;
-
- //P2
- Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_TargetY := 245 - 65 + 28;
- Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[1].LineBonus_StartY := 245 + 28;
-
- //P3
- Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[2].LineBonus_TargetY := 370 - 65 + 28;
- Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[2].LineBonus_StartY := 370 + 28;
-
- //P4
- Player[3].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[3].LineBonus_TargetY := 120 - 65 + 28;
- Player[3].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[3].LineBonus_StartY := 120 + 28;
-
- //P5
- Player[4].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[4].LineBonus_TargetY := 245 - 65 + 28;
- Player[4].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[4].LineBonus_StartY := 245 + 28;
-
- //P6
- Player[5].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
- Player[5].LineBonus_TargetY := 370 - 65 + 28;
- Player[5].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
- Player[5].LineBonus_StartY := 370 + 28;
- end;
- end;
- end;
- //Set Position of Line Bonus - PhrasenBonus End
- //Set Num of Empty Sentences for Phrasen Bonus
- NumEmptySentences := 0;
- for P := low(Czesci[0].Czesc) to high(Czesci[0].Czesc) do
- if Czesci[0].Czesc[P].TotalNotes = 0 then Inc(NumEmptySentences);
-
- Log.LogStatus('End', 'onShow');
-end;
-
-procedure TScreenSing.onShowFinish;
-begin
- // play movie (II)
-
- if AktSong.VideoLoaded then
- begin
- try
- FFmpegGetFrame(Czas.Teraz);
- FFmpegDrawGL(ScreenAct);
-// PlaySmpeg;
- except
- //If an Error occurs Reading Video: prevent Video from being Drawn again and Close Video
- AktSong.VideoLoaded := False;
- Log.LogError('Error drawing Video, Video has been disabled for this Song/Session.');
- Log.LogError('Corrupted File: ' + AktSong.Video);
- try
-// CloseSmpeg;
- FFmpegClose;
- except
-
- end;
- end;
- end;
-
- // play music (II)
- Music.Play;
-
- // prepare timer (II)
- CountSkipTimeSet;
-end;
-
-function TScreenSing.Draw: boolean;
-var
- Min: integer;
- Sec: integer;
- Tekst: string;
- Flash: real;
- S: integer;
- T: integer;
-begin
-
-
-
- //ScoreBG Mod | den wirren Scheiss hier brauch mer nimmer, wir haben colorized png's - no need for wirrness also
- // set player colors - macht nichts weiter als die farben des statics zu wechseln, was zu unschönen effekten bei colorized png führt
-{ if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
- Static[StaticP1TwoP].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P2Dark');
-
- LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
- Static[StaticP1TwoPScoreBG].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
- end;
- if ScreenAct = 2 then begin
- LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
- Static[StaticP1TwoP].Texture.ColB, 'P3Dark');
- LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P4Dark');
-
- LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
- Static[StaticP1TwoPScoreBG].Texture.ColB, 'P3Dark');
- LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P4Dark');
- end;
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
- Static[StaticP1ThreeP].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P2Dark');
- LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
- Static[StaticP3R].Texture.ColB, 'P3Dark');
-
- LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
- Static[StaticP1ThreePScoreBG].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
- LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
- Static[StaticP3RScoreBG].Texture.ColB, 'P3Dark');
- end;
- if ScreenAct = 2 then begin
-
- LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
- Static[StaticP1ThreeP].Texture.ColB, 'P4Dark');
- LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P5Dark');
- LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
- Static[StaticP3R].Texture.ColB, 'P6Dark');
-
-
- LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
- Static[StaticP1ThreePScoreBG].Texture.ColB, 'P4Dark');
- LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P5Dark');
- LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
- Static[StaticP3RScoreBG].Texture.ColB, 'P6Dark');
- end;
- end;
- }
-
- // set player names (for 2 screens and only Singstar skin)
- if ScreenAct = 1 then begin
- Text[TextP1].Text := 'P1';
- Text[TextP1TwoP].Text := 'P1';
- Text[TextP1ThreeP].Text := 'P1';
- Text[TextP2R].Text := 'P2';
- Text[TextP2M].Text := 'P2';
- Text[TextP3R].Text := 'P3';
- end;
-
- if ScreenAct = 2 then begin
- case PlayersPlay of
-{ 1: begin
- Text[TextP1].Text := 'P2';
- end;
- 2: begin
- Text[TextP1].Text := 'P3';
- Text[TextP2R].Text := 'P4';
- end;
- 3: begin
- Text[TextP1].Text := 'P4';
- Text[TextP2M].Text := 'P5';
- Text[TextP3R].Text := 'P6';
- end;}
-
- 4: begin
- Text[TextP1TwoP].Text := 'P3';
- Text[TextP2R].Text := 'P4';
- end;
- 6: begin
- Text[TextP1ThreeP].Text := 'P4';
- Text[TextP2M].Text := 'P5';
- Text[TextP3R].Text := 'P6';
- end;
- end; // case
- end; // if
-
- // stereo
-
-// weird stuff, maybe this is for "dual screen?", but where is player three then? | okay, i commented the stuff out the other day - nothing was missing on screen w/ 6 players - so do we even need this stuff?
-// okay this stuff appears again some lines beneath this one, I commented it out for testing what it does - seems like it's doing nothing
-// but I might be wrong, so what is this stuff here doing? O.o
- Static[StaticP1].Texture.X := Static[StaticP1].Texture.X + 10*ScreenX;
- Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X + 10*ScreenX;
-
- Text[TextP1].X := Text[TextP1].X + 10*ScreenX;
- Text[TextP1Score].X := Text[TextP1Score].X + 10*ScreenX;
-
-
- Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X + 10*ScreenX;
- Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X + 10*ScreenX;
-
- Text[TextP2R].X := Text[TextP2R].X + 10*ScreenX;
- Text[TextP2RScore].X := Text[TextP2RScore].X + 10*ScreenX;
-// end of weird stuff
-
- for S := 1 to 1 do //wtf?
- Static[S].Texture.X := Static[S].Texture.X + 10*ScreenX;
-
- for T := 0 to 1 do
- Text[T].X := Text[T].X + 10*ScreenX;
-
- // update static menu with time ...
- Min := Round(Czas.Teraz) div 60;
- Sec := Round(Czas.Teraz) mod 60;
- Text[TextTimeText].Text := '';
- if Min < 10 then Text[TextTimeText].Text := '0';
- Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Min) + ':';
- if Sec < 10 then Text[TextTimeText].Text := Text[TextTimeText].Text + '0';
- Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Sec);
-
- // .. and scores
- if PlayersPlay = 1 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1Score].Text := Tekst;
- end;
-
- if PlayersPlay = 2 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1TwoPScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2RScore].Text := Tekst;
- end;
-
- if PlayersPlay = 3 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1ThreePScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2MScore].Text := Tekst;
-
- Tekst := IntToStr(Player[2].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP3RScore].Text := Tekst;
- end;
-
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1TwoPScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2RScore].Text := Tekst;
- end;
- if ScreenAct = 2 then begin
- Tekst := IntToStr(Player[2].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1TwoPScore].Text := Tekst;
-
- Tekst := IntToStr(Player[3].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2RScore].Text := Tekst;
- end;
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1ThreePScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2MScore].Text := Tekst;
-
- Tekst := IntToStr(Player[2].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP3RScore].Text := Tekst;
- end;
- if ScreenAct = 2 then begin
- Tekst := IntToStr(Player[3].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1ThreePScore].Text := Tekst;
-
- Tekst := IntToStr(Player[4].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2MScore].Text := Tekst;
-
- Tekst := IntToStr(Player[5].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP3RScore].Text := Tekst;
- end;
- end;
-
- // draw static menu (BG)
- DrawBG;
- //Draw Background
- SingDrawBackground;
- // update and draw movie
- if ShowFinish and AktSong.VideoLoaded then begin
- try
-// UpdateSmpeg; // this only draws
- // todo: find a way to determine, when a new frame is needed
- // toto: same for the need to skip frames
- FFmpegGetFrame(Czas.Teraz);
- FFmpegDrawGL(ScreenAct);
- except
- //If an Error occurs drawing: prevent Video from being Drawn again and Close Video
- AktSong.VideoLoaded := False;
- log.LogError('Error drawing Video, Video has been disabled for this Song/Session.');
- Log.LogError('Corrupted File: ' + AktSong.Video);
- try
-// CloseSmpeg;
- FFmpegClose;
- except
-
- end;
- end;
- end;
-
- // draw static menu (FG)
- DrawFG;
-
- // check for music finish
-// Log.LogError('Check for music finish: ' + BoolToStr(Music.Finished) + ' ' + FloatToStr(Czas.Teraz*1000) + ' ' + IntToStr(AktSong.Finish));
- if ShowFinish then begin
- if (not Music.Finished) and ((AktSong.Finish = 0) or (Czas.Teraz*1000 <= AktSong.Finish)) then begin
- //Pause Mod:
- if not Paused then
- Sing(Self); // analyze song
- end else begin
-// Log.LogError('End');
- if not FadeOut then begin
-// Log.LogError('End2');
- Finish;
- FadeOut := true;
- FadeTo(@ScreenScore);
- end;
- end;
- end;
-
- // draw custom items
- SingDraw; // always draw
-
-//GoldenNoteStarsTwinkle Mod
- GoldenRec.SpawnRec;
-//GoldenNoteStarsTwinkle Mod
-
- // back stereo
-
-// weird stuff, maybe this is for "dual screen?", but where is player three then?
-// okay this stuff appears again some lines above this one, I commented it out for testing what it does - seems like it's doing nothing
-// but I might be wrong, so what is this stuff here doing? O.o
- Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10*ScreenX;
- Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X - 10*ScreenX;
-
- Text[TextP1].X := Text[TextP1].X - 10*ScreenX;
- Text[TextP1Score].X := Text[TextP1Score].X - 10*ScreenX;
-
-
- Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X - 10*ScreenX;
- Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X - 10*ScreenX;
-
- Text[TextP2R].X := Text[TextP2R].X - 10*ScreenX;
- Text[TextP2RScore].X := Text[TextP2RScore].X - 10*ScreenX;
-//weird end
-
- for S := 1 to 1 do // wtf?
- Static[S].Texture.X := Static[S].Texture.X - 10*ScreenX;
-
- for T := 0 to 1 do
- Text[T].X := Text[T].X - 10*ScreenX;
-
-end;
-
-procedure TScreenSing.Finish;
-begin
- Music.CaptureStop;
- Music.Stop;
-
- if Ini.SavePlayback = 1 then begin
- Log.BenchmarkStart(0);
- Log.LogVoice(0);
- Log.LogVoice(1);
- Log.LogVoice(2);
- Log.BenchmarkEnd(0);
- Log.LogBenchmark('Creating files', 0);
- end;
-
- if AktSong.VideoLoaded then begin
-// CloseSmpeg;
- FFmpegClose;
- AktSong.VideoLoaded := false; // to prevent drawing closed video
- end;
-
- SetFontItalic (False);
-end;
-
-procedure TScreenSing.UpdateLCD;
-var
- T: string;
-begin
- LCD.HideCursor;
- LCD.Clear;
-
- T := LyricMain.Text;
- if Copy(T, Length(T), 1) <> ' ' then T := T + ' ';
- LCD.AddTextBR(T);
-
- T := LyricSub.Text;
- if Copy(T, Length(T), 1) <> ' ' then T := T + ' ';
- LCD.AddTextBR(T);
-end;
-
-procedure TScreenSing.onSentenceEnd(S: Cardinal);
-var
-I: Integer;
-A: Real;
-B: integer; //Max Points for Notes
-begin
-
- //Check for Empty Sentence
- if (Czesci[0].Czesc[S].TotalNotes<=0) then
- exit;
-
- //Set Max Note Points
- if (Ini.LineBonus > 0) then
- B := 9000
- else
- B := 10000;
-
- for I := 0 to High(Player) do begin
- A := Player[I].Score + Player[I].ScoreGolden - Player[I].ScoreLast + 2;
-
- //SingBar Mod
- If ({(Ini.Oscilloscope = 2) and }(Czesci[0].Czesc[S].TotalNotes>0)) then
- begin
- Player[I].ScorePercentTarget := Player[I].ScorePercentTarget + floor(A / (B * Czesci[0].Czesc[S].TotalNotes / Czesci[0].Wartosc) * 40 - 26);
- if Player[I].ScorePercentTarget < 0 then Player[I].ScorePercentTarget := 0;
- if Player[I].ScorePercentTarget > 99 then Player[I].ScorePercentTarget := 99;
-
- //end Singbar Mod
- end;
-
- //PhrasenBonus - Line Bonus Mod
-
- //Generate Steps 0 to 8
- A := Floor(A / (B * Czesci[0].Czesc[S].TotalNotes / Czesci[0].Wartosc) * 8);
-
- If (Ini.LineBonus > 0) then
- begin
-
- //Generate Text
- if A >= 8 then
- Player[I].LineBonus_Text := Theme.Sing.LineBonusText[8]
- else
- Player[I].LineBonus_Text := Theme.Sing.LineBonusText[Floor(A)];
-
- //PhrasenBonus give Points
- Player[I].ScoreLine := Player[I].ScoreLine + (1000 / (Length(Czesci[0].Czesc) - NumEmptySentences) * A / 8);
- Player[I].ScoreLineI := Round(Player[I].ScoreLine / 10) * 10;
- //Update Total Score
- Player[I].ScoreTotalI := Player[I].ScoreI + Player[I].ScoreGoldenI + Player[I].ScoreLineI;
-
- //Color
- Case Floor(A) of
- 0: begin
- Player[I].LineBonus_Color.R := 1;
- Player[I].LineBonus_Color.G := 0;
- Player[I].LineBonus_Color.B := 0;
- end;
- 1..3: begin
- Player[I].LineBonus_Color.R := 1;
- Player[I].LineBonus_Color.G := (A * 0.25);
- Player[I].LineBonus_Color.B := 0;
- end;
- 4: begin
- Player[I].LineBonus_Color.R := 1;
- Player[I].LineBonus_Color.G := 1;
- Player[I].LineBonus_Color.B := 0;
- end;
- 5..7: begin
- Player[I].LineBonus_Color.R := 1-((a-4)*0.25);
- Player[I].LineBonus_Color.G := 1;
- Player[I].LineBonus_Color.B := 0;
- end;
- 8: begin
- Player[I].LineBonus_Color.R := 0;
- Player[I].LineBonus_Color.G := 1;
- Player[I].LineBonus_Color.B := 0;
- end;
- End; //Case
- //Player[I].LineBonus_Color.B := 0;
- //Player[I].LineBonus_Color.R := (8-A)/8;
- //Player[I].LineBonus_Color.G := A/10;
-
- Player[I].LineBonus_PosX := Player[I].LineBonus_StartX;
- Player[I].LineBonus_PosY := Player[I].LineBonus_StartY;
- Player[I].LineBonus_Alpha := 0.92;
- Player[I].LineBonus_Visible := True;
- Player[I].LineBonus_Age := 1;
- end;
- //PhrasenBonus - Line Bonus Mod End// }
-
- //PerfectLineTwinkle Mod (effect) Pt.1
- If (Ini.EffectSing=1) then
- begin
- if A >= 8 then Player[I].LastSentencePerfect := True
- else Player[I].LastSentencePerfect := False;
- end;
- //PerfectLineTwinkle Mod end
-
- //Refresh LastScore
- Player[I].ScoreLast := Player[I].Score + Player[I].ScoreGolden;
-
- end;
-
- //PerfectLineTwinkle Mod (effect) Pt.2
- if Ini.EffectSing=1 then
- GoldenRec.SpawnPerfectLineTwinkle;
- //PerfectLineTwinkle Mod end
-end;
-
-//Called on Sentence Change S= New Current Sentence
-procedure TScreenSing.onSentenceChange(S: Cardinal);
-begin
- //GoldenStarsTwinkle Mod
- GoldenRec.SentenceChange;
- //GoldenStarsTwinkle Mod End
-end;
-
-end.
+unit UScreenSing;
+
+interface
+
+{$I switches.inc}
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+{$ENDIF}
+
+
+uses UMenu,
+ UMusic,
+ SDL,
+ SysUtils,
+ UFiles,
+ UTime,
+ USongs,
+ UIni,
+ ULog,
+ UTexture,
+ ULyrics,
+ TextGL,
+ OpenGL12,
+ {$IFDEF useBASS}
+ bass,
+ {$ENDIF}
+ UThemes,
+ ULCD,
+ UGraphicClasses,
+ UVideo;
+
+type
+ TScreenSing = class(TMenu)
+ protected
+ paused: boolean; //Pause Mod
+ PauseTime: Real;
+ NumEmptySentences: integer;
+ public
+ //TextTime: integer;
+
+ //TimeBar mod
+ StaticTimeProgress: integer;
+ TextTimeText: integer;
+ //eoa TimeBar mod
+
+ StaticP1: integer;
+ StaticP1ScoreBG: integer;
+ TextP1: integer;
+ TextP1Score: integer;
+
+ //moveable singbar mod
+ StaticP1SingBar: integer;
+ StaticP1ThreePSingBar: integer;
+ StaticP1TwoPSingBar: integer;
+ StaticP2RSingBar: integer;
+ StaticP2MSingBar: integer;
+ StaticP3SingBar: integer;
+ //eoa moveable singbar
+
+ //Added for ps3 skin
+ //shown when game is in 2/4 player modus
+ StaticP1TwoP: integer;
+ StaticP1TwoPScoreBG: integer;
+ TextP1TwoP: integer;
+ TextP1TwoPScore: integer;
+ //shown when game is in 3/6 player modus
+ StaticP1ThreeP: integer;
+ StaticP1ThreePScoreBG: integer;
+ TextP1ThreeP: integer;
+ TextP1ThreePScore: integer;
+ //eoa
+
+ StaticP2R: integer;
+ StaticP2RScoreBG: integer;
+ TextP2R: integer;
+ TextP2RScore: integer;
+
+ StaticP2M: integer;
+ StaticP2MScoreBG: integer;
+ TextP2M: integer;
+ TextP2MScore: integer;
+
+ StaticP3R: integer;
+ StaticP3RScoreBG: integer;
+ TextP3R: integer;
+ TextP3RScore: integer;
+
+ Tex_Background: TTexture;
+ FadeOut: boolean;
+ LyricMain: TLyric;
+ LyricSub: TLyric;
+
+ constructor Create; override;
+ procedure onShow; override;
+ procedure onShowFinish; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+ procedure Finish; virtual;
+ procedure UpdateLCD;
+ procedure Pause; //Pause Mod(Toggles Pause)
+
+ //OnSentenceEnd for LineBonus + Singbar
+ procedure onSentenceEnd(S: Cardinal);
+ //OnSentenceChange (for Golden Notes)
+ procedure onSentenceChange(S: Cardinal);
+ end;
+
+implementation
+uses UGraphic, UDraw, UMain, Classes, URecord, ULanguage, math;
+
+// Method for input parsing. If False is returned, GetNextWindow
+// should be checked to know the next window to load;
+function TScreenSing.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_Q:
+ begin
+ //When not ask before Exit then Finish now
+ if (Ini.AskbeforeDel <> 1) then
+ Finish
+ //else just Pause and let the Popup make the Work
+ else if not paused then
+ Pause;
+
+ Result := false;
+ end;
+
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ //Record Sound Hack:
+ //Sound[0].BufferLong
+
+ Finish;
+ Music.PlayBack;
+ FadeTo(@ScreenScore);
+ end;
+
+ SDLK_P://Pause Mod
+ begin
+ Pause;
+ end;
+
+ SDLK_RETURN:
+ begin
+ end;
+
+ // Up and Down could be done at the same time,
+ // but I don't want to declare variables inside
+ // functions like this one, called so many times
+ SDLK_DOWN :
+ begin
+ end;
+ SDLK_UP :
+ begin
+ end;
+ end;
+ end;
+end;
+
+//Pause Mod
+procedure TScreenSing.Pause;
+begin
+ if not paused then //Pause einschalten
+ begin
+ // pause Time
+ PauseTime := Czas.Teraz;
+ Paused := true;
+
+ // pause Music
+ Music.Pause;
+
+ // pause Video
+ if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then
+ FFmpegTogglePause;
+ end
+ else //Pause ausschalten
+ begin
+ Czas.Teraz := PauseTime; //Position of Notes
+
+ // Position of Music
+ Music.MoveTo (PauseTime);
+ // Play Music
+ Music.Play;
+
+ // Video
+ if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then
+ FFmpegTogglePause;
+ //SkipSmpeg(PauseTime);
+
+ Paused := false;
+ end;
+end;
+//Pause Mod End
+
+constructor TScreenSing.Create;
+var
+ I: integer;
+ P: integer;
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.Sing);
+
+ //TimeBar
+ StaticTimeProgress := AddStatic(Theme.Sing.StaticTimeProgress);
+ TextTimeText := AddText(Theme.Sing.TextTimeText);
+
+// 1 player | P1
+ StaticP1 := AddStatic(Theme.Sing.StaticP1);
+ StaticP1ScoreBG := AddStatic(Theme.Sing.StaticP1ScoreBG);
+ TextP1 := AddText(Theme.Sing.TextP1);
+ TextP1Score := AddText(Theme.Sing.TextP1Score);
+ StaticP1SingBar := AddStatic(Theme.Sing.StaticP1SingBar);
+
+// 2 or 4 players | P1
+ StaticP1TwoP := AddStatic(Theme.Sing.StaticP1TwoP);
+ StaticP1TwoPScoreBG := AddStatic(Theme.Sing.StaticP1TwoPScoreBG);
+ TextP1TwoP := AddText(Theme.Sing.TextP1TwoP);
+ TextP1TwoPScore := AddText(Theme.Sing.TextP1TwoPScore);
+ StaticP1TwoPSingBar := AddStatic(Theme.Sing.StaticP2RSingBar);
+
+ // | P2
+ StaticP2R := AddStatic(Theme.Sing.StaticP2R);
+ StaticP2RScoreBG := AddStatic(Theme.Sing.StaticP2RScoreBG);
+ TextP2R := AddText(Theme.Sing.TextP2R);
+ TextP2RScore := AddText(Theme.Sing.TextP2RScore);
+ StaticP2RSingBar := AddStatic(Theme.Sing.StaticP2RSingBar);
+
+// 3 or 6 players | P1
+ StaticP1ThreeP := AddStatic(Theme.Sing.StaticP1ThreeP);
+ StaticP1ThreePScoreBG := AddStatic(Theme.Sing.StaticP1ThreePScoreBG);
+ TextP1ThreeP := AddText(Theme.Sing.TextP1ThreeP);
+ TextP1ThreePScore := AddText(Theme.Sing.TextP1ThreePScore);
+ StaticP1ThreePSingBar := AddStatic(Theme.Sing.StaticP1ThreePSingBar);
+
+ // | P2
+ StaticP2M := AddStatic(Theme.Sing.StaticP2M);
+ StaticP2MScoreBG := AddStatic(Theme.Sing.StaticP2MScoreBG);
+ TextP2M := AddText(Theme.Sing.TextP2M);
+ TextP2MScore := AddText(Theme.Sing.TextP2MScore);
+ StaticP2MSingBar := AddStatic(Theme.Sing.StaticP2MSingBar);
+
+ // | P3
+ StaticP3R := AddStatic(Theme.Sing.StaticP3R);
+ StaticP3RScoreBG := AddStatic(Theme.Sing.StaticP3RScoreBG);
+ TextP3R := AddText(Theme.Sing.TextP3R);
+ TextP3RScore := AddText(Theme.Sing.TextP3RScore);
+ StaticP3SingBar := AddStatic(Theme.Sing.StaticP3SingBar);
+
+ if ScreenAct = 2 then begin
+ // katze und affe
+
+ end;
+
+ LyricMain := TLyric.Create;
+ LyricSub := TLyric.Create;
+
+ UVideo.Init;
+end;
+
+procedure TScreenSing.onShow;
+var
+ P: integer;
+ V1: boolean;
+ V1TwoP: boolean; //added for ps3 skin
+ V1ThreeP: boolean; //added for ps3 skin
+ V2R: boolean;
+ V2M: boolean;
+ V3R: boolean;
+ NR: TRecR; //Line Bonus Mod
+begin
+ Log.LogStatus('Begin', 'onShow');
+ FadeOut := false; // 0.5.0: early 0.5.0 problems were by this line commented
+
+ // prepare players
+ SetLength(Player, PlayersPlay);
+// Player[0].ScoreTotalI := 0;
+
+ case PlayersPlay of
+ 1: begin
+ V1 := true;
+ V1TwoP := false;
+ V1ThreeP := false;
+ V2R := false;
+ V2M := false;
+ V3R := false;
+ end;
+ 2: begin
+ V1 := false;
+ V1TwoP := true;
+ V1ThreeP := false;
+ V2R := true;
+ V2M := false;
+ V3R := false;
+ end;
+ 3: begin
+ V1 := false;
+ V1TwoP := false;
+ V1ThreeP := true;
+ V2R := false;
+ V2M := true;
+ V3R := true;
+ end;
+ 4: begin // double screen
+ V1 := false;
+ V1TwoP := true;
+ V1ThreeP := false;
+ V2R := true;
+ V2M := false;
+ V3R := false;
+ end;
+ 6: begin // double screen
+ V1 := false;
+ V1TwoP := false;
+ V1ThreeP := true;
+ V2R := false;
+ V2M := true;
+ V3R := true;
+ end;
+
+ end;
+
+ //This one is shown in 1P mode
+ Static[StaticP1].Visible := V1;
+ Static[StaticP1ScoreBG].Visible := V1;
+ Text[TextP1].Visible := V1;
+ Text[TextP1Score].Visible := V1;
+
+
+ //This one is shown in 2/4P mode
+ Static[StaticP1TwoP].Visible := V1TwoP;
+ Static[StaticP1TwoPScoreBG].Visible := V1TwoP;
+ Text[TextP1TwoP].Visible := V1TwoP;
+ Text[TextP1TwoPScore].Visible := V1TwoP;
+
+ Static[StaticP2R].Visible := V2R;
+ Static[StaticP2RScoreBG].Visible := V2R;
+ Text[TextP2R].Visible := V2R;
+ Text[TextP2RScore].Visible := V2R;
+
+
+ //This one is shown in 3/6P mode
+ Static[StaticP1ThreeP].Visible := V1ThreeP;
+ Static[StaticP1ThreePScoreBG].Visible := V1ThreeP;
+ Text[TextP1ThreeP].Visible := V1ThreeP;
+ Text[TextP1ThreePScore].Visible := V1ThreeP;
+
+ Static[StaticP2M].Visible := V2M;
+ Static[StaticP2MScoreBG].Visible := V2M;
+ Text[TextP2M].Visible := V2M;
+ Text[TextP2MScore].Visible := V2M;
+
+ Static[StaticP3R].Visible := V3R;
+ Static[StaticP3RScoreBG].Visible := V3R;
+ Text[TextP3R].Visible := V3R;
+ Text[TextP3RScore].Visible := V3R;
+
+ // load notes
+ ResetSingTemp;
+// Log.LogWarning(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName, '!!!');
+ AktSong := CatSongs.Song[CatSongs.Selected];
+ try
+ if not LoadSong(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName) then
+ begin
+ //Error Loading Song -> Go back to Song Screen and Show some Error Message
+ FadeTo(@ScreenSong);
+ //Select New Song in Party Mode
+ if ScreenSong.Mode = 1 then
+ ScreenSong.SelectRandomSong;
+ ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG'));
+ Exit;
+ end;
+ except
+ //Error Loading Song -> Go back to Song Screen and Show some Error Message
+ FadeTo(@ScreenSong);
+ //Select New Song in Party Mode
+ if ScreenSong.Mode = 1 then
+ ScreenSong.SelectRandomSong;
+ ScreenPopupError.ShowPopup (Language.Translate('ERROR_CORRUPT_SONG'));
+ Exit;
+ end;
+ AktSong.Path := CatSongs.Song[CatSongs.Selected].Path;
+// AktSong.GAP := AktSong.GAP + 40 {4096 = 100ms for buffer} + 20 {microphone} + 60000 / AktSong.BPM[0].BPM / 2; // temporary until UMain will be fixed
+
+ // set movie
+ if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then begin
+(* OpenSmpeg(AktSong.Path + AktSong.Video);
+ SkipSmpeg(AktSong.VideoGAP + AktSong.Start);*)
+
+ // todo: VideoGap and Start time verwursten
+ FFmpegOpenFile(pAnsiChar(AktSong.Path + AktSong.Video));
+ FFmpegSkip(AktSong.VideoGAP + AktSong.Start);
+ AktSong.VideoLoaded := true;
+ end;
+
+ // set background
+ if (AktSong.Background <> '') and (AktSong.VideoLoaded = false) then
+ try
+ Tex_Background := Texture.LoadTexture(AktSong.Path + AktSong.Background);
+ except
+ log.LogError('Background could not be loaded: ' + AktSong.Path + AktSong.Background);
+ Tex_Background.TexNum := -1;
+ end
+ else
+ Tex_Background.TexNum := -1;
+
+
+
+ // play music (I)
+ Music.CaptureStart;
+ Music.MoveTo(AktSong.Start);
+// Music.Play;
+
+ // prepare timer (I)
+// CountSkipTimeSet;
+ Czas.Teraz := AktSong.Start;
+ Czas.Razem := Music.Length;
+ if (AktSong.Finish > 0) then Czas.Razem := AktSong.Finish / 1000;
+ Czas.OldBeat := -1;
+ for P := 0 to High(Player) do
+ ClearScores(P);
+
+ // main text
+ LyricMain.Clear;
+ LyricMain.X := 400;
+ LyricMain.Y := Skin_LyricsT;
+ LyricMain.Scale := 1.4; //1.4
+ LyricMain.Align := 1;
+
+ // sub text
+ LyricSub.Clear;
+ LyricSub.X := 400;
+ LyricSub.Y := Skin_LyricsT + 35; //42 //40
+ LyricSub.Align := 1;
+
+ // set custom options
+ case Ini.LyricsFont of
+ 0:
+ begin
+ LyricMain.FontStyle := 0;
+ LyricSub.FontStyle := 0;
+ LyricMain.Size := 14; // 13
+ LyricSub.Size := 14; // 13
+ LyricMain.ColR := Skin_FontR;
+ LyricMain.ColG := Skin_FontG;
+ LyricMain.ColB := Skin_FontB; //Change für Crazy Joker
+ {LyricMain.ColSR := Skin_FontHighlightR;
+ LyricMain.ColSG := Skin_FontHighlightG;
+ LyricMain.ColSB := Skin_FontHighlightB;1aa5dc}
+ LyricMain.ColSR := 5/255; //26
+ LyricMain.ColSG := 163/255; //165
+ LyricMain.ColSB := 210/255; //220
+
+ LyricSub.ColR := 0.4; //0.6
+ LyricSub.ColG := 0.4; //0.6
+ LyricSub.ColB := 0.4; //0.6
+ end;
+ 1:
+ begin
+ LyricMain.FontStyle := 2;
+ LyricSub.FontStyle := 2;
+ LyricMain.Size := 14;
+ LyricSub.Size := 14;
+ LyricMain.ColR := 0.75;
+ LyricMain.ColG := 0.75;
+ LyricMain.ColB := 1;
+ LyricMain.ColSR := 0.5;
+ LyricMain.ColSG := 0.5;
+ LyricMain.ColSB := 1;
+ LyricSub.ColR := 0.8;
+ LyricSub.ColG := 0.8;
+ LyricSub.ColB := 0.8;
+ end;
+ 2:
+ begin
+ LyricMain.FontStyle := 3;
+ LyricSub.FontStyle := 3;
+ LyricMain.Size := 12;
+ LyricSub.Size := 12;
+ LyricMain.ColR := 0.75;
+ LyricMain.ColG := 0.75;
+ LyricMain.ColB := 1;
+ LyricMain.ColSR := 0.5;
+ LyricMain.ColSG := 0.5;
+ LyricMain.ColSB := 1;
+ LyricSub.ColR := 0.8;
+ LyricSub.ColG := 0.8;
+ LyricSub.ColB := 0.8;
+ end;
+ end; // case
+
+ case Ini.LyricsEffect of
+ 0: LyricMain.Style := 1; // 0 - one selected, 1 - selected all to the current
+ 1: LyricMain.Style := 2;
+ 2: LyricMain.Style := 3;
+ 3: LyricMain.Style := 4;
+ end; // case
+
+ // fill texts
+ LyricMain.AddCzesc(0);
+ LyricMain.Selected := -1;
+ LyricSub.AddCzesc(1);
+ LyricSub.Selected := -1;
+
+ UpdateLCD;
+
+ //Deactivate Pause
+ Paused := False;
+
+ //Kill all Stars not Killed yet
+ //GoldenStarsTwinkle Mod
+ GoldenRec.SentenceChange;
+ //GoldenStarsTwinkle Mod End
+
+ //Set Position of Line Bonus - PhrasenBonus
+ if (Ini.LineBonus = 1) then //Show Line Bonus at Scores
+ begin
+ Case PlayersPlay of
+ 1: begin
+ Player[0].LineBonus_TargetX := Theme.Sing.StaticP1ScoreBG.x;
+ Player[0].LineBonus_TargetY := Theme.Sing.TextP1Score.Y;
+ Player[0].LineBonus_StartX := Theme.Sing.StaticP1ScoreBG.x;
+ Player[0].LineBonus_StartY := Theme.Sing.TextP1Score.Y + 65;
+ end;
+
+ 2: begin
+ //P1
+ Player[0].LineBonus_TargetX := Theme.Sing.StaticP1TwoPScoreBG.x;
+ Player[0].LineBonus_TargetY := Theme.Sing.TextP1TwoPScore.Y;
+ Player[0].LineBonus_StartX := Theme.Sing.StaticP1TwoPScoreBG.X;
+ Player[0].LineBonus_StartY := Theme.Sing.TextP1TwoPScore.Y + 65;
+
+ //P2
+ Player[1].LineBonus_TargetX := Theme.Sing.StaticP2RScoreBG.X;
+ Player[1].LineBonus_TargetY := Theme.Sing.TextP2RScore.Y;
+ Player[1].LineBonus_StartX := Theme.Sing.StaticP2RScoreBG.X;
+ Player[1].LineBonus_StartY := Theme.Sing.TextP2RScore.Y + 65;
+ end;
+
+ 3: begin
+ //P1
+ Player[0].LineBonus_TargetX := Theme.Sing.StaticP1ThreePScoreBG.x;
+ Player[0].LineBonus_TargetY := Theme.Sing.TextP1ThreePScore.Y;
+ Player[0].LineBonus_StartX := Theme.Sing.StaticP1ThreePScoreBG.x;
+ Player[0].LineBonus_StartY := Theme.Sing.TextP1ThreePScore.Y + 65;
+
+ //P2
+ Player[1].LineBonus_TargetX := Theme.Sing.StaticP2MScoreBG.x;
+ Player[1].LineBonus_TargetY := Theme.Sing.TextP2MScore.Y;
+ Player[1].LineBonus_StartX := Theme.Sing.StaticP2MScoreBG.x;
+ Player[1].LineBonus_StartY := Theme.Sing.TextP2MScore.Y + 65;
+
+ //P3
+ Player[2].LineBonus_TargetX := Theme.Sing.StaticP3RScoreBG.x;
+ Player[2].LineBonus_TargetY := Theme.Sing.TextP3RScore.Y;
+ Player[2].LineBonus_StartX := Theme.Sing.StaticP3RScoreBG.x;
+ Player[2].LineBonus_StartY := Theme.Sing.TextP3RScore.Y + 65;
+ end;
+
+ 4: begin
+ //P1
+ Player[0].LineBonus_TargetX := Theme.Sing.StaticP1TwoPScoreBG.x;
+ Player[0].LineBonus_TargetY := Theme.Sing.TextP1TwoPScore.Y;
+ Player[0].LineBonus_StartX := Theme.Sing.StaticP1TwoPScoreBG.x;
+ Player[0].LineBonus_StartY := Theme.Sing.TextP1TwoPScore.Y + 65;
+
+ //P2
+ Player[1].LineBonus_TargetX := Theme.Sing.StaticP2RScoreBG.x;
+ Player[1].LineBonus_TargetY := Theme.Sing.TextP2RScore.Y;
+ Player[1].LineBonus_StartX := Theme.Sing.StaticP2RScoreBG.x;
+ Player[1].LineBonus_StartY := Theme.Sing.TextP2RScore.Y + 65;
+
+ //P3
+ Player[2].LineBonus_TargetX := Theme.Sing.StaticP1TwoPScoreBG.x;
+ Player[2].LineBonus_TargetY := Theme.Sing.TextP1TwoPScore.Y;
+ Player[2].LineBonus_StartX := Theme.Sing.StaticP1TwoPScoreBG.x;
+ Player[2].LineBonus_StartY := Theme.Sing.TextP1TwoPScore.Y + 65;
+
+ //P4
+ Player[3].LineBonus_TargetX := Theme.Sing.StaticP2RScoreBG.x;
+ Player[3].LineBonus_TargetY := Theme.Sing.TextP2RScore.Y;
+ Player[3].LineBonus_StartX := Theme.Sing.StaticP2RScoreBG.x;
+ Player[3].LineBonus_StartY := Theme.Sing.TextP2RScore.Y + 65;
+ end;
+
+ 6: begin
+ //P1
+ Player[0].LineBonus_TargetX := Theme.Sing.StaticP1ThreePScoreBG.x;
+ Player[0].LineBonus_TargetY := Theme.Sing.TextP1ThreePScore.Y;
+ Player[0].LineBonus_StartX := Theme.Sing.StaticP1ThreePScoreBG.x;
+ Player[0].LineBonus_StartY := Theme.Sing.TextP1ThreePScore.Y + 65;
+
+ //P2
+ Player[1].LineBonus_TargetX := Theme.Sing.StaticP2MScoreBG.x;
+ Player[1].LineBonus_TargetY := Theme.Sing.TextP2MScore.Y;
+ Player[1].LineBonus_StartX := Theme.Sing.StaticP2MScoreBG.x;
+ Player[1].LineBonus_StartY := Theme.Sing.TextP2MScore.Y + 65;
+
+ //P3
+ Player[2].LineBonus_TargetX := Theme.Sing.StaticP3RScoreBG.x;
+ Player[2].LineBonus_TargetY := Theme.Sing.TextP3RScore.Y;
+ Player[2].LineBonus_StartX := Theme.Sing.StaticP3RScoreBG.x;
+ Player[2].LineBonus_StartY := Theme.Sing.TextP3RScore.Y + 65;
+
+ //P4
+ Player[3].LineBonus_TargetX := Theme.Sing.StaticP1ThreePScoreBG.x;
+ Player[3].LineBonus_TargetY := Theme.Sing.TextP1ThreePScore.Y;
+ Player[3].LineBonus_StartX := Theme.Sing.StaticP1ThreePScoreBG.x;
+ Player[3].LineBonus_StartY := Theme.Sing.TextP1ThreePScore.Y + 65;
+
+ //P5
+ Player[4].LineBonus_TargetX := Theme.Sing.StaticP2MScoreBG.x;
+ Player[4].LineBonus_TargetY := Theme.Sing.TextP2MScore.Y;
+ Player[4].LineBonus_StartX := Theme.Sing.StaticP2MScoreBG.x;
+ Player[4].LineBonus_StartY := Theme.Sing.TextP2MScore.Y + 65;
+
+ //P6
+ Player[5].LineBonus_TargetX := Theme.Sing.StaticP3RScoreBG.x;
+ Player[5].LineBonus_TargetY := Theme.Sing.TextP3RScore.Y;
+ Player[5].LineBonus_StartX := Theme.Sing.StaticP3RScoreBG.x;
+ Player[5].LineBonus_StartY := Theme.Sing.TextP3RScore.Y + 65;
+ end;
+ end;
+ end
+ else if (Ini.LineBonus = 2) then //Show Line Bonus at Notes
+ begin
+
+ // positions
+ if Ini.SingWindow = 0 then begin
+ NR.Left := 120;
+ end else begin
+ NR.Left := 20;
+ end;
+ NR.Right := 780;
+
+ NR.Width := NR.Right - NR.Left;
+ NR.WMid := NR.Width / 2;
+ NR.Mid := NR.Left + NR.WMid;
+
+ Case PlayersPlay of
+ 1: begin
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_StartY := Skin_P2_NotesB - 105;
+ end;
+
+ 2: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
+ end;
+
+ 3: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_TargetY := 120 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_StartY := 120 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_TargetY := 245 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_StartY := 245 + 28;
+
+ //P3
+ Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[2].LineBonus_TargetY := 370 - 65 + 28;
+ Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[2].LineBonus_StartY := 370 + 28;
+ end;
+
+ 4: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
+
+ //P3
+ Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[2].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
+ Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[2].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
+
+ //P4
+ Player[3].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[3].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
+ Player[3].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[3].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
+ end;
+
+ 6: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_TargetY := 120 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[0].LineBonus_StartY := 120 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_TargetY := 245 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[1].LineBonus_StartY := 245 + 28;
+
+ //P3
+ Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[2].LineBonus_TargetY := 370 - 65 + 28;
+ Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[2].LineBonus_StartY := 370 + 28;
+
+ //P4
+ Player[3].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[3].LineBonus_TargetY := 120 - 65 + 28;
+ Player[3].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[3].LineBonus_StartY := 120 + 28;
+
+ //P5
+ Player[4].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[4].LineBonus_TargetY := 245 - 65 + 28;
+ Player[4].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[4].LineBonus_StartY := 245 + 28;
+
+ //P6
+ Player[5].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[5].LineBonus_TargetY := 370 - 65 + 28;
+ Player[5].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 100);
+ Player[5].LineBonus_StartY := 370 + 28;
+ end;
+ end;
+ end;
+ //Set Position of Line Bonus - PhrasenBonus End
+ //Set Num of Empty Sentences for Phrasen Bonus
+ NumEmptySentences := 0;
+ for P := low(Czesci[0].Czesc) to high(Czesci[0].Czesc) do
+ if Czesci[0].Czesc[P].TotalNotes = 0 then Inc(NumEmptySentences);
+
+ Log.LogStatus('End', 'onShow');
+end;
+
+procedure TScreenSing.onShowFinish;
+begin
+ // play movie (II)
+
+ if AktSong.VideoLoaded then
+ begin
+ try
+ FFmpegGetFrame(Czas.Teraz);
+ FFmpegDrawGL(ScreenAct);
+// PlaySmpeg;
+ except
+ //If an Error occurs Reading Video: prevent Video from being Drawn again and Close Video
+ AktSong.VideoLoaded := False;
+ Log.LogError('Error drawing Video, Video has been disabled for this Song/Session.');
+ Log.LogError('Corrupted File: ' + AktSong.Video);
+ try
+// CloseSmpeg;
+ FFmpegClose;
+ except
+
+ end;
+ end;
+ end;
+
+ // play music (II)
+ Music.Play;
+
+ // prepare timer (II)
+ CountSkipTimeSet;
+end;
+
+function TScreenSing.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ Flash: real;
+ S: integer;
+ T: integer;
+begin
+
+
+
+ //ScoreBG Mod | den wirren Scheiss hier brauch mer nimmer, wir haben colorized png's - no need for wirrness also
+ // set player colors - macht nichts weiter als die farben des statics zu wechseln, was zu unschönen effekten bei colorized png führt
+{ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
+ Static[StaticP1TwoP].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P2Dark');
+
+ LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
+ Static[StaticP1TwoPScoreBG].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
+ end;
+ if ScreenAct = 2 then begin
+ LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
+ Static[StaticP1TwoP].Texture.ColB, 'P3Dark');
+ LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P4Dark');
+
+ LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
+ Static[StaticP1TwoPScoreBG].Texture.ColB, 'P3Dark');
+ LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P4Dark');
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
+ Static[StaticP1ThreeP].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P2Dark');
+ LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
+ Static[StaticP3R].Texture.ColB, 'P3Dark');
+
+ LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
+ Static[StaticP1ThreePScoreBG].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
+ LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
+ Static[StaticP3RScoreBG].Texture.ColB, 'P3Dark');
+ end;
+ if ScreenAct = 2 then begin
+
+ LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
+ Static[StaticP1ThreeP].Texture.ColB, 'P4Dark');
+ LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P5Dark');
+ LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
+ Static[StaticP3R].Texture.ColB, 'P6Dark');
+
+
+ LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
+ Static[StaticP1ThreePScoreBG].Texture.ColB, 'P4Dark');
+ LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P5Dark');
+ LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
+ Static[StaticP3RScoreBG].Texture.ColB, 'P6Dark');
+ end;
+ end;
+ }
+
+ // set player names (for 2 screens and only Singstar skin)
+ if ScreenAct = 1 then begin
+ Text[TextP1].Text := 'P1';
+ Text[TextP1TwoP].Text := 'P1';
+ Text[TextP1ThreeP].Text := 'P1';
+ Text[TextP2R].Text := 'P2';
+ Text[TextP2M].Text := 'P2';
+ Text[TextP3R].Text := 'P3';
+ end;
+
+ if ScreenAct = 2 then begin
+ case PlayersPlay of
+{ 1: begin
+ Text[TextP1].Text := 'P2';
+ end;
+ 2: begin
+ Text[TextP1].Text := 'P3';
+ Text[TextP2R].Text := 'P4';
+ end;
+ 3: begin
+ Text[TextP1].Text := 'P4';
+ Text[TextP2M].Text := 'P5';
+ Text[TextP3R].Text := 'P6';
+ end;}
+
+ 4: begin
+ Text[TextP1TwoP].Text := 'P3';
+ Text[TextP2R].Text := 'P4';
+ end;
+ 6: begin
+ Text[TextP1ThreeP].Text := 'P4';
+ Text[TextP2M].Text := 'P5';
+ Text[TextP3R].Text := 'P6';
+ end;
+ end; // case
+ end; // if
+
+ // stereo
+
+// weird stuff, maybe this is for "dual screen?", but where is player three then? | okay, i commented the stuff out the other day - nothing was missing on screen w/ 6 players - so do we even need this stuff?
+// okay this stuff appears again some lines beneath this one, I commented it out for testing what it does - seems like it's doing nothing
+// but I might be wrong, so what is this stuff here doing? O.o
+ Static[StaticP1].Texture.X := Static[StaticP1].Texture.X + 10*ScreenX;
+ Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X + 10*ScreenX;
+
+ Text[TextP1].X := Text[TextP1].X + 10*ScreenX;
+ Text[TextP1Score].X := Text[TextP1Score].X + 10*ScreenX;
+
+
+ Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X + 10*ScreenX;
+ Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X + 10*ScreenX;
+
+ Text[TextP2R].X := Text[TextP2R].X + 10*ScreenX;
+ Text[TextP2RScore].X := Text[TextP2RScore].X + 10*ScreenX;
+// end of weird stuff
+
+ for S := 1 to 1 do //wtf?
+ Static[S].Texture.X := Static[S].Texture.X + 10*ScreenX;
+
+ for T := 0 to 1 do
+ Text[T].X := Text[T].X + 10*ScreenX;
+
+ // update static menu with time ...
+ Min := Round(Czas.Teraz) div 60;
+ Sec := Round(Czas.Teraz) mod 60;
+ Text[TextTimeText].Text := '';
+ if Min < 10 then Text[TextTimeText].Text := '0';
+ Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Min) + ':';
+ if Sec < 10 then Text[TextTimeText].Text := Text[TextTimeText].Text + '0';
+ Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Sec);
+
+ // .. and scores
+ if PlayersPlay = 1 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1Score].Text := Tekst;
+ end;
+
+ if PlayersPlay = 2 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1TwoPScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2RScore].Text := Tekst;
+ end;
+
+ if PlayersPlay = 3 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1ThreePScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2MScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[2].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP3RScore].Text := Tekst;
+ end;
+
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1TwoPScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2RScore].Text := Tekst;
+ end;
+ if ScreenAct = 2 then begin
+ Tekst := IntToStr(Player[2].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1TwoPScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[3].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2RScore].Text := Tekst;
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1ThreePScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2MScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[2].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP3RScore].Text := Tekst;
+ end;
+ if ScreenAct = 2 then begin
+ Tekst := IntToStr(Player[3].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1ThreePScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[4].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2MScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[5].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP3RScore].Text := Tekst;
+ end;
+ end;
+
+ // draw static menu (BG)
+ DrawBG;
+ //Draw Background
+ SingDrawBackground;
+ // update and draw movie
+ if ShowFinish and AktSong.VideoLoaded then begin
+ try
+// UpdateSmpeg; // this only draws
+ // todo: find a way to determine, when a new frame is needed
+ // toto: same for the need to skip frames
+ FFmpegGetFrame(Czas.Teraz);
+ FFmpegDrawGL(ScreenAct);
+ except
+ //If an Error occurs drawing: prevent Video from being Drawn again and Close Video
+ AktSong.VideoLoaded := False;
+ log.LogError('Error drawing Video, Video has been disabled for this Song/Session.');
+ Log.LogError('Corrupted File: ' + AktSong.Video);
+ try
+// CloseSmpeg;
+ FFmpegClose;
+ except
+
+ end;
+ end;
+ end;
+
+ // draw static menu (FG)
+ DrawFG;
+
+ // check for music finish
+// Log.LogError('Check for music finish: ' + BoolToStr(Music.Finished) + ' ' + FloatToStr(Czas.Teraz*1000) + ' ' + IntToStr(AktSong.Finish));
+ if ShowFinish then begin
+ if (not Music.Finished) and ((AktSong.Finish = 0) or (Czas.Teraz*1000 <= AktSong.Finish)) then begin
+ //Pause Mod:
+ if not Paused then
+ Sing(Self); // analyze song
+ end else begin
+// Log.LogError('End');
+ if not FadeOut then begin
+// Log.LogError('End2');
+ Finish;
+ FadeOut := true;
+ FadeTo(@ScreenScore);
+ end;
+ end;
+ end;
+
+ // draw custom items
+ SingDraw; // always draw
+
+//GoldenNoteStarsTwinkle Mod
+ GoldenRec.SpawnRec;
+//GoldenNoteStarsTwinkle Mod
+
+ // back stereo
+
+// weird stuff, maybe this is for "dual screen?", but where is player three then?
+// okay this stuff appears again some lines above this one, I commented it out for testing what it does - seems like it's doing nothing
+// but I might be wrong, so what is this stuff here doing? O.o
+ Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10*ScreenX;
+ Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X - 10*ScreenX;
+
+ Text[TextP1].X := Text[TextP1].X - 10*ScreenX;
+ Text[TextP1Score].X := Text[TextP1Score].X - 10*ScreenX;
+
+
+ Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X - 10*ScreenX;
+ Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X - 10*ScreenX;
+
+ Text[TextP2R].X := Text[TextP2R].X - 10*ScreenX;
+ Text[TextP2RScore].X := Text[TextP2RScore].X - 10*ScreenX;
+//weird end
+
+ for S := 1 to 1 do // wtf?
+ Static[S].Texture.X := Static[S].Texture.X - 10*ScreenX;
+
+ for T := 0 to 1 do
+ Text[T].X := Text[T].X - 10*ScreenX;
+
+end;
+
+procedure TScreenSing.Finish;
+begin
+ Music.CaptureStop;
+ Music.Stop;
+
+ if Ini.SavePlayback = 1 then begin
+ Log.BenchmarkStart(0);
+ Log.LogVoice(0);
+ Log.LogVoice(1);
+ Log.LogVoice(2);
+ Log.BenchmarkEnd(0);
+ Log.LogBenchmark('Creating files', 0);
+ end;
+
+ if AktSong.VideoLoaded then begin
+// CloseSmpeg;
+ FFmpegClose;
+ AktSong.VideoLoaded := false; // to prevent drawing closed video
+ end;
+
+ SetFontItalic (False);
+end;
+
+procedure TScreenSing.UpdateLCD;
+var
+ T: string;
+begin
+ LCD.HideCursor;
+ LCD.Clear;
+
+ T := LyricMain.Text;
+ if Copy(T, Length(T), 1) <> ' ' then T := T + ' ';
+ LCD.AddTextBR(T);
+
+ T := LyricSub.Text;
+ if Copy(T, Length(T), 1) <> ' ' then T := T + ' ';
+ LCD.AddTextBR(T);
+end;
+
+procedure TScreenSing.onSentenceEnd(S: Cardinal);
+var
+I: Integer;
+A: Real;
+B: integer; //Max Points for Notes
+begin
+
+ //Check for Empty Sentence
+ if (Czesci[0].Czesc[S].TotalNotes<=0) then
+ exit;
+
+ //Set Max Note Points
+ if (Ini.LineBonus > 0) then
+ B := 9000
+ else
+ B := 10000;
+
+ for I := 0 to High(Player) do begin
+ A := Player[I].Score + Player[I].ScoreGolden - Player[I].ScoreLast + 2;
+
+ //SingBar Mod
+ If ({(Ini.Oscilloscope = 2) and }(Czesci[0].Czesc[S].TotalNotes>0)) then
+ begin
+ Player[I].ScorePercentTarget := Player[I].ScorePercentTarget + floor(A / (B * Czesci[0].Czesc[S].TotalNotes / Czesci[0].Wartosc) * 40 - 26);
+ if Player[I].ScorePercentTarget < 0 then Player[I].ScorePercentTarget := 0;
+ if Player[I].ScorePercentTarget > 99 then Player[I].ScorePercentTarget := 99;
+
+ //end Singbar Mod
+ end;
+
+ //PhrasenBonus - Line Bonus Mod
+
+ //Generate Steps 0 to 8
+ A := Floor(A / (B * Czesci[0].Czesc[S].TotalNotes / Czesci[0].Wartosc) * 8);
+
+ If (Ini.LineBonus > 0) then
+ begin
+
+ //Generate Text
+ if A >= 8 then
+ Player[I].LineBonus_Text := Theme.Sing.LineBonusText[8]
+ else
+ Player[I].LineBonus_Text := Theme.Sing.LineBonusText[Floor(A)];
+
+ //PhrasenBonus give Points
+ Player[I].ScoreLine := Player[I].ScoreLine + (1000 / (Length(Czesci[0].Czesc) - NumEmptySentences) * A / 8);
+ Player[I].ScoreLineI := Round(Player[I].ScoreLine / 10) * 10;
+ //Update Total Score
+ Player[I].ScoreTotalI := Player[I].ScoreI + Player[I].ScoreGoldenI + Player[I].ScoreLineI;
+
+ //Color
+ Case Floor(A) of
+ 0: begin
+ Player[I].LineBonus_Color.R := 1;
+ Player[I].LineBonus_Color.G := 0;
+ Player[I].LineBonus_Color.B := 0;
+ end;
+ 1..3: begin
+ Player[I].LineBonus_Color.R := 1;
+ Player[I].LineBonus_Color.G := (A * 0.25);
+ Player[I].LineBonus_Color.B := 0;
+ end;
+ 4: begin
+ Player[I].LineBonus_Color.R := 1;
+ Player[I].LineBonus_Color.G := 1;
+ Player[I].LineBonus_Color.B := 0;
+ end;
+ 5..7: begin
+ Player[I].LineBonus_Color.R := 1-((a-4)*0.25);
+ Player[I].LineBonus_Color.G := 1;
+ Player[I].LineBonus_Color.B := 0;
+ end;
+ 8: begin
+ Player[I].LineBonus_Color.R := 0;
+ Player[I].LineBonus_Color.G := 1;
+ Player[I].LineBonus_Color.B := 0;
+ end;
+ End; //Case
+ //Player[I].LineBonus_Color.B := 0;
+ //Player[I].LineBonus_Color.R := (8-A)/8;
+ //Player[I].LineBonus_Color.G := A/10;
+
+ Player[I].LineBonus_PosX := Player[I].LineBonus_StartX;
+ Player[I].LineBonus_PosY := Player[I].LineBonus_StartY;
+ Player[I].LineBonus_Alpha := 0.92;
+ Player[I].LineBonus_Visible := True;
+ Player[I].LineBonus_Age := 1;
+ end;
+ //PhrasenBonus - Line Bonus Mod End// }
+
+ //PerfectLineTwinkle Mod (effect) Pt.1
+ If (Ini.EffectSing=1) then
+ begin
+ if A >= 8 then Player[I].LastSentencePerfect := True
+ else Player[I].LastSentencePerfect := False;
+ end;
+ //PerfectLineTwinkle Mod end
+
+ //Refresh LastScore
+ Player[I].ScoreLast := Player[I].Score + Player[I].ScoreGolden;
+
+ end;
+
+ //PerfectLineTwinkle Mod (effect) Pt.2
+ if Ini.EffectSing=1 then
+ GoldenRec.SpawnPerfectLineTwinkle;
+ //PerfectLineTwinkle Mod end
+end;
+
+//Called on Sentence Change S= New Current Sentence
+procedure TScreenSing.onSentenceChange(S: Cardinal);
+begin
+ //GoldenStarsTwinkle Mod
+ GoldenRec.SentenceChange;
+ //GoldenStarsTwinkle Mod End
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenSingModi.pas b/Game/Code/Screens/UScreenSingModi.pas
index 6d3add87..455d7b40 100644
--- a/Game/Code/Screens/UScreenSingModi.pas
+++ b/Game/Code/Screens/UScreenSingModi.pas
@@ -1,665 +1,669 @@
-unit UScreenSingModi;
-
-interface
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-uses UMenu,
- UMusic,
- SDL,
- SysUtils,
- UFiles,
- UTime,
- USongs,
- UIni,
- ULog,
- UTexture,
- ULyrics,
- TextGL,
- OpenGL12,
- BASS,
- UThemes,
- ULCD,
- UScreenSing,
- ModiSDK;
-
-type
- TScreenSingModi = class(TScreenSing)
- protected
- //paused: boolean; //Pause Mod
- //PauseTime: Real;
- //NumEmptySentences: integer;
- public
- //TextTime: integer;
-
- //StaticP1: integer;
- //StaticP1ScoreBG: integer;
- //TextP1: integer;
- //TextP1Score: integer;
-
- //StaticP2R: integer;
- //StaticP2RScoreBG: integer;
- //TextP2R: integer;
- //TextP2RScore: integer;
-
- //StaticP2M: integer;
- //StaticP2MScoreBG: integer;
- //TextP2M: integer;
- //TextP2MScore: integer;
-
- //StaticP3R: integer;
- //StaticP3RScoreBG: integer;
- //TextP3R: integer;
- //TextP3RScore: integer;
-
- //Tex_Background: TTexture;
- //FadeOut: boolean;
- //LyricMain: TLyric;
- //LyricSub: TLyric;
- Winner: Byte; //Who Wins
- PlayerInfo: TPlayerInfo;
- TeamInfo: TTeamInfo;
-
- constructor Create; override;
- procedure onShow; override;
- //procedure onShowFinish; override;
- function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
- function Draw: boolean; override;
- procedure Finish; override;
- //procedure UpdateLCD;
- //procedure Pause; //Pause Mod(Toggles Pause)
- end;
-
-//Procedured for Plugin
-function LoadTex (const Name, Typ: PChar): TsmallTexture; stdcall;
-//function Translate (const Name: PChar): PChar; stdcall;
-procedure Print (const Style, Size: Byte; const X, Y: Real; const Text: PChar); stdcall; //Procedure to Print Text
-function LoadSound (const Name: PChar): Cardinal; stdcall; //Procedure that loads a Custom Sound
-procedure PlaySound (const Index: Cardinal); stdcall; //Plays a Custom Sound
-
-//Utilys
-function ToSentences(Const Czeski: TCzesci): TSentences;
-
-implementation
-uses UGraphic, UDraw, UMain, Classes, URecord, ULanguage, math, UDLLManager, USkins, UGraphicClasses;
-
-// Method for input parsing. If False is returned, GetNextWindow
-// should be checked to know the next window to load;
-function TScreenSingModi.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- case PressedKey of
-
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- Finish;
- Music.PlayBack;
- FadeTo(@ScreenPartyScore);
- end;
-
- else
- Result := inherited ParseInput(PressedKey, ScanCode, PressedDown);
- end;
- end;
-end;
-
-constructor TScreenSingModi.Create;
-begin
- inherited Create;
-
-end;
-
-function ToSentences(Const Czeski: TCzesci): TSentences;
-var
- I, J: Integer;
-begin
- Result.Akt := Czeski.Akt;
- Result.High := Czeski.High;
- Result.Ilosc := Czeski.Ilosc;
- Result.Resolution := Czeski.Resolution;
- Result.NotesGAP := Czeski.NotesGAP;
- Result.TotalLength := Czeski.Wartosc;
-
- SetLength(Result.Sentence, Length(Czeski.Czesc));
- for I := low(Result.Sentence) to high(Result.Sentence) do
- begin
- Result.Sentence[I].Start := Czeski.Czesc[I].Start;
- Result.Sentence[I].StartNote := Czeski.Czesc[I].StartNote;
- Result.Sentence[I].Lyric := Czeski.Czesc[I].Lyric;
- Result.Sentence[I].LyricWidth := Czeski.Czesc[I].LyricWidth;
- Result.Sentence[I].Koniec := Czeski.Czesc[I].Koniec;
- Result.Sentence[I].BaseNote := Czeski.Czesc[I].BaseNote;
- Result.Sentence[I].HighNote := Czeski.Czesc[I].HighNut;
- Result.Sentence[I].IlNut := Czeski.Czesc[I].IlNut;
- Result.Sentence[I].TotalNotes := Czeski.Czesc[I].TotalNotes;
-
- SetLength(Result.Sentence[I].Note, Length(Czeski.Czesc[I].Nuta));
- for J := low(Result.Sentence[I].Note) to high(Result.Sentence[I].Note) do
- begin
- Result.Sentence[I].Note[J].Color := Czeski.Czesc[I].Nuta[J].Color;
- Result.Sentence[I].Note[J].Start := Czeski.Czesc[I].Nuta[J].Start;
- Result.Sentence[I].Note[J].Length := Czeski.Czesc[I].Nuta[J].Dlugosc;
- Result.Sentence[I].Note[J].Ton := Czeski.Czesc[I].Nuta[J].Ton;
- Result.Sentence[I].Note[J].TonGamy := Czeski.Czesc[I].Nuta[J].TonGamy;
- //Result.Sentence[I].Note[J].Text := Czeski.Czesc[I].Nuta[J].Tekst;
- Result.Sentence[I].Note[J].FreeStyle := Czeski.Czesc[I].Nuta[J].FreeStyle;
- Result.Sentence[I].Note[J].Typ := Czeski.Czesc[I].Nuta[J].Wartosc;
- end;
- end;
-end;
-
-procedure TScreenSingModi.onShow;
-var
- I: Integer;
-begin
-
- PlayersPlay := TeamInfo.NumTeams;
-
- if DLLMan.Selected.LoadSong then //Start with Song
- begin
- inherited;
- end
- else //Start Without Song
- begin
- Music.CaptureStart;
- end;
-
-//Set Playerinfo
- PlayerInfo.NumPlayers := PlayersPlay;
- for I := 0 to PlayerInfo.NumPlayers-1 do
- begin
- PlayerInfo.Playerinfo[I].Name := PChar(Ini.Name[I]);
- PlayerInfo.Playerinfo[I].Score := 0;
- PlayerInfo.Playerinfo[I].Bar := 50;
- PlayerInfo.Playerinfo[I].Enabled := True;
- end;
-
- for I := PlayerInfo.NumPlayers to high(PlayerInfo.Playerinfo) do
- begin
- PlayerInfo.Playerinfo[I].Score:= 0;
- PlayerInfo.Playerinfo[I].Bar := 0;
- PlayerInfo.Playerinfo[I].Enabled := False;
- end;
-
- Case PlayersPlay of
- 1: begin
- PlayerInfo.Playerinfo[0].PosX := Static[StaticP1ScoreBG].Texture.X;
- PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ScoreBG].Texture.Y + Static[StaticP1ScoreBG].Texture.H;
- end;
- 2,4: begin
- PlayerInfo.Playerinfo[0].PosX := Static[StaticP1TwoPScoreBG].Texture.X;
- PlayerInfo.Playerinfo[0].PosY := Static[StaticP1TwoPScoreBG].Texture.Y + Static[StaticP1TwoPScoreBG].Texture.H;
- PlayerInfo.Playerinfo[2].PosX := Static[StaticP1TwoPScoreBG].Texture.X;
- PlayerInfo.Playerinfo[2].PosY := Static[StaticP1TwoPScoreBG].Texture.Y + Static[StaticP1TwoPScoreBG].Texture.H;
- PlayerInfo.Playerinfo[1].PosX := Static[StaticP2RScoreBG].Texture.X;
- PlayerInfo.Playerinfo[1].PosY := Static[StaticP2RScoreBG].Texture.Y + Static[StaticP2RScoreBG].Texture.H;
- PlayerInfo.Playerinfo[3].PosX := Static[StaticP2RScoreBG].Texture.X;
- PlayerInfo.Playerinfo[3].PosY := Static[StaticP2RScoreBG].Texture.Y + Static[StaticP2RScoreBG].Texture.H;
- end;
- 3,6: begin
- PlayerInfo.Playerinfo[0].PosX := Static[StaticP1ThreePScoreBG].Texture.X;
- PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ThreePScoreBG].Texture.Y + Static[StaticP1ThreePScoreBG].Texture.H;
- PlayerInfo.Playerinfo[3].PosX := Static[StaticP1ThreePScoreBG].Texture.X;
- PlayerInfo.Playerinfo[3].PosY := Static[StaticP1ThreePScoreBG].Texture.Y + Static[StaticP1ThreePScoreBG].Texture.H;
- PlayerInfo.Playerinfo[1].PosX := Static[StaticP2MScoreBG].Texture.X;
- PlayerInfo.Playerinfo[1].PosY := Static[StaticP2MScoreBG].Texture.Y + Static[StaticP2MScoreBG].Texture.H;
- PlayerInfo.Playerinfo[4].PosX := Static[StaticP2MScoreBG].Texture.X;
- PlayerInfo.Playerinfo[4].PosY := Static[StaticP2MScoreBG].Texture.Y + Static[StaticP2MScoreBG].Texture.H;
- PlayerInfo.Playerinfo[2].PosX := Static[StaticP3RScoreBG].Texture.X;
- PlayerInfo.Playerinfo[2].PosY := Static[StaticP3RScoreBG].Texture.Y + Static[StaticP3RScoreBG].Texture.H;
- PlayerInfo.Playerinfo[5].PosX := Static[StaticP3RScoreBG].Texture.X;
- PlayerInfo.Playerinfo[5].PosY := Static[StaticP3RScoreBG].Texture.Y + Static[StaticP3RScoreBG].Texture.H;
- end;
- end;
-
- // play music (I)
- //Music.CaptureStart;
- //Music.MoveTo(AktSong.Start);
-
- //Init Plugin
- if not DLLMan.PluginInit(TeamInfo, PlayerInfo, ToSentences(Czesci[0]), LoadTex, Print, LoadSound, PlaySound) then
- begin
- //Fehler
- Log.LogError('Could not Init Plugin');
- Halt;
- end;
-
- // Set Background (Little Workaround, maybe change sometime)
- if (DLLMan.Selected.LoadBack) AND (DLLMan.Selected.LoadSong) then
- ScreenSing.Tex_Background := Tex_Background;
-
- Winner := 0;
-
- //Set Score Visibility
- if PlayersPlay = 1 then begin
- Text[TextP1Score].Visible := DLLMan.Selected.ShowScore;
- Static[StaticP1ScoreBG].Visible := DLLMan.Selected.ShowScore;
- end;
-
- if (PlayersPlay = 2) OR (PlayersPlay = 4) then begin
- Text[TextP1TwoPScore].Visible := DLLMan.Selected.ShowScore;
- Static[StaticP1TwoPScoreBG].Visible := DLLMan.Selected.ShowScore;
-
- Text[TextP2RScore].Visible := DLLMan.Selected.ShowScore;
- Static[StaticP2RScoreBG].Visible := DLLMan.Selected.ShowScore;
- end;
-
- if (PlayersPlay = 3) OR (PlayersPlay = 6) then begin
- Text[TextP1ThreePScore].Visible := DLLMan.Selected.ShowScore;
- Static[StaticP1ThreePScoreBG].Visible := DLLMan.Selected.ShowScore;
-
- Text[TextP2MScore].Visible := DLLMan.Selected.ShowScore;
- Static[StaticP2MScoreBG].Visible := DLLMan.Selected.ShowScore;
-
- Text[TextP3RScore].Visible := DLLMan.Selected.ShowScore;
- Static[StaticP3RScoreBG].Visible := DLLMan.Selected.ShowScore;
- end;
-end;
-
-function TScreenSingModi.Draw: boolean;
-var
- Min: integer;
- Sec: integer;
- Tekst: string;
- S, I: integer;
- T: integer;
-begin
-//Set Playerinfo
- PlayerInfo.NumPlayers := PlayersPlay;
- for I := 0 to PlayerInfo.NumPlayers-1 do
- begin
- PlayerInfo.Playerinfo[I].Name := PChar(Player[I].Name);
- if PlayerInfo.Playerinfo[I].Enabled then
- begin
- if (Player[I].ScoreTotalI<=10000) then
- PlayerInfo.Playerinfo[I].Score:= Player[I].ScoreTotalI;
- PlayerInfo.Playerinfo[I].Bar := Player[I].ScorePercent;
- end;
- end;
-
-//Show Score
-if DLLMan.Selected.ShowScore then
-begin
- //ScoreBG Mod
- // set player colors
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
- Static[StaticP1TwoP].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P2Dark');
-
-
-
- LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
- Static[StaticP1TwoPScoreBG].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
-
-
-
- end;
- if ScreenAct = 2 then begin
- LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
- Static[StaticP1TwoP].Texture.ColB, 'P3Dark');
- LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P4Dark');
-
-
-
- LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
- Static[StaticP1TwoPScoreBG].Texture.ColB, 'P3Dark');
- LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P4Dark');
-
-
-
- end;
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
- Static[StaticP1ThreeP].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P2Dark');
- LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
- Static[StaticP3R].Texture.ColB, 'P3Dark');
-
-
-
- LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
- Static[StaticP1ThreePScoreBG].Texture.ColB, 'P1Dark');
- LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
- LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
- Static[StaticP3RScoreBG].Texture.ColB, 'P3Dark');
-
-
-
- end;
- if ScreenAct = 2 then begin
- LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
- Static[StaticP1ThreeP].Texture.ColB, 'P4Dark');
- LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
- Static[StaticP2R].Texture.ColB, 'P5Dark');
- LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
- Static[StaticP3R].Texture.ColB, 'P6Dark');
-
-
-
-
- LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
- Static[StaticP1ThreePScoreBG].Texture.ColB, 'P4Dark');
- LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
- Static[StaticP2RScoreBG].Texture.ColB, 'P5Dark');
- LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
- Static[StaticP3RScoreBG].Texture.ColB, 'P6Dark');
-
-
-
-
- end;
- end;
- //end ScoreBG Mod
-
-// set player names (for 2 screens and only Singstar skin)
- if ScreenAct = 1 then begin
- Text[TextP1].Text := 'P1';
- Text[TextP1TwoP].Text := 'P1'; // added for ps3 skin
- Text[TextP1ThreeP].Text := 'P1'; // added for ps3 skin
- Text[TextP2R].Text := 'P2';
- Text[TextP2M].Text := 'P2';
- Text[TextP3R].Text := 'P3';
- end;
-
- if ScreenAct = 2 then begin
- case PlayersPlay of
- 4: begin
- Text[TextP1TwoP].Text := 'P3';
- Text[TextP2R].Text := 'P4';
- end;
- 6: begin
- Text[TextP1ThreeP].Text := 'P4';
- Text[TextP2M].Text := 'P5';
- Text[TextP3R].Text := 'P6';
- end;
- end; // case
- end; // if
-
-
- // stereo <- and where iss P2M? or P3?
- Static[StaticP1].Texture.X := Static[StaticP1].Texture.X + 10*ScreenX;
- Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X + 10*ScreenX;
-
- Text[TextP1].X := Text[TextP1].X + 10*ScreenX;
- Text[TextP1Score].X := Text[TextP1Score].X + 10*ScreenX;
-
- Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X + 10*ScreenX;
- Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X + 10*ScreenX;
-
- Text[TextP2R].X := Text[TextP2R].X + 10*ScreenX;
- Text[TextP2RScore].X := Text[TextP2RScore].X + 10*ScreenX;
-
- // .. and scores
- if PlayersPlay = 1 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1Score].Text := Tekst;
- end;
-
- if PlayersPlay = 2 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1TwoPScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2RScore].Text := Tekst;
- end;
-
- if PlayersPlay = 3 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1ThreePScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2MScore].Text := Tekst;
-
- Tekst := IntToStr(Player[2].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP3RScore].Text := Tekst;
- end;
-
- if PlayersPlay = 4 then begin
- if ScreenAct = 1 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1TwoPScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2RScore].Text := Tekst;
- end;
- if ScreenAct = 2 then begin
- Tekst := IntToStr(Player[2].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1TwoPScore].Text := Tekst;
-
- Tekst := IntToStr(Player[3].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2RScore].Text := Tekst;
- end;
- end;
-
- if PlayersPlay = 6 then begin
- if ScreenAct = 1 then begin
- Tekst := IntToStr(Player[0].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1ThreePScore].Text := Tekst;
-
- Tekst := IntToStr(Player[1].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2MScore].Text := Tekst;
-
- Tekst := IntToStr(Player[2].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP3RScore].Text := Tekst;
- end;
- if ScreenAct = 2 then begin
- Tekst := IntToStr(Player[3].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP1ThreePScore].Text := Tekst;
-
- Tekst := IntToStr(Player[4].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP2MScore].Text := Tekst;
-
- Tekst := IntToStr(Player[5].ScoreTotalI);
- while Length(Tekst) < 5 do Tekst := '0' + Tekst;
- Text[TextP3RScore].Text := Tekst;
- end;
- end;
-
-end; //ShowScore
-
- for S := 1 to 1 do
- Static[S].Texture.X := Static[S].Texture.X + 10*ScreenX;
-
- for T := 0 to 1 do
- Text[T].X := Text[T].X + 10*ScreenX;
-
-if DLLMan.Selected.LoadSong then
-begin
- // update static menu with time ...
- Min := Round(Czas.Teraz) div 60;
- Sec := Round(Czas.Teraz) mod 60;
- Text[TextTimeText].Text := '';
- if Min < 10 then Text[TextTimeText].Text := '0';
- Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Min) + ':';
- if Sec < 10 then Text[TextTimeText].Text := Text[TextTimeText].Text + '0';
- Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Sec);
-end;
-
- // draw static menu (BG)
- DrawBG;
-
- //Draw Background
- if (DllMan.Selected.LoadSong) AND (DllMan.Selected.LoadBack) then
- SingDrawBackground;
-
- // comment by blindy: wo zum henker wird denn in diesem screen ein video abgespielt?
- // update and draw movie
- // <mog> wie wo wadd? also in der selben funktion in der uscreensing kommt des video in der zeile 995, oder was wollteste wissen? :X
-{ if ShowFinish and AktSong.VideoLoaded AND DllMan.Selected.LoadVideo then begin
- UpdateSmpeg; // this only draws
- end;}
-
- // draw static menu (FG)
- DrawFG;
-
- if ShowFinish then begin
- if DllMan.Selected.LoadSong then
- begin
- if (not Music.Finished) and ((AktSong.Finish = 0) or (Czas.Teraz*1000 <= AktSong.Finish)) then begin
- //Pause Mod:
- if not Paused then
- Sing(Self); // analyze song
- end else begin
- if not FadeOut then begin
- Finish;
- FadeOut := true;
- FadeTo(@ScreenPartyScore);
- end;
- end;
- end;
- end;
-
- // draw custom items
- SingModiDraw(PlayerInfo); // always draw
-
- //GoldenNoteStarsTwinkle Mod
- GoldenRec.SpawnRec;
- //GoldenNoteStarsTwinkle Mod
-
- //Update PlayerInfo
- for I := 0 to PlayerInfo.NumPlayers-1 do
- begin
- if PlayerInfo.Playerinfo[I].Enabled then
- begin
- PlayerInfo.Playerinfo[I].Bar := Player[I].ScorePercent;
- PlayerInfo.Playerinfo[I].Score := Player[I].ScoreTotalI;
- end;
- end;
-
- if ((ShowFinish) AND (NOT Paused)) then
- begin
- if not DLLMan.PluginDraw(Playerinfo, Czesci[0].Akt) then
- begin
- if not FadeOut then begin
- Finish;
- FadeOut := true;
- FadeTo(@ScreenPartyScore);
- end;
- end;
- end;
-
- //Change PlayerInfo/Changeables
- for I := 0 to PlayerInfo.NumPlayers-1 do
- begin
- if (Player[I].ScoreTotalI <> PlayerInfo.Playerinfo[I].Score) then
- begin
- //Player[I].ScoreTotal := Player[I].ScoreTotal + (PlayerInfo.Playerinfo[I].Score - Player[I].ScoreTotalI);
- Player[I].ScoreTotalI := PlayerInfo.Playerinfo[I].Score;
- end;
- if (PlayerInfo.Playerinfo[I].Bar <> Player[I].ScorePercent) then
- Player[I].ScorePercentTarget := PlayerInfo.Playerinfo[I].Bar;
- end;
-
- // back stereo
- Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10*ScreenX;
- Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X - 10*ScreenX;
-
- Text[TextP1].X := Text[TextP1].X - 10*ScreenX;
- Text[TextP1Score].X := Text[TextP1Score].X - 10*ScreenX;
-
-
- Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X - 10*ScreenX;
- Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X - 10*ScreenX;
-
- Text[TextP2R].X := Text[TextP2R].X - 10*ScreenX;
- Text[TextP2RScore].X := Text[TextP2RScore].X - 10*ScreenX;
-
-
- for S := 1 to 1 do
- Static[S].Texture.X := Static[S].Texture.X - 10*ScreenX;
-
- for T := 0 to 1 do
- Text[T].X := Text[T].X - 10*ScreenX;
-
-
-end;
-
-procedure TScreenSingModi.Finish;
-begin
-inherited Finish;
-
-Winner := DllMan.PluginFinish(PlayerInfo);
-
-//Log.LogError('Winner: ' + InttoStr(Winner));
-
-//DLLMan.UnLoadPlugin;
-end;
-
-function LoadTex (const Name, Typ: PChar): TsmallTexture; stdcall;
-var
- Texname, EXT: String;
- Tex: TTexture;
-begin
- //Get texture Name
- TexName := Skin.GetTextureFileName(String(Name));
- //Get File Typ
- Ext := ExtractFileExt(TexName);
- if (uppercase(Ext) = '.JPG') then
- Ext := 'JPG'
- else
- Ext := 'BMP';
-
- Tex := Texture.LoadTexture(PChar(TexName), PChar(Ext), Typ, 0);
-
- Result.TexNum := Tex.TexNum;
- Result.W := Tex.W;
- Result.H := Tex.H;
-end;
-{
-function Translate (const Name: PChar): PChar; stdcall;
-begin
- Result := PChar(Language.Translate(String(Name)));
-end; }
-
-procedure Print (const Style, Size: Byte; const X, Y: Real; const Text: PChar); stdcall; //Procedure to Print Text
-begin
- SetFontItalic ((Style and 128) = 128);
- SetFontStyle(Style and 7);
- SetFontSize(Size);
- SetFontPos (X, Y);
- glPrint (PChar(Language.Translate(String(Text))));
-end;
-
-function LoadSound (const Name: PChar): Cardinal; stdcall; //Procedure that loads a Custom Sound
-begin
- Result := Music.LoadCustomSound(String(Name));
-end;
-
-procedure PlaySound (const Index: Cardinal); stdcall; //Plays a Custom Sound
-begin
- Music.PlayCustomSound(Index);
-end;
-
-end.
+unit UScreenSingModi;
+
+interface
+
+{$I switches.inc}
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+{$ENDIF}
+
+uses UMenu,
+ UMusic,
+ SDL,
+ SysUtils,
+ UFiles,
+ UTime,
+ USongs,
+ UIni,
+ ULog,
+ UTexture,
+ ULyrics,
+ TextGL,
+ OpenGL12,
+ {$IFDEF useBASS}
+ bass,
+ {$ENDIF}
+ UThemes,
+ ULCD,
+ UScreenSing,
+ ModiSDK;
+
+type
+ TScreenSingModi = class(TScreenSing)
+ protected
+ //paused: boolean; //Pause Mod
+ //PauseTime: Real;
+ //NumEmptySentences: integer;
+ public
+ //TextTime: integer;
+
+ //StaticP1: integer;
+ //StaticP1ScoreBG: integer;
+ //TextP1: integer;
+ //TextP1Score: integer;
+
+ //StaticP2R: integer;
+ //StaticP2RScoreBG: integer;
+ //TextP2R: integer;
+ //TextP2RScore: integer;
+
+ //StaticP2M: integer;
+ //StaticP2MScoreBG: integer;
+ //TextP2M: integer;
+ //TextP2MScore: integer;
+
+ //StaticP3R: integer;
+ //StaticP3RScoreBG: integer;
+ //TextP3R: integer;
+ //TextP3RScore: integer;
+
+ //Tex_Background: TTexture;
+ //FadeOut: boolean;
+ //LyricMain: TLyric;
+ //LyricSub: TLyric;
+ Winner: Byte; //Who Wins
+ PlayerInfo: TPlayerInfo;
+ TeamInfo: TTeamInfo;
+
+ constructor Create; override;
+ procedure onShow; override;
+ //procedure onShowFinish; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+ procedure Finish; override;
+ //procedure UpdateLCD;
+ //procedure Pause; //Pause Mod(Toggles Pause)
+ end;
+
+//Procedured for Plugin
+function LoadTex (const Name, Typ: PChar): TsmallTexture; stdcall;
+//function Translate (const Name: PChar): PChar; stdcall;
+procedure Print (const Style, Size: Byte; const X, Y: Real; const Text: PChar); stdcall; //Procedure to Print Text
+function LoadSound (const Name: PChar): Cardinal; stdcall; //Procedure that loads a Custom Sound
+procedure PlaySound (const Index: Cardinal); stdcall; //Plays a Custom Sound
+
+//Utilys
+function ToSentences(Const Czeski: TCzesci): TSentences;
+
+implementation
+uses UGraphic, UDraw, UMain, Classes, URecord, ULanguage, math, UDLLManager, USkins, UGraphicClasses;
+
+// Method for input parsing. If False is returned, GetNextWindow
+// should be checked to know the next window to load;
+function TScreenSingModi.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ Finish;
+ Music.PlayBack;
+ FadeTo(@ScreenPartyScore);
+ end;
+
+ else
+ Result := inherited ParseInput(PressedKey, ScanCode, PressedDown);
+ end;
+ end;
+end;
+
+constructor TScreenSingModi.Create;
+begin
+ inherited Create;
+
+end;
+
+function ToSentences(Const Czeski: TCzesci): TSentences;
+var
+ I, J: Integer;
+begin
+ Result.Akt := Czeski.Akt;
+ Result.High := Czeski.High;
+ Result.Ilosc := Czeski.Ilosc;
+ Result.Resolution := Czeski.Resolution;
+ Result.NotesGAP := Czeski.NotesGAP;
+ Result.TotalLength := Czeski.Wartosc;
+
+ SetLength(Result.Sentence, Length(Czeski.Czesc));
+ for I := low(Result.Sentence) to high(Result.Sentence) do
+ begin
+ Result.Sentence[I].Start := Czeski.Czesc[I].Start;
+ Result.Sentence[I].StartNote := Czeski.Czesc[I].StartNote;
+ Result.Sentence[I].Lyric := Czeski.Czesc[I].Lyric;
+ Result.Sentence[I].LyricWidth := Czeski.Czesc[I].LyricWidth;
+ Result.Sentence[I].Koniec := Czeski.Czesc[I].Koniec;
+ Result.Sentence[I].BaseNote := Czeski.Czesc[I].BaseNote;
+ Result.Sentence[I].HighNote := Czeski.Czesc[I].HighNut;
+ Result.Sentence[I].IlNut := Czeski.Czesc[I].IlNut;
+ Result.Sentence[I].TotalNotes := Czeski.Czesc[I].TotalNotes;
+
+ SetLength(Result.Sentence[I].Note, Length(Czeski.Czesc[I].Nuta));
+ for J := low(Result.Sentence[I].Note) to high(Result.Sentence[I].Note) do
+ begin
+ Result.Sentence[I].Note[J].Color := Czeski.Czesc[I].Nuta[J].Color;
+ Result.Sentence[I].Note[J].Start := Czeski.Czesc[I].Nuta[J].Start;
+ Result.Sentence[I].Note[J].Length := Czeski.Czesc[I].Nuta[J].Dlugosc;
+ Result.Sentence[I].Note[J].Ton := Czeski.Czesc[I].Nuta[J].Ton;
+ Result.Sentence[I].Note[J].TonGamy := Czeski.Czesc[I].Nuta[J].TonGamy;
+ //Result.Sentence[I].Note[J].Text := Czeski.Czesc[I].Nuta[J].Tekst;
+ Result.Sentence[I].Note[J].FreeStyle := Czeski.Czesc[I].Nuta[J].FreeStyle;
+ Result.Sentence[I].Note[J].Typ := Czeski.Czesc[I].Nuta[J].Wartosc;
+ end;
+ end;
+end;
+
+procedure TScreenSingModi.onShow;
+var
+ I: Integer;
+begin
+
+ PlayersPlay := TeamInfo.NumTeams;
+
+ if DLLMan.Selected.LoadSong then //Start with Song
+ begin
+ inherited;
+ end
+ else //Start Without Song
+ begin
+ Music.CaptureStart;
+ end;
+
+//Set Playerinfo
+ PlayerInfo.NumPlayers := PlayersPlay;
+ for I := 0 to PlayerInfo.NumPlayers-1 do
+ begin
+ PlayerInfo.Playerinfo[I].Name := PChar(Ini.Name[I]);
+ PlayerInfo.Playerinfo[I].Score := 0;
+ PlayerInfo.Playerinfo[I].Bar := 50;
+ PlayerInfo.Playerinfo[I].Enabled := True;
+ end;
+
+ for I := PlayerInfo.NumPlayers to high(PlayerInfo.Playerinfo) do
+ begin
+ PlayerInfo.Playerinfo[I].Score:= 0;
+ PlayerInfo.Playerinfo[I].Bar := 0;
+ PlayerInfo.Playerinfo[I].Enabled := False;
+ end;
+
+ Case PlayersPlay of
+ 1: begin
+ PlayerInfo.Playerinfo[0].PosX := Static[StaticP1ScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ScoreBG].Texture.Y + Static[StaticP1ScoreBG].Texture.H;
+ end;
+ 2,4: begin
+ PlayerInfo.Playerinfo[0].PosX := Static[StaticP1TwoPScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[0].PosY := Static[StaticP1TwoPScoreBG].Texture.Y + Static[StaticP1TwoPScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[2].PosX := Static[StaticP1TwoPScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[2].PosY := Static[StaticP1TwoPScoreBG].Texture.Y + Static[StaticP1TwoPScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[1].PosX := Static[StaticP2RScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[1].PosY := Static[StaticP2RScoreBG].Texture.Y + Static[StaticP2RScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[3].PosX := Static[StaticP2RScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[3].PosY := Static[StaticP2RScoreBG].Texture.Y + Static[StaticP2RScoreBG].Texture.H;
+ end;
+ 3,6: begin
+ PlayerInfo.Playerinfo[0].PosX := Static[StaticP1ThreePScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ThreePScoreBG].Texture.Y + Static[StaticP1ThreePScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[3].PosX := Static[StaticP1ThreePScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[3].PosY := Static[StaticP1ThreePScoreBG].Texture.Y + Static[StaticP1ThreePScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[1].PosX := Static[StaticP2MScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[1].PosY := Static[StaticP2MScoreBG].Texture.Y + Static[StaticP2MScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[4].PosX := Static[StaticP2MScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[4].PosY := Static[StaticP2MScoreBG].Texture.Y + Static[StaticP2MScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[2].PosX := Static[StaticP3RScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[2].PosY := Static[StaticP3RScoreBG].Texture.Y + Static[StaticP3RScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[5].PosX := Static[StaticP3RScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[5].PosY := Static[StaticP3RScoreBG].Texture.Y + Static[StaticP3RScoreBG].Texture.H;
+ end;
+ end;
+
+ // play music (I)
+ //Music.CaptureStart;
+ //Music.MoveTo(AktSong.Start);
+
+ //Init Plugin
+ if not DLLMan.PluginInit(TeamInfo, PlayerInfo, ToSentences(Czesci[0]), LoadTex, Print, LoadSound, PlaySound) then
+ begin
+ //Fehler
+ Log.LogError('Could not Init Plugin');
+ Halt;
+ end;
+
+ // Set Background (Little Workaround, maybe change sometime)
+ if (DLLMan.Selected.LoadBack) AND (DLLMan.Selected.LoadSong) then
+ ScreenSing.Tex_Background := Tex_Background;
+
+ Winner := 0;
+
+ //Set Score Visibility
+ if PlayersPlay = 1 then begin
+ Text[TextP1Score].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP1ScoreBG].Visible := DLLMan.Selected.ShowScore;
+ end;
+
+ if (PlayersPlay = 2) OR (PlayersPlay = 4) then begin
+ Text[TextP1TwoPScore].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP1TwoPScoreBG].Visible := DLLMan.Selected.ShowScore;
+
+ Text[TextP2RScore].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP2RScoreBG].Visible := DLLMan.Selected.ShowScore;
+ end;
+
+ if (PlayersPlay = 3) OR (PlayersPlay = 6) then begin
+ Text[TextP1ThreePScore].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP1ThreePScoreBG].Visible := DLLMan.Selected.ShowScore;
+
+ Text[TextP2MScore].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP2MScoreBG].Visible := DLLMan.Selected.ShowScore;
+
+ Text[TextP3RScore].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP3RScoreBG].Visible := DLLMan.Selected.ShowScore;
+ end;
+end;
+
+function TScreenSingModi.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ S, I: integer;
+ T: integer;
+begin
+//Set Playerinfo
+ PlayerInfo.NumPlayers := PlayersPlay;
+ for I := 0 to PlayerInfo.NumPlayers-1 do
+ begin
+ PlayerInfo.Playerinfo[I].Name := PChar(Player[I].Name);
+ if PlayerInfo.Playerinfo[I].Enabled then
+ begin
+ if (Player[I].ScoreTotalI<=10000) then
+ PlayerInfo.Playerinfo[I].Score:= Player[I].ScoreTotalI;
+ PlayerInfo.Playerinfo[I].Bar := Player[I].ScorePercent;
+ end;
+ end;
+
+//Show Score
+if DLLMan.Selected.ShowScore then
+begin
+ //ScoreBG Mod
+ // set player colors
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
+ Static[StaticP1TwoP].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P2Dark');
+
+
+
+ LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
+ Static[StaticP1TwoPScoreBG].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
+
+
+
+ end;
+ if ScreenAct = 2 then begin
+ LoadColor(Static[StaticP1TwoP].Texture.ColR, Static[StaticP1TwoP].Texture.ColG,
+ Static[StaticP1TwoP].Texture.ColB, 'P3Dark');
+ LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P4Dark');
+
+
+
+ LoadColor(Static[StaticP1TwoPScoreBG].Texture.ColR, Static[StaticP1TwoPScoreBG].Texture.ColG,
+ Static[StaticP1TwoPScoreBG].Texture.ColB, 'P3Dark');
+ LoadColor(Static[StaticP2RScoreBG].Texture.ColR, Static[StaticP2RScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P4Dark');
+
+
+
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
+ Static[StaticP1ThreeP].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P2Dark');
+ LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
+ Static[StaticP3R].Texture.ColB, 'P3Dark');
+
+
+
+ LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
+ Static[StaticP1ThreePScoreBG].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P2Dark');
+ LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
+ Static[StaticP3RScoreBG].Texture.ColB, 'P3Dark');
+
+
+
+ end;
+ if ScreenAct = 2 then begin
+ LoadColor(Static[StaticP1ThreeP].Texture.ColR, Static[StaticP1ThreeP].Texture.ColG,
+ Static[StaticP1ThreeP].Texture.ColB, 'P4Dark');
+ LoadColor(Static[StaticP2M].Texture.ColR, Static[StaticP2M].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P5Dark');
+ LoadColor(Static[StaticP3R].Texture.ColR, Static[StaticP3R].Texture.ColG,
+ Static[StaticP3R].Texture.ColB, 'P6Dark');
+
+
+
+
+ LoadColor(Static[StaticP1ThreePScoreBG].Texture.ColR, Static[StaticP1ThreePScoreBG].Texture.ColG,
+ Static[StaticP1ThreePScoreBG].Texture.ColB, 'P4Dark');
+ LoadColor(Static[StaticP2MScoreBG].Texture.ColR, Static[StaticP2MScoreBG].Texture.ColG,
+ Static[StaticP2RScoreBG].Texture.ColB, 'P5Dark');
+ LoadColor(Static[StaticP3RScoreBG].Texture.ColR, Static[StaticP3RScoreBG].Texture.ColG,
+ Static[StaticP3RScoreBG].Texture.ColB, 'P6Dark');
+
+
+
+
+ end;
+ end;
+ //end ScoreBG Mod
+
+// set player names (for 2 screens and only Singstar skin)
+ if ScreenAct = 1 then begin
+ Text[TextP1].Text := 'P1';
+ Text[TextP1TwoP].Text := 'P1'; // added for ps3 skin
+ Text[TextP1ThreeP].Text := 'P1'; // added for ps3 skin
+ Text[TextP2R].Text := 'P2';
+ Text[TextP2M].Text := 'P2';
+ Text[TextP3R].Text := 'P3';
+ end;
+
+ if ScreenAct = 2 then begin
+ case PlayersPlay of
+ 4: begin
+ Text[TextP1TwoP].Text := 'P3';
+ Text[TextP2R].Text := 'P4';
+ end;
+ 6: begin
+ Text[TextP1ThreeP].Text := 'P4';
+ Text[TextP2M].Text := 'P5';
+ Text[TextP3R].Text := 'P6';
+ end;
+ end; // case
+ end; // if
+
+
+ // stereo <- and where iss P2M? or P3?
+ Static[StaticP1].Texture.X := Static[StaticP1].Texture.X + 10*ScreenX;
+ Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X + 10*ScreenX;
+
+ Text[TextP1].X := Text[TextP1].X + 10*ScreenX;
+ Text[TextP1Score].X := Text[TextP1Score].X + 10*ScreenX;
+
+ Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X + 10*ScreenX;
+ Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X + 10*ScreenX;
+
+ Text[TextP2R].X := Text[TextP2R].X + 10*ScreenX;
+ Text[TextP2RScore].X := Text[TextP2RScore].X + 10*ScreenX;
+
+ // .. and scores
+ if PlayersPlay = 1 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1Score].Text := Tekst;
+ end;
+
+ if PlayersPlay = 2 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1TwoPScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2RScore].Text := Tekst;
+ end;
+
+ if PlayersPlay = 3 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1ThreePScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2MScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[2].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP3RScore].Text := Tekst;
+ end;
+
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1TwoPScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2RScore].Text := Tekst;
+ end;
+ if ScreenAct = 2 then begin
+ Tekst := IntToStr(Player[2].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1TwoPScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[3].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2RScore].Text := Tekst;
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ Tekst := IntToStr(Player[0].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1ThreePScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[1].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2MScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[2].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP3RScore].Text := Tekst;
+ end;
+ if ScreenAct = 2 then begin
+ Tekst := IntToStr(Player[3].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP1ThreePScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[4].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP2MScore].Text := Tekst;
+
+ Tekst := IntToStr(Player[5].ScoreTotalI);
+ while Length(Tekst) < 5 do Tekst := '0' + Tekst;
+ Text[TextP3RScore].Text := Tekst;
+ end;
+ end;
+
+end; //ShowScore
+
+ for S := 1 to 1 do
+ Static[S].Texture.X := Static[S].Texture.X + 10*ScreenX;
+
+ for T := 0 to 1 do
+ Text[T].X := Text[T].X + 10*ScreenX;
+
+if DLLMan.Selected.LoadSong then
+begin
+ // update static menu with time ...
+ Min := Round(Czas.Teraz) div 60;
+ Sec := Round(Czas.Teraz) mod 60;
+ Text[TextTimeText].Text := '';
+ if Min < 10 then Text[TextTimeText].Text := '0';
+ Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Min) + ':';
+ if Sec < 10 then Text[TextTimeText].Text := Text[TextTimeText].Text + '0';
+ Text[TextTimeText].Text := Text[TextTimeText].Text + IntToStr(Sec);
+end;
+
+ // draw static menu (BG)
+ DrawBG;
+
+ //Draw Background
+ if (DllMan.Selected.LoadSong) AND (DllMan.Selected.LoadBack) then
+ SingDrawBackground;
+
+ // comment by blindy: wo zum henker wird denn in diesem screen ein video abgespielt?
+ // update and draw movie
+ // <mog> wie wo wadd? also in der selben funktion in der uscreensing kommt des video in der zeile 995, oder was wollteste wissen? :X
+{ if ShowFinish and AktSong.VideoLoaded AND DllMan.Selected.LoadVideo then begin
+ UpdateSmpeg; // this only draws
+ end;}
+
+ // draw static menu (FG)
+ DrawFG;
+
+ if ShowFinish then begin
+ if DllMan.Selected.LoadSong then
+ begin
+ if (not Music.Finished) and ((AktSong.Finish = 0) or (Czas.Teraz*1000 <= AktSong.Finish)) then begin
+ //Pause Mod:
+ if not Paused then
+ Sing(Self); // analyze song
+ end else begin
+ if not FadeOut then begin
+ Finish;
+ FadeOut := true;
+ FadeTo(@ScreenPartyScore);
+ end;
+ end;
+ end;
+ end;
+
+ // draw custom items
+ SingModiDraw(PlayerInfo); // always draw
+
+ //GoldenNoteStarsTwinkle Mod
+ GoldenRec.SpawnRec;
+ //GoldenNoteStarsTwinkle Mod
+
+ //Update PlayerInfo
+ for I := 0 to PlayerInfo.NumPlayers-1 do
+ begin
+ if PlayerInfo.Playerinfo[I].Enabled then
+ begin
+ PlayerInfo.Playerinfo[I].Bar := Player[I].ScorePercent;
+ PlayerInfo.Playerinfo[I].Score := Player[I].ScoreTotalI;
+ end;
+ end;
+
+ if ((ShowFinish) AND (NOT Paused)) then
+ begin
+ if not DLLMan.PluginDraw(Playerinfo, Czesci[0].Akt) then
+ begin
+ if not FadeOut then begin
+ Finish;
+ FadeOut := true;
+ FadeTo(@ScreenPartyScore);
+ end;
+ end;
+ end;
+
+ //Change PlayerInfo/Changeables
+ for I := 0 to PlayerInfo.NumPlayers-1 do
+ begin
+ if (Player[I].ScoreTotalI <> PlayerInfo.Playerinfo[I].Score) then
+ begin
+ //Player[I].ScoreTotal := Player[I].ScoreTotal + (PlayerInfo.Playerinfo[I].Score - Player[I].ScoreTotalI);
+ Player[I].ScoreTotalI := PlayerInfo.Playerinfo[I].Score;
+ end;
+ if (PlayerInfo.Playerinfo[I].Bar <> Player[I].ScorePercent) then
+ Player[I].ScorePercentTarget := PlayerInfo.Playerinfo[I].Bar;
+ end;
+
+ // back stereo
+ Static[StaticP1].Texture.X := Static[StaticP1].Texture.X - 10*ScreenX;
+ Static[StaticP1ScoreBG].Texture.X := Static[StaticP1ScoreBG].Texture.X - 10*ScreenX;
+
+ Text[TextP1].X := Text[TextP1].X - 10*ScreenX;
+ Text[TextP1Score].X := Text[TextP1Score].X - 10*ScreenX;
+
+
+ Static[StaticP2R].Texture.X := Static[StaticP2R].Texture.X - 10*ScreenX;
+ Static[StaticP2RScoreBG].Texture.X := Static[StaticP2RScoreBG].Texture.X - 10*ScreenX;
+
+ Text[TextP2R].X := Text[TextP2R].X - 10*ScreenX;
+ Text[TextP2RScore].X := Text[TextP2RScore].X - 10*ScreenX;
+
+
+ for S := 1 to 1 do
+ Static[S].Texture.X := Static[S].Texture.X - 10*ScreenX;
+
+ for T := 0 to 1 do
+ Text[T].X := Text[T].X - 10*ScreenX;
+
+
+end;
+
+procedure TScreenSingModi.Finish;
+begin
+inherited Finish;
+
+Winner := DllMan.PluginFinish(PlayerInfo);
+
+//Log.LogError('Winner: ' + InttoStr(Winner));
+
+//DLLMan.UnLoadPlugin;
+end;
+
+function LoadTex (const Name, Typ: PChar): TsmallTexture; stdcall;
+var
+ Texname, EXT: String;
+ Tex: TTexture;
+begin
+ //Get texture Name
+ TexName := Skin.GetTextureFileName(String(Name));
+ //Get File Typ
+ Ext := ExtractFileExt(TexName);
+ if (uppercase(Ext) = '.JPG') then
+ Ext := 'JPG'
+ else
+ Ext := 'BMP';
+
+ Tex := Texture.LoadTexture(PChar(TexName), PChar(Ext), Typ, 0);
+
+ Result.TexNum := Tex.TexNum;
+ Result.W := Tex.W;
+ Result.H := Tex.H;
+end;
+{
+function Translate (const Name: PChar): PChar; stdcall;
+begin
+ Result := PChar(Language.Translate(String(Name)));
+end; }
+
+procedure Print (const Style, Size: Byte; const X, Y: Real; const Text: PChar); stdcall; //Procedure to Print Text
+begin
+ SetFontItalic ((Style and 128) = 128);
+ SetFontStyle(Style and 7);
+ SetFontSize(Size);
+ SetFontPos (X, Y);
+ glPrint (PChar(Language.Translate(String(Text))));
+end;
+
+function LoadSound (const Name: PChar): Cardinal; stdcall; //Procedure that loads a Custom Sound
+begin
+ Result := Music.LoadCustomSound(String(Name));
+end;
+
+procedure PlaySound (const Index: Cardinal); stdcall; //Plays a Custom Sound
+begin
+ Music.PlayCustomSound(Index);
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenSong.pas b/Game/Code/Screens/UScreenSong.pas
index 7b16c315..569645d4 100644
--- a/Game/Code/Screens/UScreenSong.pas
+++ b/Game/Code/Screens/UScreenSong.pas
@@ -1,2007 +1,2040 @@
-unit UScreenSong;
-
-interface
-{$I switches.inc}
-
-uses
- UMenu, SDL, UMusic, UFiles, UTime, UDisplay, USongs, SysUtils, ULog, UThemes, UTexture, ULanguage,
- ULCD, ULight, UIni;
-
-type
- TScreenSong = class(TMenu)
- public
- TextArtist: integer;
- TextTitle: integer;
- TextNumber: integer;
-
- //Video Icon Mod
- VideoIcon: Cardinal;
-
- TextCat: integer;
- StaticCat: integer;
-
- SongCurrent: real;
- SongTarget: real;
-
- HighSpeed: boolean;
- CoverFull: boolean;
- CoverTime: real;
- CoverX: integer;
- CoverY: integer;
- CoverW: integer;
- is_jump: boolean; // Jump to Song Mod
- is_jump_title:boolean; //Jump to SOng MOd-YTrue if search for Title
-
- EqualizerBands: array of Byte;
- EqualizerTime: Cardinal;
- EqualizerTime2: Byte;
-
- //Party Mod
- Mode: Byte; //0 = Standard, 1= Go to PartyMode after Selection + Change to Random Song at Show
- //party Statics (Joker)
- StaticTeam1Joker1: Cardinal;
- StaticTeam1Joker2: Cardinal;
- StaticTeam1Joker3: Cardinal;
- StaticTeam1Joker4: Cardinal;
- StaticTeam1Joker5: Cardinal;
-
- StaticTeam2Joker1: Cardinal;
- StaticTeam2Joker2: Cardinal;
- StaticTeam2Joker3: Cardinal;
- StaticTeam2Joker4: Cardinal;
- StaticTeam2Joker5: Cardinal;
-
- StaticTeam3Joker1: Cardinal;
- StaticTeam3Joker2: Cardinal;
- StaticTeam3Joker3: Cardinal;
- StaticTeam3Joker4: Cardinal;
- StaticTeam3Joker5: Cardinal;
-
- StaticParty: Array of Cardinal;
- TextParty: Array of Cardinal;
- StaticNonParty: Array of Cardinal;
- TextNonParty: Array of Cardinal;
-
-
- constructor Create; override;
- procedure SetScroll;
- procedure SetScroll1;
- procedure SetScroll2;
- procedure SetScroll3;
- procedure SetScroll4;
- procedure SetScroll5;
- procedure SetScroll6;
- function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
- function Draw: boolean; override;
- procedure onShow; override;
- procedure onHide; override;
- procedure SelectNext;
- procedure SelectPrev;
- procedure UpdateLCD;
- procedure SkipTo(Target: Cardinal);
- procedure FixSelected; //Show Wrong Song when Tabs on Fix
- procedure FixSelected2; //Show Wrong Song when Tabs on Fix
- procedure ShowCatTL(Cat: Integer);// Show Cat in Top left
- procedure ShowCatTLCustom(Caption: String);// Show Custom Text in Top left
- procedure HideCatTL;// Show Cat in Tob left
- procedure Refresh; //Refresh Song Sorting
- procedure DrawEqualizer;
- procedure ChangeMusic;
- //Party Mode
- procedure SelectRandomSong;
- procedure SetJoker;
- procedure SetStatics;
- //procedures for Menu
- procedure StartSong;
- procedure OpenEditor;
- procedure DoJoker(Team: Byte);
- procedure SelectPlayers;
-
- procedure UnLoadDetailedCover;
-
- //Extensions
- procedure DrawExtensions;
- end;
-
-implementation
-uses UGraphic, UMain, UCovers, math, OpenGL12, Windows, USkins, UDLLManager, UParty, UPlaylist, UScreenSongMenu;
-
-// ***** Public methods ****** //
-
-//Show Wrong Song when Tabs on Fix
-procedure TScreenSong.FixSelected;
-var I, I2: Integer;
- begin
- if CatSongs.VisibleSongs > 0 then
- begin
- I2:= 0;
- for I := low(CatSongs.Song) to High(Catsongs.Song) do
- begin
- if CatSongs.Song[I].Visible then
- inc(I2);
-
- if I = Interaction - 1 then
- break;
- end;
-
- SongCurrent := I2;
- SongTarget := I2;
- end;
- end;
-
-procedure TScreenSong.FixSelected2;
-var I, I2: Integer;
- begin
- if CatSongs.VisibleSongs > 0 then
- begin
- I2:= 0;
- for I := low(CatSongs.Song) to High(Catsongs.Song) do
- begin
- if CatSongs.Song[I].Visible then
- inc(I2);
-
- if I = Interaction - 1 then
- break;
- end;
-
- SongTarget := I2;
- end;
- end;
-//Show Wrong Song when Tabs on Fix End
-
- procedure TScreenSong.ShowCatTLCustom(Caption: String);// Show Custom Text in Top left
- begin
- Text[TextCat].Text := Caption;
- Text[TextCat].Visible := true;
- Static[StaticCat].Visible := False;
- end;
-
- //Show Cat in Top Left Mod
- procedure TScreenSong.ShowCatTL(Cat: Integer);
- begin
- //Change
- Text[TextCat].Text := CatSongs.Song[Cat].Artist;
- //showmessage(CatSongs.Song[Cat].Path + CatSongs.Song[Cat].Cover);
- //Static[StaticCat].Texture := Texture.GetTexture(Button[Cat].Texture.Name, 'Plain', true);
-
- Static[StaticCat].Texture := Texture.GetTexture(Button[Cat].Texture.Name, 'Plain', true);
- //Texture.GetTexture(Button[Cat].Texture.Name, 'Plain', false);
- //Button[Cat].
- //Cover
-
-
- //Show
- Text[TextCat].Visible := true;
- Static[StaticCat].Visible := True;
- end;
-
- procedure TScreenSong.HideCatTL;
- begin
- //Hide
- //Text[TextCat].Visible := false;
- Static[StaticCat].Visible := false;
- //New -> Show Text specified in Theme
- Text[TextCat].Visible := True;
- Text[TextCat].Text := Theme.Song.TextCat.Text;
- end;
- //Show Cat in Top Left Mod End
-
-
-// Method for input parsing. If False is returned, GetNextWindow
-// should be checked to know the next window to load;
-function TScreenSong.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
-var
- I: integer;
- I2: integer;
- HS: integer;
- SDL_ModState: Word;
- Letter: Char;
-begin
- Result := true;
-
- //Song Screen Extensions (Jumpto + Menu)
- if (ScreenSongMenu.Visible) then
- begin
- Result := ScreenSongMenu.ParseInput(PressedKey, ScanCode, PressedDown);
- Exit;
- end
- else if (ScreenSongJumpto.Visible) then
- begin
- Result := ScreenSongJumpto.ParseInput(PressedKey, ScanCode, PressedDown);
- Exit;
- end;
-
- If (PressedDown) Then
- begin // Key Down
-
- SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
- + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT);
-
- //Jump to Artist/Titel
- if (SDL_ModState and KMOD_LALT <> 0) AND (Mode = 0) AND (PressedKey >= SDLK_A) AND (PressedKey <= SDLK_Z) then
- begin
- Letter := UpCase(Chr(ScanCode));
- I2 := Length(CatSongs.Song);
-
- //Jump To Titel
- if (SDL_ModState = KMOD_LALT or KMOD_LSHIFT) then
- begin
- For I := 1 to high(CatSongs.Song) do
- begin
- if (CatSongs.Song[(I + Interaction) mod I2].Visible) AND (Length(CatSongs.Song[(I + Interaction) mod I2].Title)>0) AND (UpCase(CatSongs.Song[(I + Interaction) mod I2].Title[1]) = Letter) then
- begin
- SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2));
-
- Music.PlayChange;
-
- ChangeMusic;
- SetScroll4;
- UpdateLCD;
- //Break and Exit
- Exit;
- end;
- end;
- end
- //Jump to Artist
- else if (SDL_ModState = KMOD_LALT) then
- begin
- For I := 1 to high(CatSongs.Song) do
- begin
- if (CatSongs.Song[(I + Interaction) mod I2].Visible) AND (Length(CatSongs.Song[(I + Interaction) mod I2].Artist)>0) AND (UpCase(CatSongs.Song[(I + Interaction) mod I2].Artist[1]) = Letter) then
- begin
- SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2));
-
- Music.PlayChange;
-
- ChangeMusic;
- SetScroll4;
- UpdateLCD;
-
- //Break and Exit
- Exit;
- end;
- end;
- end;
- Exit;
- end;
-
- case PressedKey of
- SDLK_Q:
- begin
- Result := false;
- end;
-
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- if (Mode = 0) then
- begin
- //On Escape goto Cat-List Hack
- if (Ini.Tabs_at_startup = 1) AND (CatSongs.CatNumShow <> -1) then
- begin
- //Find Category
- I := Interaction;
- while not catsongs.Song[I].Main do
- begin
- Dec (I);
- if (I < low(catsongs.Song)) then
- break;
- end;
- if (I<= 1) then
- Interaction := high(catsongs.Song)
- else
- Interaction := I - 1;
-
- //Stop Music
- Music.Stop;
-
- CatSongs.ShowCategoryList;
-
- //Show Cat in Top Left Mod
- HideCatTL;
-
-
- //Show Wrong Song when Tabs on Fix
- SelectNext;
- FixSelected;
- //SelectPrev;
- //CatSongs.Song[0].Visible := False;
- end
- else
- begin
- //On Escape goto Cat-List Hack End
- //Tabs off and in Search or Playlist -> Go back to Song view
- if (CatSongs.CatNumShow < -1) then
- begin
- //Atm: Set Empty Filter
- CatSongs.SetFilter('', 0);
-
- //Show Cat in Top Left Mod
- HideCatTL;
- Interaction := 0;
-
- //Show Wrong Song when Tabs on Fix
- SelectNext;
- FixSelected;
-
- ChangeMusic;
- end
- else
- begin
- Music.Stop;
- Music.PlayBack;
-
- FadeTo(@ScreenMain);
- end;
-
- end;
- end
- //When in party Mode then Ask before Close
- else if (Mode = 1) then
- begin
- Music.PlayBack;
- CheckFadeTo(@ScreenMain,'MSG_END_PARTY');
- end;
- end;
- SDLK_RETURN:
- begin
- if Length(Songs.Song) > 0 then
- begin
- {$IFDEF UseSerialPort}
- // PortWriteB($378, 0);
- {$ENDIF}
- if CatSongs.Song[Interaction].Main then
- begin // clicked on Category Button
-
- //Show Cat in Top Left Mod
- ShowCatTL (Interaction);
-
- //I := CatSongs.VisibleIndex(Interaction);
- CatSongs.ClickCategoryButton(Interaction);
- {I2 := CatSongs.VisibleIndex(Interaction);
- SongCurrent := SongCurrent - I + I2;
- SongTarget := SongTarget - I + I2; }
-
-// if I<>I2 then beep;
- // SetScroll4;
-
- //Show Wrong Song when Tabs on Fix
- SelectNext;
- FixSelected;
-
- //Play Music:
- ChangeMusic;
-
- end else begin // clicked on song
- if (Mode = 0) then //Normal Mode -> Start Song
- begin
- //Do the Action that is specified in Ini
- case Ini.OnSongClick of
- 0: StartSong;
- 1: SelectPlayers;
- 2:begin
- If (CatSongs.CatNumShow = -3) then
- ScreenSongMenu.MenuShow(SM_Playlist)
- else
- ScreenSongMenu.MenuShow(SM_Main);
- end;
- end;
- end
- else if (Mode = 1) then //PartyMode -> Show Menu
- begin
- if (Ini.PartyPopup = 1) then
- ScreenSongMenu.MenuShow(SM_Party_Main)
- else
- ScreenSong.StartSong;
- end;
- end;
- end;
- end;
-
- SDLK_M: //Show SongMenu
- begin
- if (Length(Songs.Song) > 0) then begin
- if (Mode = 0) then begin
- if not CatSongs.Song[Interaction].Main then begin // clicked on Song
- if CatSongs.CatNumShow = -3 then
- ScreenSongMenu.MenuShow(SM_Playlist)
- else
- ScreenSongMenu.MenuShow(SM_Main);
- end
- else
- begin
- ScreenSongMenu.MenuShow(SM_Playlist_Load);
- end;
- end //Party Mode -> Show Party Menu
- else ScreenSongMenu.MenuShow(SM_Party_Main);
- end;
- end;
-
- SDLK_P: //Show Playlist Menu
- begin
- if (Length(Songs.Song) > 0) AND (Mode = 0) then begin
- ScreenSongMenu.MenuShow(SM_Playlist_Load);
- end;
- end;
-
- SDLK_J: //Show Jumpto Menu
- begin
- if (Length(Songs.Song) > 0) AND (Mode = 0) then
- begin
- ScreenSongJumpto.Visible := True;
- end;
- end;
-
- SDLK_DOWN:
- begin
- if (Mode = 0) then
- begin
- //Only Change Cat when not in Playlist or Search Mode
- if (CatSongs.CatNumShow > -2) then
- begin
- //Cat Change Hack
- if Ini.Tabs_at_startup = 1 then
- begin
- I := Interaction;
- if I <= 0 then I := 1;
-
- while not catsongs.Song[I].Main do
- begin
- Inc (I);
- if (I > high(catsongs.Song)) then
- I := low(catsongs.Song);
- end;
-
- Interaction := I;
-
- //Show Cat in Top Left Mod
- ShowCatTL (Interaction);
-
- CatSongs.ClickCategoryButton(Interaction);
- SelectNext;
- FixSelected;
-
- //Play Music:
- Music.PlayChange;
- ChangeMusic;
-
- end;
-
- //
- //Cat Change Hack End}
- end;
- end;
- end;
- SDLK_UP:
- begin
- if (Mode = 0) then
- begin
- //Only Change Cat when not in Playlist or Search Mode
- if (CatSongs.CatNumShow > -2) then
- begin
- //Cat Change Hack
- if Ini.Tabs_at_startup = 1 then
- begin
- I := Interaction;
- I2 := 0;
- if I <= 0 then I := 1;
-
- while not catsongs.Song[I].Main or (I2 = 0) do
- begin
- if catsongs.Song[I].Main then
- Inc(I2);
- Dec (I);
- if (I < low(catsongs.Song)) then
- I := high(catsongs.Song);
- end;
-
- Interaction := I;
-
- //Show Cat in Top Left Mod
- ShowCatTL (I);
-
- CatSongs.ClickCategoryButton(I);
- SelectNext;
- FixSelected;
-
- //Play Music:
- Music.PlayChange;
- ChangeMusic;
- end;
- end;
- //Cat Change Hack End}
- end;
- end;
-
- SDLK_RIGHT:
- begin
- if (Length(Songs.Song) > 0) AND (Mode = 0) then begin
- Music.PlayChange;
- SelectNext;
-// InteractNext;
-// SongTarget := Interaction;
- ChangeMusic;
- SetScroll4;
- UpdateLCD;
- Light.LightOne(1, 200);
- end;
- end;
-
- SDLK_LEFT:
- begin
- if (Length(Songs.Song) > 0)AND (Mode = 0) then begin
- Music.PlayChange;
- SelectPrev;
- ChangeMusic;
- SetScroll4;
- UpdateLCD;
- Light.LightOne(0, 200);
- end;
- end;
-
- SDLK_E:
- begin
- OpenEditor;
- end;
-
- SDLK_R:
- begin
- if (Length(Songs.Song) > 0) AND (Mode = 0) then begin
-
- if (SDL_ModState = KMOD_LSHIFT) AND (Ini.Tabs_at_startup = 1) then //Random Category
- begin
- I2 := 0; //Count Cats
- for I:= low(CatSongs.Song) to high (CatSongs.Song) do
- if CatSongs.Song[I].Main then Inc(I2);
-
- I2 := Random (I2)+1; //Zufall
-
- //Find Cat:
- for I:= low(CatSongs.Song) to high (CatSongs.Song) do
- begin
- if CatSongs.Song[I].Main then
- Dec(I2);
- if (I2<=0) then
- begin
- //Show Cat in Top Left Mod
- ShowCatTL (I);
-
- Interaction := I;
-
- CatSongs.ShowCategoryList;
- CatSongs.ClickCategoryButton(I);
- SelectNext;
- FixSelected;
- break;
- end;
- end;
-
-
- end
- else if (SDL_ModState = KMOD_LCTRL) AND (Ini.Tabs_at_startup = 1) then //random in All Categorys
- begin
- repeat
- I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1;
- until CatSongs.Song[I2].Main = false;
-
- //Search Cat
- for I := I2 downto low(CatSongs.Song) do
- begin
- if CatSongs.Song[I].Main then
- break;
- end;
- //In I ist jetzt die Kategorie in I2 der Song
-
- //Choose Cat
- CatSongs.ShowCategoryList;
-
- //Show Cat in Top Left Mod
- ShowCatTL (I);
-
- CatSongs.ClickCategoryButton(I);
- SelectNext;
-
- //Fix: Not Existing Song selected:
- //if (I+1=I2) then Inc(I2);
-
- //Choose Song
- SkipTo(I2-I);
-
- end
- else //Random in one Category
- begin
- SkipTo(Random(CatSongs.VisibleSongs));
- end;
- Music.PlayChange;
-
- ChangeMusic;
- SetScroll4;
- UpdateLCD;
- end;
- end;
-
- SDLK_1:
- begin //Jocker
- if (Mode = 1) AND (PartySession.Teams.NumTeams >= 1) AND (PartySession.Teams.Teaminfo[0].Joker > 0) then
- begin
- //Joker spielen
- Dec(PartySession.Teams.Teaminfo[0].Joker);
- SelectRandomSong;
- SetJoker;
- end;
- end;
-
- SDLK_2:
- begin //Jocker
- if (Mode = 1) AND (PartySession.Teams.NumTeams >= 2) AND (PartySession.Teams.Teaminfo[1].Joker > 0) then
- begin
- //Joker spielen
- Dec(PartySession.Teams.Teaminfo[1].Joker);
- SelectRandomSong;
- SetJoker;
- end;
- end;
-
- SDLK_3:
- begin //Jocker
- if (Mode = 1) AND (PartySession.Teams.NumTeams >= 3) AND (PartySession.Teams.Teaminfo[2].Joker > 0) then
- begin
- //Joker spielen
- Dec(PartySession.Teams.Teaminfo[2].Joker);
- SelectRandomSong;
- SetJoker;
- end;
- end;
- end;
- end;
-end;
-
-constructor TScreenSong.Create;
-var
- Pet: integer;
- I: integer;
-Label CreateSongButtons;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.Song);
-
- TextArtist := AddText(Theme.Song.TextArtist);
- TextTitle := AddText(Theme.Song.TextTitle);
- TextNumber := AddText(Theme.Song.TextNumber);
-
- //Show Cat in Top Left mod
- TextCat := AddText(Theme.Song.TextCat);
- StaticCat := AddStatic(Theme.Song.StaticCat);
-
- //Show Video Icon Mod
- VideoIcon := AddStatic(Theme.Song.VideoIcon);
-
- //Party Mode
- StaticTeam1Joker1 := AddStatic(Theme.Song.StaticTeam1Joker1);
- StaticTeam1Joker2 := AddStatic(Theme.Song.StaticTeam1Joker2);
- StaticTeam1Joker3 := AddStatic(Theme.Song.StaticTeam1Joker3);
- StaticTeam1Joker4 := AddStatic(Theme.Song.StaticTeam1Joker4);
- StaticTeam1Joker5 := AddStatic(Theme.Song.StaticTeam1Joker5);
-
- StaticTeam2Joker1 := AddStatic(Theme.Song.StaticTeam2Joker1);
- StaticTeam2Joker2 := AddStatic(Theme.Song.StaticTeam2Joker2);
- StaticTeam2Joker3 := AddStatic(Theme.Song.StaticTeam2Joker3);
- StaticTeam2Joker4 := AddStatic(Theme.Song.StaticTeam2Joker4);
- StaticTeam2Joker5 := AddStatic(Theme.Song.StaticTeam2Joker5);
-
- StaticTeam3Joker1 := AddStatic(Theme.Song.StaticTeam3Joker1);
- StaticTeam3Joker2 := AddStatic(Theme.Song.StaticTeam3Joker2);
- StaticTeam3Joker3 := AddStatic(Theme.Song.StaticTeam3Joker3);
- StaticTeam3Joker4 := AddStatic(Theme.Song.StaticTeam3Joker4);
- StaticTeam3Joker5 := AddStatic(Theme.Song.StaticTeam3Joker5);
-
- //Load Party or NonParty specific Statics and Texts
- SetLength(StaticParty, Length(Theme.Song.StaticParty));
- for I := 0 to High(Theme.Song.StaticParty) do
- StaticParty[I] := AddStatic(Theme.Song.StaticParty[I]);
-
- SetLength(TextParty, Length(Theme.Song.TextParty));
- for I := 0 to High(Theme.Song.TextParty) do
- TextParty[I] := AddText(Theme.Song.TextParty[I]);
-
- SetLength(StaticNonParty, Length(Theme.Song.StaticNonParty));
- for I := 0 to High(Theme.Song.StaticNonParty) do
- StaticNonParty[I] := AddStatic(Theme.Song.StaticNonParty[I]);
-
- SetLength(TextNonParty, Length(Theme.Song.TextNonParty));
- for I := 0 to High(Theme.Song.TextNonParty) do
- TextNonParty[I] := AddText(Theme.Song.TextNonParty[I]);
-
- // Song List
-// Songs.LoadSongList; // moved to the UltraStar unit
- CatSongs.Refresh;
-
- if (length(CatSongs.Song) > 0) then
- begin
- //Set Length of Button Array one Time Instead of one time for every Song
- SetButtonLength(Length(CatSongs.Song));
-
- I := 0;
- CreateSongButtons:
-
- try
- for Pet := I to High(CatSongs.Song) do begin // creating all buttons
- // new
- Texture.Limit := 512;// 256 0.4.2 value, 512 in 0.5.0
-
- if not FileExists(CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover) then
- CatSongs.Song[Pet].Cover := ''; // 0.5.0: if cover not found then show 'no cover'
-
- if CatSongs.Song[Pet].Cover = '' then
- AddButton(300 + Pet*250, 140, 200, 200, Skin.GetTextureFileName('SongCover'), 'JPG', 'Plain', Theme.Song.Cover.Reflections)
- else begin
- // cache texture if there is a need to this
- if not Covers.CoverExists(CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover) then begin
- Texture.CreateCacheMipmap := true;
- Texture.GetTexture(CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover, 'Plain', true); // preloads textures and creates cache mipmap
- Texture.CreateCacheMipmap := false;
-
- // puts this texture to the cache file
- Covers.AddCover(CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover);
-
- // unload full size texture
- Texture.UnloadTexture(CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover, false);
-
- // we should also add mipmap texture by calling createtexture and use mipmap cache as data source
- end;
-
- // and now load it from cache file (small place for the optimization by eliminating reading it from file, but not here)
- AddButton(300 + Pet*250, 140, 200, 200, CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover, 'JPG', 'Plain', Theme.Song.Cover.Reflections);
- end;
- Texture.Limit := 1024*1024;
- I := -1;
- end;
- except
- //When Error is reported the First time for this Song
- if (I <> Pet) then
- begin
- //Some Error reporting:
- Log.LogError('Could not load Cover: ' + CatSongs.Song[Pet].Cover);
-
- //Change Cover to NoCover and Continue Loading
- CatSongs.Song[Pet].Cover := '';
- I := Pet;
- end
- else //when Error occurs Multiple Times(NoSong Cover is damaged), then start loading next Song
- begin
- Log.LogError('NoCover Cover is damaged!');
- try
- AddButton(300 + Pet*250, 140, 200, 200, '', 'JPG', 'Plain', Theme.Song.Cover.Reflections);
- except
- Messagebox(0, PChar('No Cover Image is damage. Could not Workaround Song Loading, Ultrastar will exit now.'), PChar(Language.Translate('US_VERSION')), MB_ICONERROR or MB_OK);
- Halt;
- end;
- I := Pet + 1;
- end;
- end;
-
- if (I <> -1) then
- GoTo CreateSongButtons;
-
- end;
-
- // Randomize Patch
- Randomize;
- //Equalizer
- SetLength(EqualizerBands, Theme.Song.Equalizer.Bands);
- //ClearArray
- For I := low(EqualizerBands) to high(EqualizerBands) do
- EqualizerBands[I] := 3;
-
- if (Length(CatSongs.Song) > 0) then
- Interaction := 0;
-end;
-
-procedure TScreenSong.SetScroll;
-var
- VS, B: Integer;
-begin
- VS := CatSongs.VisibleSongs;
- if VS > 0 then
- begin
- //Set Positions
- Case Theme.Song.Cover.Style of
- 3: SetScroll3;
- 5:begin
- if VS > 5 then
- SetScroll5
- else
- SetScroll4;
- end;
- 6: SetScroll6;
- else SetScroll4;
- end;
- //Set Visibility of Video Icon
- Static[VideoIcon].Visible := (CatSongs.Song[Interaction].Video <> '');
-
- //Set Texts:
- Text[TextArtist].Text := CatSongs.Song[Interaction].Artist;
- Text[TextTitle].Text := CatSongs.Song[Interaction].Title;
- if (Ini.Tabs_at_startup = 1) And (CatSongs.CatNumShow = -1) then
- begin
- Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].OrderNum) + '/' + IntToStr(CatSongs.CatCount);
- Text[TextTitle].Text := '(' + IntToStr(CatSongs.Song[Interaction].CatNumber) + ' ' + Language.Translate('SING_SONGS_IN_CAT') + ')';
- end
- else if (CatSongs.CatNumShow = -2) then
- Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS)
- else if (CatSongs.CatNumShow = -3) then
- Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS)
- else if (Ini.Tabs_at_startup = 1) then
- Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].CatNumber) + '/' + IntToStr(CatSongs.Song[Interaction - CatSongs.Song[Interaction].CatNumber].CatNumber)
- else
- Text[TextNumber].Text := IntToStr(Interaction+1) + '/' + IntToStr(Length(CatSongs.Song));
- end
- else
- begin
- Text[TextNumber].Text := '0/0';
- Text[TextArtist].Text := '';
- Text[TextTitle].Text := '';
- for B := 0 to High(Button) do
- Button[B].Visible := False;
-
- end;
-end;
-
-procedure TScreenSong.SetScroll1;
-var
- B: integer; // button
- BMin: integer; // button min
- BMax: integer; // button max
- Src: integer;
-// Dst: integer;
- Count: integer; // Dst is not used. Count is used.
- Ready: boolean;
-
- VisCount: integer; // count of visible (or selectable) buttons
- VisInt: integer; // visible position of interacted button
- Typ: integer; // 0 when all songs fits the screen
- Placed: integer; // number of placed visible buttons
-begin
-// Src := 0;
-// Dst := -1;
- Count := 1;
- Typ := 0;
- Ready := false;
- Placed := 0;
-
- VisCount := 0;
- for B := 0 to High(Button) do
- if CatSongs.Song[B].Visible then Inc(VisCount);
-
- VisInt := 0;
- for B := 0 to Interaction-1 do
- if CatSongs.Song[B].Visible then Inc(VisInt);
-
-
- if VisCount <= 6 then begin
- Typ := 0;
- end else begin
- if VisInt <= 3 then begin
- Typ := 1;
- Count := 7;
- Ready := true;
- end;
-
- if (VisCount - VisInt) <= 3 then begin
- Typ := 2;
- Count := 7;
- Ready := true;
- end;
-
- if not Ready then begin
- Typ := 3;
- Src := Interaction;
- end;
- end;
-
-
-
- // hide all buttons
- for B := 0 to High(Button) do begin
- Button[B].Visible := false;
- Button[B].Selectable := CatSongs.Song[B].Visible;
- end;
-
-{ for B := Src to Dst do begin
-// Button[B].Visible := true;
- Button[B].Visible := CatSongs.Song[B].Visible;
- Button[B].Selectable := Button[B].Visible;
- Button[B].Y := 140 + (B-Src) * 60;
- end;}
-
-
- if Typ = 0 then begin
- for B := 0 to High(Button) do begin
- if CatSongs.Song[B].Visible then begin
- Button[B].Visible := true;
- Button[B].Y := 140 + (Placed) * 60;
- Inc(Placed);
- end;
- end;
- end;
-
- if Typ = 1 then begin
- B := 0;
- while (Count > 0) do begin
- if CatSongs.Song[B].Visible then begin
- Button[B].Visible := true;
- Button[B].Y := 140 + (Placed) * 60;
- Inc(Placed);
- Dec(Count);
- end;
- Inc(B);
- end;
- end;
-
- if Typ = 2 then begin
- B := High(Button);
- while (Count > 0) do begin
- if CatSongs.Song[B].Visible then begin
- Button[B].Visible := true;
- Button[B].Y := 140 + (6-Placed) * 60;
- Inc(Placed);
- Dec(Count);
- end;
- Dec(B);
- end;
- end;
-
- if Typ = 3 then begin
- B := Src;
- Count := 4;
- while (Count > 0) do begin
- if CatSongs.Song[B].Visible then begin
- Button[B].Visible := true;
- Button[B].Y := 140 + (3+Placed) * 60;
- Inc(Placed);
- Dec(Count);
- end;
- Inc(B);
- end;
-
- B := Src-1;
- Placed := 0;
- Count := 3;
- while (Count > 0) do begin
- if CatSongs.Song[B].Visible then begin
- Button[B].Visible := true;
- Button[B].Y := 140 + (2-Placed) * 60;
- Inc(Placed);
- Dec(Count);
- end;
- Dec(B);
- end;
-
- end;
-
- if Length(Button) > 0 then
- Static[1].Texture.Y := Button[Interaction].Y - 5; // selection texture
-end;
-
-procedure TScreenSong.SetScroll2;
-var
- B: integer;
- Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu
- Wsp2: real;
-begin
- // liniowe
- for B := 0 to High(Button) do
- Button[B].X := 300 + (B - Interaction) * 260;
-
- if Length(Button) >= 3 then begin
- if Interaction = 0 then
- Button[High(Button)].X := 300 - 260;
-
- if Interaction = High(Button) then
- Button[0].X := 300 + 260;
- end;
-
- // kolowe
-{ for B := 0 to High(Button) do begin
- Wsp := (B - Interaction); // 0 dla srodka, -1 dla lewego, +1 dla prawego itd.
- Wsp2 := Wsp / Length(Button);
- Button[B].X := 300 + 10000 * sin(2*pi*Wsp2);
-// Button[B].Y := 140 + 50 * ;
- end;}
-end;
-
-procedure TScreenSong.SetScroll3; // with slide
-var
- B: integer;
- Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu
- Wsp2: real;
-begin
- SongTarget := Interaction;
-
- // liniowe
- for B := 0 to High(Button) do
- begin
- Button[B].X := 300 + (B - SongCurrent) * 260;
- if (Button[B].X < -Button[B].W) OR (Button[B].X > 800) then
- Button[B].Visible := False
- else
- Button[B].Visible := True;
- end;
-
-{ if Length(Button) >= 3 then begin
- if Interaction = 0 then
- Button[High(Button)].X := 300 - 260;
-
- if Interaction = High(Button) then
- Button[0].X := 300 + 260;
- end;}
-
- // kolowe
-{ for B := 0 to High(Button) do begin
- Wsp := (B - Interaction); // 0 dla srodka, -1 dla lewego, +1 dla prawego itd.
- Wsp2 := Wsp / Length(Button);
- Button[B].X := 300 + 10000 * sin(2*pi*Wsp2);
-// Button[B].Y := 140 + 50 * ;
- end;}
-end;
-
-procedure TScreenSong.SetScroll4; // rotate
-var
- B: integer;
- Wsp: real;
- Z, Z2: real;
- VS: integer;
-begin
- VS := CatSongs.VisibleSongs; // 0.5.0 (I): cached, very important
-
- // kolowe
- for B := 0 to High(Button) do begin
- Button[B].Visible := CatSongs.Song[B].Visible; // nowe
- if Button[B].Visible then begin // 0.5.0 optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed
-
- Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / VS {CatSongs.VisibleSongs};// 0.5.0 (II): takes another 16ms
-
- Z := (1 + cos(Wsp)) / 2;
- Z2 := (1 + 2*Z) / 3;
-
-
- Button[B].X := Theme.Song.Cover.X + (0.185 * Theme.Song.Cover.H * VS * sin(Wsp)) * Z2 - ((Button[B].H - Theme.Song.Cover.H)/2); // 0.5.0 (I): 2 times faster by not calling CatSongs.VisibleSongs
- Button[B].Z := Z / 2 + 0.3;
-
- Button[B].W := Theme.Song.Cover.H * Z2;
-
-// Button[B].Y := {50 +} 140 + 50 - 50 * Z2;
- Button[B].Y := Theme.Song.Cover.Y + (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7 ;
- Button[B].H := Button[B].W;
- end;
- end;
-end;
-
-(*
-procedure TScreenSong.SetScroll4; // rotate
-var
- B: integer;
- Wsp: real;
- Z: real;
- Z2, Z3: real;
- VS: integer;
- function modreal (const X, Y: real):real;
- begin
- Result := Frac(x / y) * y;
- if Result < -3 then
- Result := Result + Y
- else if Result > 3 then
- Result := Result - Y;
- end;
-begin
- VS := CatSongs.VisibleSongs; // 0.5.0 (I): cached, very important
- Z3 := 1;
- if VS < 12 then
- Z2 := VS
- else
- Z2 := 12;
-
- // kolowe
- for B := 0 to High(Button) do begin
- Button[B].Visible := CatSongs.Song[B].Visible; // nowe
- if Button[B].Visible then begin // 0.5.0 optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed
- if ((ModReal(CatSongs.VisibleIndex(B) - SongCurrent, VS)>-3) AND (ModReal(CatSongs.VisibleIndex(B) - SongCurrent, VS)<3)) then
- begin
- if CatSongs.VisibleIndex(B)> SongCurrent then
- Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / Z2
- else
- Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / Z2;
-
- Z3 := 2;
- Z := (1 + cos(Wsp)) / 2;
- //Z2 := (1 + 2*Z) / 3;
- //Z2 := (0.5 + Z/2);
- //Z2 := sin(Wsp);
-
- //Z2 := Power (Z2,Z3);
-
- Button[B].W := Theme.Song.CoverW * Power(cos(Wsp), Z3);//Power(Z2, 3);
-
- //Button[B].X := Theme.Song.CoverX + ({Theme.Song.CoverX + Theme.Song.CoverW/2 + Theme.Song.CoverW*0.18 * VS {CatSongs.VisibleSongs {Length(Button) * sin(Wsp) {- Theme.Song.CoverX - Theme.Song.CoverW) * Z2; // 0.5.0 (I): 2 times faster by not calling CatSongs.VisibleSongs
- if (sin(Wsp)<0) then
- Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX + Theme.Song.CoverW - Button[B].W
- else //*Theme.Song.CoverW*0.004*Z3
- Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX;
- Button[B].Z := Z-0.00001;
-
-// Button[B].Y := {50 + 140 + 50 - 50 * Z2;
- // Button[B].Y := (Theme.Song.CoverY + 40 + 50 - 50 * Z2);
- Button[B].Y := (Theme.Song.CoverY + Theme.Song.CoverW - Button[B].W);
- Button[B].H := Button[B].W;
- Button[B].Visible := True;
- end
- {else if (((CatSongs.VisibleIndex(B) - SongCurrent)>-3) AND ((CatSongs.VisibleIndex(B) - SongCurrent)<3)) OR ((round (CatSongs.VisibleIndex(B) - SongCurrent) mod VS > -3) AND ((CatSongs.VisibleIndex(B) - SongCurrent)<3)) then
- begin
- Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / 12 ;// 0.5.0 (II): takes another 16ms
-
- Z := (1 + cos(Wsp)) / 2 -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
-
- Button[B].W := Theme.Song.CoverW * Power(cos(Wsp), Z3);//Power(Z2, 3);
-
- if (sin(Wsp)<0) then
- Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX + Theme.Song.CoverW - Button[B].W
- else
- Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX;
-
- Button[B].Z := Z;
-
- Button[B].Y := (Theme.Song.CoverY + Theme.Song.CoverW - Button[B].W);
-
- Button[B].H := Button[B].W;
- Button[B].Visible := True;
- end
- else Button[B].Visible := False;
- end;
- end;
-end; *)
-
-procedure TScreenSong.SetScroll5; // rotate
-var
- B: integer;
- Angle: real;
- Pos: Real;
- VS: integer;
- diff: real;
- X: Real;
- helper: real;
-begin
- VS := CatSongs.VisibleSongs; // cache Visible Songs
- {Vars
- Theme.Song.CoverW: Radius des Kreises
- Theme.Song.CoverX: X Pos Linke Kante des gewählten Covers
- Theme.Song.CoverX: Y Pos Obere Kante des gewählten Covers
- Theme.Song.CoverH: Höhe der Cover
-
- (CatSongs.VisibleIndex(B) - SongCurrent)/VS = Abstand zum MIttleren Cover in %
- }
-
- //Change Pos of all Buttons
- for B := low(Button) to high(Button) do
- begin
- Button[B].Visible := CatSongs.Song[B].Visible; //Adjust Visibility
- if Button[B].Visible then //Only Change Pos for Visible Buttons
- begin
- Pos := (CatSongs.VisibleIndex(B) - SongCurrent);
- if (Pos < -VS/2) then
- Pos := Pos + VS
- else if (Pos > VS/2) then
- Pos := Pos - VS;
-
- if (Abs(Pos) < 2.5) then {fixed Positions}
- begin
- Angle := Pi * (Pos / 5);
-// Button[B].Visible := False;
-
- Button[B].H := Abs(Theme.Song.Cover.H * cos(Angle*0.8));//Power(Z2, 3);
-
-// Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
- Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
-
- Button[B].Z := 0.95 - Abs(Pos) * 0.01;
-
- Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Abs(Theme.Song.Cover.H * cos(Angle))) * 0.5);
-
- Button[B].W := Button[B].H;
-
- Diff := (Button[B].H - Theme.Song.Cover.H)/2;
-
-
- X := Sin(Angle*1.3)*0.9;
-
- Button[B].X := Theme.Song.Cover.X + Theme.Song.Cover.W * X - Diff;
-
- end
- else
- begin {Behind the Front Covers}
-
- // limit-bg-covers hack
- if (abs(abs(Pos)-VS/2)>10) then Button[B].Visible:=False;
- // end of limit-bg-covers hack
-
- if Pos < 0 then
- Pos := (Pos - VS/2)/VS
- else
- Pos := (Pos + VS/2)/VS;
-
- Angle := pi * Pos*2;
- if VS > 24 then
- begin
- if Angle < 0 then helper:=-1 else helper:=1;
- Angle:=2*pi-abs(Angle);
- Angle:=Angle*(VS/24);
- Angle:=(2*pi-Angle)*helper;
- end;
-
- Button[B].Z := (0.4 - Abs(Pos/4)) -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
-
- Button[B].H :=0.6*(Theme.Song.Cover.H-Abs(Theme.Song.Cover.H * cos(Angle/2)*0.8));//Power(Z2, 3);
-
- Button[B].W := Button[B].H;
-
- Button[B].Y := Theme.Song.Cover.Y - (Button[B].H - Theme.Song.Cover.H)*0.75;
-
-// Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
- Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
-
- Diff := (Button[B].H - Theme.Song.Cover.H)/2;
-
- Button[B].X := Theme.Song.Cover.X+Theme.Song.Cover.H/2-Button[b].H/2+Theme.Song.Cover.W/320*((Theme.Song.Cover.H)*sin(Angle/2)*1.52);
-
- end;
-
- //Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Button[B].H)/1.5); //Cover at down border of the change field
-// Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Button[B].H) * 0.7);
-
- end;
- end;
-end;
-
-procedure TScreenSong.SetScroll6; // rotate (slotmachine style)
-var
- B: integer;
- Angle: real;
- Pos: Real;
- VS: integer;
- diff: real;
- X: Real;
- Wsp: real;
- Z, Z2: real;
-begin
- VS := CatSongs.VisibleSongs; // cache Visible Songs
- if VS <=5 then begin
- // kolowe
- for B := 0 to High(Button) do
- begin
- Button[B].Visible := CatSongs.Song[B].Visible; // nowe
- if Button[B].Visible then begin // 0.5.0 optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed
-
- Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / VS {CatSongs.VisibleSongs};// 0.5.0 (II): takes another 16ms
-
- Z := (1 + cos(Wsp)) / 2;
- Z2 := (1 + 2*Z) / 3;
-
-
- Button[B].Y := Theme.Song.Cover.Y + (0.185 * Theme.Song.Cover.H * VS * sin(Wsp)) * Z2 - ((Button[B].H - Theme.Song.Cover.H)/2); // 0.5.0 (I): 2 times faster by not calling CatSongs.VisibleSongs
- Button[B].Z := Z / 2 + 0.3;
-
- Button[B].W := Theme.Song.Cover.H * Z2;
-
-// Button[B].Y := {50 +} 140 + 50 - 50 * Z2;
- Button[B].X := Theme.Song.Cover.X + (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7 ;
- Button[B].H := Button[B].W;
- end;
- end;
- end
- else begin
-
- //Change Pos of all Buttons
- for B := low(Button) to high(Button) do
- begin
- Button[B].Visible := CatSongs.Song[B].Visible; //Adjust Visibility
- if Button[B].Visible then //Only Change Pos for Visible Buttons
- begin
- Pos := (CatSongs.VisibleIndex(B) - SongCurrent);
- if (Pos < -VS/2) then
- Pos := Pos + VS
- else if (Pos > VS/2) then
- Pos := Pos - VS;
-
- if (Abs(Pos) < 2.5) then {fixed Positions}
- begin
- Angle := Pi * (Pos / 5);
-// Button[B].Visible := False;
-
- Button[B].H := Abs(Theme.Song.Cover.H * cos(Angle*0.8));//Power(Z2, 3);
-
- Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
-
- Button[B].Z := 0.95 - Abs(Pos) * 0.01;
-
- Button[B].X := (Theme.Song.Cover.X + (Theme.Song.Cover.H - Abs(Theme.Song.Cover.H * cos(Angle))) * 0.5);
-
- Button[B].W := Button[B].H;
-
- Diff := (Button[B].H - Theme.Song.Cover.H)/2;
-
-
- X := Sin(Angle*1.3)*0.9;
-
- Button[B].Y := Theme.Song.Cover.Y + Theme.Song.Cover.W * X - Diff;
- end
- else
- begin {Behind the Front Covers}
-
- // limit-bg-covers hack
- if (abs(VS/2-abs(Pos))>10) then Button[B].Visible:=False;
- if VS > 25 then VS:=25;
- // end of limit-bg-covers hack
-
- if Pos < 0 then
- Pos := (Pos - VS/2)/VS
- else
- Pos := (Pos + VS/2)/VS;
-
- Angle := pi * Pos*2;
-
- Button[B].Z := (0.4 - Abs(Pos/4)) -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
-
- Button[B].H :=0.6*(Theme.Song.Cover.H-Abs(Theme.Song.Cover.H * cos(Angle/2)*0.8));//Power(Z2, 3);
-
- Button[B].W := Button[B].H;
-
- Button[B].X := Theme.Song.Cover.X - (Button[B].H - Theme.Song.Cover.H)*0.5;
-
-
- Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
-
- Button[B].Y := Theme.Song.Cover.Y+Theme.Song.Cover.H/2-Button[b].H/2+Theme.Song.Cover.W/320*(Theme.Song.Cover.H*sin(Angle/2)*1.52);
- end;
- end;
- end;
- end;
-end;
-
-
-procedure TScreenSong.onShow;
-begin
- Music.Stop;
-
- if Ini.Players <= 3 then PlayersPlay := Ini.Players + 1;
- if Ini.Players = 4 then PlayersPlay := 6;
-
- //Cat Mod etc
- if (Ini.Tabs_at_startup = 1) AND (CatSongs.CatNumShow = -1) then
- begin
- CatSongs.ShowCategoryList;
- FixSelected;
- //Show Cat in Top Left Mod
- HideCatTL;
- end;
-
-
- if Length(CatSongs.Song) > 0 then begin
- //Load Music only when Song Preview is activated
- if (Ini.PreviewVolume <> 0) then
- begin
- Music.SetLoop(false);
- Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3);
- Music.MoveTo(Music.Length / 4);
- Music.Play;
-
- //Set Preview Volume
- Music.SetMusicVolume (Ini.PreviewVolume * 10);
- {//if Music Fade is activated, Set Volume to 0 %
- if (Ini.PreviewFading <> 0) then
- Music.SetMusicVolume(0);}
- end;
-
- SetScroll;
- UpdateLCD;
- end;
-
- //Playlist Mode
- if (Mode = 0) then
- begin
- //If Playlist Shown -> Select Next automatically
- if (CatSongs.CatNumShow = -3) then
- begin
- SelectNext;
- ChangeMusic;
- end;
- end
- //Party Mode
- else if (Mode = 1) then
- begin
-
- SelectRandomSong;
- //Show Menu directly in PartyMode
- //But only if selected in Options
- if (Ini.PartyPopup = 1) then
- begin
- ScreenSongMenu.MenuShow(SM_Party_Main);
- end;
-
-
- end;
-
- SetJoker;
- SetStatics;
-end;
-
-procedure TScreenSong.onHide;
-begin
- //When Music Fading is activated, Turn Music to 100 %
- If (Ini.PreviewVolume <> 100) or (Ini.PreviewFading <> 0) then
- Music.SetMusicVolume(100);
-
- //If Preview is deactivated: Load MUsicfile now
- If (Ini.PreviewVolume = 0) then
- Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3);
-
- //When hide then Stop Music (For Party Mode Popup on Exit)
- if (Display.NextScreen <> @ScreenSing) and (Display.NextScreen <> @ScreenSingModi) and (Music <> nil) then
- Music.Stop;
-end;
-
-procedure TScreenSong.DrawExtensions;
-begin
- //Draw Song Menu
- if (ScreenSongMenu.Visible) then
- begin
- ScreenSongMenu.Draw;
- end
- else if (ScreenSongJumpto.Visible) then
- begin
- ScreenSongJumpto.Draw;
- end
-end;
-
-function TScreenSong.Draw: boolean;
-var
- dx: real;
- dt: real;
- I: Integer;
-begin
- dx := SongTarget-SongCurrent;
- dt := TimeSkip*7;
- if dt > 1 then dt := 1;
- SongCurrent := SongCurrent + dx*dt;
-
-{ if SongCurrent > Catsongs.VisibleSongs then begin
- SongCurrent := SongCurrent - Catsongs.VisibleSongs;
- SongTarget := SongTarget - Catsongs.VisibleSongs;
- end;}
-
-// Log.BenchmarkStart(5);
- SetScroll;
-// Log.BenchmarkEnd(5);
-// Log.LogBenchmark('SetScroll4', 5);
-
- //Fading Functions, Only if Covertime is under 5 Seconds
- If (CoverTime < 5) then
- begin
- // 0.5.0: cover fade
- if (CoverTime < 1) and (CoverTime + TimeSkip >= 1) then begin
- // load new texture
- Texture.GetTexture(Button[Interaction].Texture.Name, 'Plain', false);
- Button[Interaction].Texture.Alpha := 1;
- Button[Interaction].Texture2 := Texture.GetTexture(Button[Interaction].Texture.Name, 'Plain', false);
- Button[Interaction].Texture2.Alpha := 1;
- end;
-
- //Song Fade
- if (CatSongs.VisibleSongs > 0) AND (Ini.PreviewVolume <> 0) AND (Not CatSongs.Song[Interaction].Main) AND (Ini.PreviewFading <> 0) then
- begin
- //Start Song Fade after a little Time, to prevent Song to be Played on Scrolling
- if (CoverTime < 0.2) and (CoverTime + TimeSkip >= 0.2) then
- Music.Play;
-
- //Update Song Volume
- if (CoverTime < Ini.PreviewFading) then
- Music.SetMusicVolume(Round (CoverTime * Ini.PreviewVolume / Ini.PreviewFading * 10))
- else
- Music.SetMusicVolume(Ini.PreviewVolume * 10);
-
- end;
-
-
- //Update Fading Time
- CoverTime := CoverTime + TimeSkip;
-
- //Update Fading Texture
- Button[Interaction].Texture2.Alpha := (CoverTime - 1) * 1.5;
- if Button[Interaction].Texture2.Alpha > 1 then Button[Interaction].Texture2.Alpha := 1;
-
- end;
-
- //inherited Draw;
- //heres a little Hack, that causes the Statics
- //are Drawn after the Buttons because of some Blending Problems.
- //This should cause no Problems because all Buttons on this screen
- //Has Z Position.
- //Draw BG
- DrawBG;
-
- //Instead of Draw FG Procedure:
- //We draw Buttons for our own
- for I := 0 to Length(Button) - 1 do
- Button[I].Draw;
-
- // Statics
- for I := 0 to Length(Static) - 1 do
- Static[I].Draw;
-
- // and texts
- for I := 0 to Length(Text) - 1 do
- Text[I].Draw;
-
-
- //Draw Equalizer
- if Theme.Song.Equalizer.Visible then
- DrawEqualizer;
-
- DrawExtensions;
-
-end;
-
-procedure TScreenSong.SelectNext;
-var
- Skip: integer;
- I: integer;
- VS: Integer;
-begin
- VS := CatSongs.VisibleSongs;
-
- if VS > 0 then
- begin
- UnLoadDetailedCover;
-
- Skip := 1;
-
- // this 1 could be changed by CatSongs.FindNextVisible
- while (not CatSongs.Song[(Interaction + Skip) mod Length(Interactions)].Visible) do Inc(Skip);
-
- SongTarget := SongTarget + 1;//Skip;
-
- Interaction := (Interaction + Skip) mod Length(Interactions);
-
- // try to keep all at the beginning
- if SongTarget > VS-1 then begin
- SongTarget := SongTarget - VS;
- SongCurrent := SongCurrent - VS;
- end;
-
- end;
- // Interaction -> Button, ktorego okladke przeczytamy
- // Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, 'Plain', false); // 0.5.0: show uncached texture
-end;
-
-procedure TScreenSong.SelectPrev;
-var
- Skip: integer;
- I: integer;
- VS: Integer;
-begin
- VS := CatSongs.VisibleSongs;
-
- if VS > 0 then
- begin
- UnLoadDetailedCover;
-
- Skip := 1;
-
- while (not CatSongs.Song[(Interaction - Skip + Length(Interactions)) mod Length(Interactions)].Visible) do Inc(Skip);
- SongTarget := SongTarget - 1;//Skip;
-
- Interaction := (Interaction - Skip + Length(Interactions)) mod Length(Interactions);
-
- // try to keep all at the beginning
- if SongTarget < 0 then begin
- SongTarget := SongTarget + CatSongs.VisibleSongs;
- SongCurrent := SongCurrent + CatSongs.VisibleSongs;
- end;
-
- // Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, 'Plain', false); // 0.5.0: show uncached texture
- end;
-end;
-
-procedure TScreenSong.UpdateLCD;
-begin
- LCD.HideCursor;
- LCD.Clear;
- LCD.WriteText(1, Text[TextArtist].Text);
- LCD.WriteText(2, Text[TextTitle].Text);
-end;
-
-//Procedure Change current played Preview
-procedure TScreenSong.ChangeMusic;
-begin
- //When Music Preview is avtivated -> then Change Music
- if (Ini.PreviewVolume <> 0) then
- begin
- if (NOT CatSongs.Song[Interaction].Main) AND(CatSongs.VisibleSongs > 0) then
- begin
- Music.Close;
- if Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3) then begin
- Music.MoveTo(Music.Length / 4);
- //If Song Fading is activated then don't Play directly, and Set Volume to Null, else Play normal
- if (Ini.PreviewFading = 0) then
- Music.Play
- else
- Music.SetMusicVolume(0);
- end;
- end
- else
- Music.Stop;
- end;
-end;
-
-procedure TScreenSong.SkipTo(Target: Cardinal); // 0.5.0
-var
- Skip: integer;
- I: integer;
-begin
- UnLoadDetailedCover;
-
- Interaction := High(CatSongs.Song);
- SongTarget := 0;
-
- for I := 1 to Target+1 do
- SelectNext;
-
- FixSelected2;
-end;
-
-procedure TScreenSong.DrawEqualizer;
-var
- Data: TFFTData; //Audio Data
- I, J: Integer;
- Res: byte;
- A, B: Integer;
- PosX, PosY: Integer;
- Pos: Real;
-begin
-if (not Music.Finished) AND (Theme.Song.Equalizer.Length > 0) then
-begin
-
-
- A := GetTickCount div 44;
-
- if (A <> EqualizerTime) then
- begin
- EqualizerTime := A;
- Data := Music.GetFFTData;
-
- B:=0;
- Pos := 0;
- Res := ceil(92/Theme.Song.Equalizer.Bands);//How much channels are used for one Band
-
- //Change Lengths
- for I := 0 to (Res * Theme.Song.Equalizer.Bands - 1) do
- begin
- A := floor(I/Res);
-
- if (A<>B) then //Band changed
- begin
- if (Pos <= Theme.Song.Equalizer.Length) then
- begin
- if ((Pos < EqualizerBands[B]) AND (EqualizerBands[B]>1)) then
- EqualizerBands[B] := EqualizerBands[B] - 1
- else
- EqualizerBands[B] := floor(Pos);
- end
- else
- EqualizerBands[B] := 1;
-
- B := A;
- Pos := 0;
- end;
-
- if I > 35 then
- Data[i] := Data[i] * 8
- else if I > 11 then
- Data[i] := Data[i] * 4.5
- else
- Data[i] := Data[i] * 1.1;
-
- if (Data[i] >= 1) then
- Data[i] := 0.9999999999999;
-
- if Data[i]*Theme.Song.Equalizer.Length > Pos then
- Pos := Data[i]*Theme.Song.Equalizer.Length;
- end;
-
- //Change Last Band
- if (EqualizerBands[B] <= Theme.Song.Equalizer.Length) then
- begin
- if ((Pos < EqualizerBands[B]) AND (EqualizerBands[B]>1)) then
- EqualizerBands[B] := EqualizerBands[B] - 1
- else
- EqualizerBands[B] := floor(Pos)
- end
- else
- EqualizerBands[B] := 1;
- end;
-
- //Draw every Channel
- glColor4f(Theme.Song.Equalizer.ColR, Theme.Song.Equalizer.ColG, Theme.Song.Equalizer.ColB, Theme.Song.Equalizer.Alpha); //Set Color
- glDisable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
-
- PosY := Theme.Song.Equalizer.Y;
- PosX := Theme.Song.Equalizer.X;
-
- For I := 0 to Theme.Song.Equalizer.Bands-1 do
- begin
- if Theme.Song.Equalizer.Direction then
- PosY := Theme.Song.Equalizer.Y //+ (Theme.Song.Equalizer.H + Theme.Song.Equalizer.Space) * Theme.Song.Equalizer.Length
- else
- PosX := Theme.Song.Equalizer.X;
- //Draw for every visible quad
- for J := 1 to EqualizerBands[I] do
- begin
- glBegin(GL_QUADS);
- glVertex3f(PosX, PosY, Theme.Song.Equalizer.Z);
- glVertex3f(PosX, PosY+Theme.Song.Equalizer.H, Theme.Song.Equalizer.Z);
- glVertex3f(PosX+Theme.Song.Equalizer.W, PosY+Theme.Song.Equalizer.H, Theme.Song.Equalizer.Z);
- glVertex3f(PosX+Theme.Song.Equalizer.W, PosY, Theme.Song.Equalizer.Z);
- glEnd;
-
- if Theme.Song.Equalizer.Direction then //Vertically
- PosY := PosY - Theme.Song.Equalizer.H - Theme.Song.Equalizer.Space
- else //Horizontally
- PosX := PosX + Theme.Song.Equalizer.W + Theme.Song.Equalizer.Space;
- end;
- if Theme.Song.Equalizer.Direction then //Horizontally
- PosX := PosX + Theme.Song.Equalizer.W + Theme.Song.Equalizer.Space
- else //Vertically
- PosY := PosY + Theme.Song.Equalizer.H + Theme.Song.Equalizer.Space;
- end;
-end;
-end;
-
-Procedure TScreenSong.SelectRandomSong;
-var
- I, I2: Integer;
-begin
- Case PlaylistMan.Mode of
- 0: //All Songs Just Select Random Song
- begin
- //When Tabs are activated then use Tab Method
- if (Ini.Tabs_at_startup = 1) then
- begin
- repeat
- I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1;
- until CatSongs.Song[I2].Main = false;
-
- //Search Cat
- for I := I2 downto low(CatSongs.Song) do
- begin
- if CatSongs.Song[I].Main then
- break;
- end;
- //In I ist jetzt die Kategorie in I2 der Song
- //I is the CatNum, I2 is the No of the Song within this Cat
-
- //Choose Cat
- CatSongs.ShowCategoryList;
-
- //Show Cat in Top Left Mod
- ShowCatTL (I);
-
- CatSongs.ClickCategoryButton(I);
- SelectNext;
-
- //Choose Song
- SkipTo(I2-I);
- end
- //When Tabs are deactivated use easy Method
- else
- SkipTo(Random(CatSongs.VisibleSongs));
- end;
- 1: //One Category Select Category and Select Random Song
- begin
- CatSongs.ShowCategoryList;
- CatSongs.ClickCategoryButton(PlaylistMan.CurPlayList);
- ShowCatTL(PlaylistMan.CurPlayList);
-
- SelectNext;
- FixSelected2;
-
- SkipTo(Random(CatSongs.VisibleSongs));
- end;
- 2: //Playlist: Select Playlist and Select Random Song
- begin
- PlaylistMan.SetPlayList(PlaylistMan.CurPlayList);
-
- SkipTo(Random(CatSongs.VisibleSongs));
- FixSelected2;
- end;
- end;
-
- Music.PlayChange;
- ChangeMusic;
- SetScroll;
- UpdateLCD;
-end;
-
-procedure TScreenSong.SetJoker;
-begin
- //If Party Mode
- if Mode = 1 then //Show Joker that are available
- begin
- if (PartySession.Teams.NumTeams >= 1) then
- begin
- Static[StaticTeam1Joker1].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 1);
- Static[StaticTeam1Joker2].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 2);
- Static[StaticTeam1Joker3].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 3);
- Static[StaticTeam1Joker4].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 4);
- Static[StaticTeam1Joker5].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 5);
- end
- else
- begin
- Static[StaticTeam1Joker1].Visible := False;
- Static[StaticTeam1Joker2].Visible := False;
- Static[StaticTeam1Joker3].Visible := False;
- Static[StaticTeam1Joker4].Visible := False;
- Static[StaticTeam1Joker5].Visible := False;
- end;
-
- if (PartySession.Teams.NumTeams >= 2) then
- begin
- Static[StaticTeam2Joker1].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 1);
- Static[StaticTeam2Joker2].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 2);
- Static[StaticTeam2Joker3].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 3);
- Static[StaticTeam2Joker4].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 4);
- Static[StaticTeam2Joker5].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 5);
- end
- else
- begin
- Static[StaticTeam2Joker1].Visible := False;
- Static[StaticTeam2Joker2].Visible := False;
- Static[StaticTeam2Joker3].Visible := False;
- Static[StaticTeam2Joker4].Visible := False;
- Static[StaticTeam2Joker5].Visible := False;
- end;
-
- if (PartySession.Teams.NumTeams >= 3) then
- begin
- Static[StaticTeam3Joker1].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 1);
- Static[StaticTeam3Joker2].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 2);
- Static[StaticTeam3Joker3].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 3);
- Static[StaticTeam3Joker4].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 4);
- Static[StaticTeam3Joker5].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 5);
- end
- else
- begin
- Static[StaticTeam3Joker1].Visible := False;
- Static[StaticTeam3Joker2].Visible := False;
- Static[StaticTeam3Joker3].Visible := False;
- Static[StaticTeam3Joker4].Visible := False;
- Static[StaticTeam3Joker5].Visible := False;
- end;
- end
- else
- begin //Hide all
- Static[StaticTeam1Joker1].Visible := False;
- Static[StaticTeam1Joker2].Visible := False;
- Static[StaticTeam1Joker3].Visible := False;
- Static[StaticTeam1Joker4].Visible := False;
- Static[StaticTeam1Joker5].Visible := False;
-
- Static[StaticTeam2Joker1].Visible := False;
- Static[StaticTeam2Joker2].Visible := False;
- Static[StaticTeam2Joker3].Visible := False;
- Static[StaticTeam2Joker4].Visible := False;
- Static[StaticTeam2Joker5].Visible := False;
-
- Static[StaticTeam3Joker1].Visible := False;
- Static[StaticTeam3Joker2].Visible := False;
- Static[StaticTeam3Joker3].Visible := False;
- Static[StaticTeam3Joker4].Visible := False;
- Static[StaticTeam3Joker5].Visible := False;
- end;
-end;
-
-procedure TScreenSong.SetStatics;
-var
- I: Integer;
- Visible: Boolean;
-begin
- //Set Visibility of Party Statics and Text
- Visible := (Mode = 1);
-
- For I := 0 to high(StaticParty) do
- Static[StaticParty[I]].Visible := Visible;
-
- For I := 0 to high(TextParty) do
- Text[TextParty[I]].Visible := Visible;
-
- //Set Visibility of Non Party Statics and Text
- Visible := not Visible;
-
- For I := 0 to high(StaticNonParty) do
- Static[StaticNonParty[I]].Visible := Visible;
-
- For I := 0 to high(TextNonParty) do
- Text[TextNonParty[I]].Visible := Visible;
-end;
-
-//Procedures for Menu
-
-procedure TScreenSong.StartSong;
-begin
- CatSongs.Selected := Interaction;
- Music.Stop;
- //Party Mode
- if (Mode = 1) then
- begin
- FadeTo(@ScreenSingModi);
- end
- else
- begin
- FadeTo(@ScreenSing);
- end;
-end;
-
-procedure TScreenSong.SelectPlayers;
-begin
- CatSongs.Selected := Interaction;
- Music.Stop;
-
- ScreenName.Goto_SingScreen := True;
- FadeTo(@ScreenName);
-end;
-
-procedure TScreenSong.OpenEditor;
-begin
- if (Length(Songs.Song) > 0) and (not CatSongs.Song[Interaction].Main) AND (Mode = 0) then begin
- Music.Stop;
- Music.PlayStart;
- ScreenEditSub.Path := CatSongs.Song[Interaction].Path;
- ScreenEditSub.FileName := CatSongs.Song[Interaction].FileName;
- FadeTo(@ScreenEditSub);
- end;
-end;
-
-//Team No of Team (0-5)
-procedure TScreenSong.DoJoker (Team: Byte);
-begin
- if (Mode = 1) AND (PartySession.Teams.NumTeams >= Team + 1) AND (PartySession.Teams.Teaminfo[Team].Joker > 0) then
- begin
- //Joker spielen
- Dec(PartySession.Teams.Teaminfo[Team].Joker);
- SelectRandomSong;
- SetJoker;
- end;
-end;
-
-//Detailed Cover Unloading. Unloads the Detailed, uncached Cover of the cur. Song
-procedure TScreenSong.UnLoadDetailedCover;
-begin
- CoverTime := 0;
-
- Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, 'Plain', true); // 0.5.0: show cached texture
- Button[Interaction].Texture2.Alpha := 0;
-
- if Button[Interaction].Texture.Name <> Skin.GetTextureFileName('SongCover') then
- Texture.UnloadTexture(Button[Interaction].Texture.Name, false);
-end;
-
-procedure TScreenSong.Refresh;
-begin {
-CatSongs.Refresh;
-CatSongs.ShowCategoryList;
-Interaction := 0;
-SelectNext;
-FixSelected; }
-
-end;
-
-end.
+unit UScreenSong;
+
+interface
+{$I switches.inc}
+
+uses
+ UMenu,
+ SDL,
+ UMusic,
+ UFiles,
+ UTime,
+ UDisplay,
+ USongs,
+ SysUtils,
+ ULog,
+ UThemes,
+ UTexture,
+ ULanguage,
+ ULCD,
+ ULight,
+ UIni;
+
+type
+ TScreenSong = class(TMenu)
+ public
+ TextArtist: integer;
+ TextTitle: integer;
+ TextNumber: integer;
+
+ //Video Icon Mod
+ VideoIcon: Cardinal;
+
+ TextCat: integer;
+ StaticCat: integer;
+
+ SongCurrent: real;
+ SongTarget: real;
+
+ HighSpeed: boolean;
+ CoverFull: boolean;
+ CoverTime: real;
+ CoverX: integer;
+ CoverY: integer;
+ CoverW: integer;
+ is_jump: boolean; // Jump to Song Mod
+ is_jump_title:boolean; //Jump to SOng MOd-YTrue if search for Title
+
+ EqualizerBands: array of Byte;
+ EqualizerTime: Cardinal;
+ EqualizerTime2: Byte;
+
+ //Party Mod
+ Mode: Byte; //0 = Standard, 1= Go to PartyMode after Selection + Change to Random Song at Show
+ //party Statics (Joker)
+ StaticTeam1Joker1: Cardinal;
+ StaticTeam1Joker2: Cardinal;
+ StaticTeam1Joker3: Cardinal;
+ StaticTeam1Joker4: Cardinal;
+ StaticTeam1Joker5: Cardinal;
+
+ StaticTeam2Joker1: Cardinal;
+ StaticTeam2Joker2: Cardinal;
+ StaticTeam2Joker3: Cardinal;
+ StaticTeam2Joker4: Cardinal;
+ StaticTeam2Joker5: Cardinal;
+
+ StaticTeam3Joker1: Cardinal;
+ StaticTeam3Joker2: Cardinal;
+ StaticTeam3Joker3: Cardinal;
+ StaticTeam3Joker4: Cardinal;
+ StaticTeam3Joker5: Cardinal;
+
+ StaticParty: Array of Cardinal;
+ TextParty: Array of Cardinal;
+ StaticNonParty: Array of Cardinal;
+ TextNonParty: Array of Cardinal;
+
+
+ constructor Create; override;
+ procedure SetScroll;
+ procedure SetScroll1;
+ procedure SetScroll2;
+ procedure SetScroll3;
+ procedure SetScroll4;
+ procedure SetScroll5;
+ procedure SetScroll6;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+ procedure onShow; override;
+ procedure onHide; override;
+ procedure SelectNext;
+ procedure SelectPrev;
+ procedure UpdateLCD;
+ procedure SkipTo(Target: Cardinal);
+ procedure FixSelected; //Show Wrong Song when Tabs on Fix
+ procedure FixSelected2; //Show Wrong Song when Tabs on Fix
+ procedure ShowCatTL(Cat: Integer);// Show Cat in Top left
+ procedure ShowCatTLCustom(Caption: String);// Show Custom Text in Top left
+ procedure HideCatTL;// Show Cat in Tob left
+ procedure Refresh; //Refresh Song Sorting
+ procedure DrawEqualizer;
+ procedure ChangeMusic;
+ //Party Mode
+ procedure SelectRandomSong;
+ procedure SetJoker;
+ procedure SetStatics;
+ //procedures for Menu
+ procedure StartSong;
+ procedure OpenEditor;
+ procedure DoJoker(Team: Byte);
+ procedure SelectPlayers;
+
+ procedure UnLoadDetailedCover;
+
+ //Extensions
+ procedure DrawExtensions;
+ end;
+
+implementation
+uses UGraphic,
+ UMain,
+ UCovers,
+ math,
+ OpenGL12,
+ {$IFDEF win32}
+ windows,
+ {$ELSE}
+ lclintf,
+ {$ENDIF}
+ USkins,
+ UDLLManager,
+ UParty,
+ UPlaylist,
+ UScreenSongMenu;
+
+// ***** Public methods ****** //
+
+//Show Wrong Song when Tabs on Fix
+procedure TScreenSong.FixSelected;
+var I, I2: Integer;
+ begin
+ if CatSongs.VisibleSongs > 0 then
+ begin
+ I2:= 0;
+ for I := low(CatSongs.Song) to High(Catsongs.Song) do
+ begin
+ if CatSongs.Song[I].Visible then
+ inc(I2);
+
+ if I = Interaction - 1 then
+ break;
+ end;
+
+ SongCurrent := I2;
+ SongTarget := I2;
+ end;
+ end;
+
+procedure TScreenSong.FixSelected2;
+var I, I2: Integer;
+ begin
+ if CatSongs.VisibleSongs > 0 then
+ begin
+ I2:= 0;
+ for I := low(CatSongs.Song) to High(Catsongs.Song) do
+ begin
+ if CatSongs.Song[I].Visible then
+ inc(I2);
+
+ if I = Interaction - 1 then
+ break;
+ end;
+
+ SongTarget := I2;
+ end;
+ end;
+//Show Wrong Song when Tabs on Fix End
+
+ procedure TScreenSong.ShowCatTLCustom(Caption: String);// Show Custom Text in Top left
+ begin
+ Text[TextCat].Text := Caption;
+ Text[TextCat].Visible := true;
+ Static[StaticCat].Visible := False;
+ end;
+
+ //Show Cat in Top Left Mod
+ procedure TScreenSong.ShowCatTL(Cat: Integer);
+ begin
+ //Change
+ Text[TextCat].Text := CatSongs.Song[Cat].Artist;
+ //showmessage(CatSongs.Song[Cat].Path + CatSongs.Song[Cat].Cover);
+ //Static[StaticCat].Texture := Texture.GetTexture(Button[Cat].Texture.Name, 'Plain', true);
+
+ Static[StaticCat].Texture := Texture.GetTexture(Button[Cat].Texture.Name, 'Plain', true);
+ //Texture.GetTexture(Button[Cat].Texture.Name, 'Plain', false);
+ //Button[Cat].
+ //Cover
+
+
+ //Show
+ Text[TextCat].Visible := true;
+ Static[StaticCat].Visible := True;
+ end;
+
+ procedure TScreenSong.HideCatTL;
+ begin
+ //Hide
+ //Text[TextCat].Visible := false;
+ Static[StaticCat].Visible := false;
+ //New -> Show Text specified in Theme
+ Text[TextCat].Visible := True;
+ Text[TextCat].Text := Theme.Song.TextCat.Text;
+ end;
+ //Show Cat in Top Left Mod End
+
+
+// Method for input parsing. If False is returned, GetNextWindow
+// should be checked to know the next window to load;
+function TScreenSong.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+var
+ I: integer;
+ I2: integer;
+ HS: integer;
+ SDL_ModState: Word;
+ Letter: Char;
+begin
+ Result := true;
+
+ //Song Screen Extensions (Jumpto + Menu)
+ if (ScreenSongMenu.Visible) then
+ begin
+ Result := ScreenSongMenu.ParseInput(PressedKey, ScanCode, PressedDown);
+ Exit;
+ end
+ else if (ScreenSongJumpto.Visible) then
+ begin
+ Result := ScreenSongJumpto.ParseInput(PressedKey, ScanCode, PressedDown);
+ Exit;
+ end;
+
+ If (PressedDown) Then
+ begin // Key Down
+
+ SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT);
+
+ //Jump to Artist/Titel
+ if (SDL_ModState and KMOD_LALT <> 0) AND (Mode = 0) AND (PressedKey >= SDLK_A) AND (PressedKey <= SDLK_Z) then
+ begin
+ Letter := UpCase(Chr(ScanCode));
+ I2 := Length(CatSongs.Song);
+
+ //Jump To Titel
+ if (SDL_ModState = KMOD_LALT or KMOD_LSHIFT) then
+ begin
+ For I := 1 to high(CatSongs.Song) do
+ begin
+ if (CatSongs.Song[(I + Interaction) mod I2].Visible) AND (Length(CatSongs.Song[(I + Interaction) mod I2].Title)>0) AND (UpCase(CatSongs.Song[(I + Interaction) mod I2].Title[1]) = Letter) then
+ begin
+ SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2));
+
+ Music.PlayChange;
+
+ ChangeMusic;
+ SetScroll4;
+ UpdateLCD;
+ //Break and Exit
+ Exit;
+ end;
+ end;
+ end
+ //Jump to Artist
+ else if (SDL_ModState = KMOD_LALT) then
+ begin
+ For I := 1 to high(CatSongs.Song) do
+ begin
+ if (CatSongs.Song[(I + Interaction) mod I2].Visible) AND (Length(CatSongs.Song[(I + Interaction) mod I2].Artist)>0) AND (UpCase(CatSongs.Song[(I + Interaction) mod I2].Artist[1]) = Letter) then
+ begin
+ SkipTo(CatSongs.VisibleIndex((I + Interaction) mod I2));
+
+ Music.PlayChange;
+
+ ChangeMusic;
+ SetScroll4;
+ UpdateLCD;
+
+ //Break and Exit
+ Exit;
+ end;
+ end;
+ end;
+ Exit;
+ end;
+
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ if (Mode = 0) then
+ begin
+ //On Escape goto Cat-List Hack
+ if (Ini.Tabs_at_startup = 1) AND (CatSongs.CatNumShow <> -1) then
+ begin
+ //Find Category
+ I := Interaction;
+ while not catsongs.Song[I].Main do
+ begin
+ Dec (I);
+ if (I < low(catsongs.Song)) then
+ break;
+ end;
+ if (I<= 1) then
+ Interaction := high(catsongs.Song)
+ else
+ Interaction := I - 1;
+
+ //Stop Music
+ Music.Stop;
+
+ CatSongs.ShowCategoryList;
+
+ //Show Cat in Top Left Mod
+ HideCatTL;
+
+
+ //Show Wrong Song when Tabs on Fix
+ SelectNext;
+ FixSelected;
+ //SelectPrev;
+ //CatSongs.Song[0].Visible := False;
+ end
+ else
+ begin
+ //On Escape goto Cat-List Hack End
+ //Tabs off and in Search or Playlist -> Go back to Song view
+ if (CatSongs.CatNumShow < -1) then
+ begin
+ //Atm: Set Empty Filter
+ CatSongs.SetFilter('', 0);
+
+ //Show Cat in Top Left Mod
+ HideCatTL;
+ Interaction := 0;
+
+ //Show Wrong Song when Tabs on Fix
+ SelectNext;
+ FixSelected;
+
+ ChangeMusic;
+ end
+ else
+ begin
+ Music.Stop;
+ Music.PlayBack;
+
+ FadeTo(@ScreenMain);
+ end;
+
+ end;
+ end
+ //When in party Mode then Ask before Close
+ else if (Mode = 1) then
+ begin
+ Music.PlayBack;
+ CheckFadeTo(@ScreenMain,'MSG_END_PARTY');
+ end;
+ end;
+ SDLK_RETURN:
+ begin
+ if Length(Songs.Song) > 0 then
+ begin
+ {$IFDEF UseSerialPort}
+ // PortWriteB($378, 0);
+ {$ENDIF}
+ if CatSongs.Song[Interaction].Main then
+ begin // clicked on Category Button
+
+ //Show Cat in Top Left Mod
+ ShowCatTL (Interaction);
+
+ //I := CatSongs.VisibleIndex(Interaction);
+ CatSongs.ClickCategoryButton(Interaction);
+ {I2 := CatSongs.VisibleIndex(Interaction);
+ SongCurrent := SongCurrent - I + I2;
+ SongTarget := SongTarget - I + I2; }
+
+// if I<>I2 then beep;
+ // SetScroll4;
+
+ //Show Wrong Song when Tabs on Fix
+ SelectNext;
+ FixSelected;
+
+ //Play Music:
+ ChangeMusic;
+
+ end else begin // clicked on song
+ if (Mode = 0) then //Normal Mode -> Start Song
+ begin
+ //Do the Action that is specified in Ini
+ case Ini.OnSongClick of
+ 0: StartSong;
+ 1: SelectPlayers;
+ 2:begin
+ If (CatSongs.CatNumShow = -3) then
+ ScreenSongMenu.MenuShow(SM_Playlist)
+ else
+ ScreenSongMenu.MenuShow(SM_Main);
+ end;
+ end;
+ end
+ else if (Mode = 1) then //PartyMode -> Show Menu
+ begin
+ if (Ini.PartyPopup = 1) then
+ ScreenSongMenu.MenuShow(SM_Party_Main)
+ else
+ ScreenSong.StartSong;
+ end;
+ end;
+ end;
+ end;
+
+ SDLK_M: //Show SongMenu
+ begin
+ if (Length(Songs.Song) > 0) then begin
+ if (Mode = 0) then begin
+ if not CatSongs.Song[Interaction].Main then begin // clicked on Song
+ if CatSongs.CatNumShow = -3 then
+ ScreenSongMenu.MenuShow(SM_Playlist)
+ else
+ ScreenSongMenu.MenuShow(SM_Main);
+ end
+ else
+ begin
+ ScreenSongMenu.MenuShow(SM_Playlist_Load);
+ end;
+ end //Party Mode -> Show Party Menu
+ else ScreenSongMenu.MenuShow(SM_Party_Main);
+ end;
+ end;
+
+ SDLK_P: //Show Playlist Menu
+ begin
+ if (Length(Songs.Song) > 0) AND (Mode = 0) then begin
+ ScreenSongMenu.MenuShow(SM_Playlist_Load);
+ end;
+ end;
+
+ SDLK_J: //Show Jumpto Menu
+ begin
+ if (Length(Songs.Song) > 0) AND (Mode = 0) then
+ begin
+ ScreenSongJumpto.Visible := True;
+ end;
+ end;
+
+ SDLK_DOWN:
+ begin
+ if (Mode = 0) then
+ begin
+ //Only Change Cat when not in Playlist or Search Mode
+ if (CatSongs.CatNumShow > -2) then
+ begin
+ //Cat Change Hack
+ if Ini.Tabs_at_startup = 1 then
+ begin
+ I := Interaction;
+ if I <= 0 then I := 1;
+
+ while not catsongs.Song[I].Main do
+ begin
+ Inc (I);
+ if (I > high(catsongs.Song)) then
+ I := low(catsongs.Song);
+ end;
+
+ Interaction := I;
+
+ //Show Cat in Top Left Mod
+ ShowCatTL (Interaction);
+
+ CatSongs.ClickCategoryButton(Interaction);
+ SelectNext;
+ FixSelected;
+
+ //Play Music:
+ Music.PlayChange;
+ ChangeMusic;
+
+ end;
+
+ //
+ //Cat Change Hack End}
+ end;
+ end;
+ end;
+ SDLK_UP:
+ begin
+ if (Mode = 0) then
+ begin
+ //Only Change Cat when not in Playlist or Search Mode
+ if (CatSongs.CatNumShow > -2) then
+ begin
+ //Cat Change Hack
+ if Ini.Tabs_at_startup = 1 then
+ begin
+ I := Interaction;
+ I2 := 0;
+ if I <= 0 then I := 1;
+
+ while not catsongs.Song[I].Main or (I2 = 0) do
+ begin
+ if catsongs.Song[I].Main then
+ Inc(I2);
+ Dec (I);
+ if (I < low(catsongs.Song)) then
+ I := high(catsongs.Song);
+ end;
+
+ Interaction := I;
+
+ //Show Cat in Top Left Mod
+ ShowCatTL (I);
+
+ CatSongs.ClickCategoryButton(I);
+ SelectNext;
+ FixSelected;
+
+ //Play Music:
+ Music.PlayChange;
+ ChangeMusic;
+ end;
+ end;
+ //Cat Change Hack End}
+ end;
+ end;
+
+ SDLK_RIGHT:
+ begin
+ if (Length(Songs.Song) > 0) AND (Mode = 0) then begin
+ Music.PlayChange;
+ SelectNext;
+// InteractNext;
+// SongTarget := Interaction;
+ ChangeMusic;
+ SetScroll4;
+ UpdateLCD;
+ Light.LightOne(1, 200);
+ end;
+ end;
+
+ SDLK_LEFT:
+ begin
+ if (Length(Songs.Song) > 0)AND (Mode = 0) then begin
+ Music.PlayChange;
+ SelectPrev;
+ ChangeMusic;
+ SetScroll4;
+ UpdateLCD;
+ Light.LightOne(0, 200);
+ end;
+ end;
+
+ SDLK_E:
+ begin
+ OpenEditor;
+ end;
+
+ SDLK_R:
+ begin
+ if (Length(Songs.Song) > 0) AND (Mode = 0) then begin
+
+ if (SDL_ModState = KMOD_LSHIFT) AND (Ini.Tabs_at_startup = 1) then //Random Category
+ begin
+ I2 := 0; //Count Cats
+ for I:= low(CatSongs.Song) to high (CatSongs.Song) do
+ if CatSongs.Song[I].Main then Inc(I2);
+
+ I2 := Random (I2)+1; //Zufall
+
+ //Find Cat:
+ for I:= low(CatSongs.Song) to high (CatSongs.Song) do
+ begin
+ if CatSongs.Song[I].Main then
+ Dec(I2);
+ if (I2<=0) then
+ begin
+ //Show Cat in Top Left Mod
+ ShowCatTL (I);
+
+ Interaction := I;
+
+ CatSongs.ShowCategoryList;
+ CatSongs.ClickCategoryButton(I);
+ SelectNext;
+ FixSelected;
+ break;
+ end;
+ end;
+
+
+ end
+ else if (SDL_ModState = KMOD_LCTRL) AND (Ini.Tabs_at_startup = 1) then //random in All Categorys
+ begin
+ repeat
+ I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1;
+ until CatSongs.Song[I2].Main = false;
+
+ //Search Cat
+ for I := I2 downto low(CatSongs.Song) do
+ begin
+ if CatSongs.Song[I].Main then
+ break;
+ end;
+ //In I ist jetzt die Kategorie in I2 der Song
+
+ //Choose Cat
+ CatSongs.ShowCategoryList;
+
+ //Show Cat in Top Left Mod
+ ShowCatTL (I);
+
+ CatSongs.ClickCategoryButton(I);
+ SelectNext;
+
+ //Fix: Not Existing Song selected:
+ //if (I+1=I2) then Inc(I2);
+
+ //Choose Song
+ SkipTo(I2-I);
+
+ end
+ else //Random in one Category
+ begin
+ SkipTo(Random(CatSongs.VisibleSongs));
+ end;
+ Music.PlayChange;
+
+ ChangeMusic;
+ SetScroll4;
+ UpdateLCD;
+ end;
+ end;
+
+ SDLK_1:
+ begin //Jocker
+ if (Mode = 1) AND (PartySession.Teams.NumTeams >= 1) AND (PartySession.Teams.Teaminfo[0].Joker > 0) then
+ begin
+ //Joker spielen
+ Dec(PartySession.Teams.Teaminfo[0].Joker);
+ SelectRandomSong;
+ SetJoker;
+ end;
+ end;
+
+ SDLK_2:
+ begin //Jocker
+ if (Mode = 1) AND (PartySession.Teams.NumTeams >= 2) AND (PartySession.Teams.Teaminfo[1].Joker > 0) then
+ begin
+ //Joker spielen
+ Dec(PartySession.Teams.Teaminfo[1].Joker);
+ SelectRandomSong;
+ SetJoker;
+ end;
+ end;
+
+ SDLK_3:
+ begin //Jocker
+ if (Mode = 1) AND (PartySession.Teams.NumTeams >= 3) AND (PartySession.Teams.Teaminfo[2].Joker > 0) then
+ begin
+ //Joker spielen
+ Dec(PartySession.Teams.Teaminfo[2].Joker);
+ SelectRandomSong;
+ SetJoker;
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenSong.Create;
+var
+ Pet: integer;
+ I: integer;
+Label CreateSongButtons;
+begin
+ inherited Create;
+
+ LoadFromTheme(Theme.Song);
+
+ TextArtist := AddText(Theme.Song.TextArtist);
+ TextTitle := AddText(Theme.Song.TextTitle);
+ TextNumber := AddText(Theme.Song.TextNumber);
+
+ //Show Cat in Top Left mod
+ TextCat := AddText(Theme.Song.TextCat);
+ StaticCat := AddStatic(Theme.Song.StaticCat);
+
+ //Show Video Icon Mod
+ VideoIcon := AddStatic(Theme.Song.VideoIcon);
+
+ //Party Mode
+ StaticTeam1Joker1 := AddStatic(Theme.Song.StaticTeam1Joker1);
+ StaticTeam1Joker2 := AddStatic(Theme.Song.StaticTeam1Joker2);
+ StaticTeam1Joker3 := AddStatic(Theme.Song.StaticTeam1Joker3);
+ StaticTeam1Joker4 := AddStatic(Theme.Song.StaticTeam1Joker4);
+ StaticTeam1Joker5 := AddStatic(Theme.Song.StaticTeam1Joker5);
+
+ StaticTeam2Joker1 := AddStatic(Theme.Song.StaticTeam2Joker1);
+ StaticTeam2Joker2 := AddStatic(Theme.Song.StaticTeam2Joker2);
+ StaticTeam2Joker3 := AddStatic(Theme.Song.StaticTeam2Joker3);
+ StaticTeam2Joker4 := AddStatic(Theme.Song.StaticTeam2Joker4);
+ StaticTeam2Joker5 := AddStatic(Theme.Song.StaticTeam2Joker5);
+
+ StaticTeam3Joker1 := AddStatic(Theme.Song.StaticTeam3Joker1);
+ StaticTeam3Joker2 := AddStatic(Theme.Song.StaticTeam3Joker2);
+ StaticTeam3Joker3 := AddStatic(Theme.Song.StaticTeam3Joker3);
+ StaticTeam3Joker4 := AddStatic(Theme.Song.StaticTeam3Joker4);
+ StaticTeam3Joker5 := AddStatic(Theme.Song.StaticTeam3Joker5);
+
+ //Load Party or NonParty specific Statics and Texts
+ SetLength(StaticParty, Length(Theme.Song.StaticParty));
+ for I := 0 to High(Theme.Song.StaticParty) do
+ StaticParty[I] := AddStatic(Theme.Song.StaticParty[I]);
+
+ SetLength(TextParty, Length(Theme.Song.TextParty));
+ for I := 0 to High(Theme.Song.TextParty) do
+ TextParty[I] := AddText(Theme.Song.TextParty[I]);
+
+ SetLength(StaticNonParty, Length(Theme.Song.StaticNonParty));
+ for I := 0 to High(Theme.Song.StaticNonParty) do
+ StaticNonParty[I] := AddStatic(Theme.Song.StaticNonParty[I]);
+
+ SetLength(TextNonParty, Length(Theme.Song.TextNonParty));
+ for I := 0 to High(Theme.Song.TextNonParty) do
+ TextNonParty[I] := AddText(Theme.Song.TextNonParty[I]);
+
+ // Song List
+// Songs.LoadSongList; // moved to the UltraStar unit
+ CatSongs.Refresh;
+
+ if (length(CatSongs.Song) > 0) then
+ begin
+ //Set Length of Button Array one Time Instead of one time for every Song
+ SetButtonLength(Length(CatSongs.Song));
+
+ I := 0;
+ CreateSongButtons:
+
+ try
+ for Pet := I to High(CatSongs.Song) do begin // creating all buttons
+ // new
+ Texture.Limit := 512;// 256 0.4.2 value, 512 in 0.5.0
+
+ if not FileExists(CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover) then
+ CatSongs.Song[Pet].Cover := ''; // 0.5.0: if cover not found then show 'no cover'
+
+ if CatSongs.Song[Pet].Cover = '' then
+ AddButton(300 + Pet*250, 140, 200, 200, Skin.GetTextureFileName('SongCover'), 'JPG', 'Plain', Theme.Song.Cover.Reflections)
+ else begin
+ // cache texture if there is a need to this
+ if not Covers.CoverExists(CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover) then begin
+ Texture.CreateCacheMipmap := true;
+ Texture.GetTexture(CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover, 'Plain', true); // preloads textures and creates cache mipmap
+ Texture.CreateCacheMipmap := false;
+
+ // puts this texture to the cache file
+ Covers.AddCover(CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover);
+
+ // unload full size texture
+ Texture.UnloadTexture(CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover, false);
+
+ // we should also add mipmap texture by calling createtexture and use mipmap cache as data source
+ end;
+
+ // and now load it from cache file (small place for the optimization by eliminating reading it from file, but not here)
+ AddButton(300 + Pet*250, 140, 200, 200, CatSongs.Song[Pet].Path + CatSongs.Song[Pet].Cover, 'JPG', 'Plain', Theme.Song.Cover.Reflections);
+ end;
+ Texture.Limit := 1024*1024;
+ I := -1;
+ end;
+ except
+ //When Error is reported the First time for this Song
+ if (I <> Pet) then
+ begin
+ //Some Error reporting:
+ Log.LogError('Could not load Cover: ' + CatSongs.Song[Pet].Cover);
+
+ //Change Cover to NoCover and Continue Loading
+ CatSongs.Song[Pet].Cover := '';
+ I := Pet;
+ end
+ else //when Error occurs Multiple Times(NoSong Cover is damaged), then start loading next Song
+ begin
+ Log.LogError('NoCover Cover is damaged!');
+ try
+ AddButton(300 + Pet*250, 140, 200, 200, '', 'JPG', 'Plain', Theme.Song.Cover.Reflections);
+ except
+ {$IFDEF win32}
+ Messagebox(0, PChar('No Cover Image is damage. Could not Workaround Song Loading, Ultrastar will exit now.'), PChar(Language.Translate('US_VERSION')), MB_ICONERROR or MB_OK);
+ {$ELSE}
+ // TODO : JB_linux - better handle this message and display to user..
+ writeln( 'No Cover Image is damage. Could not Workaround Song Loading, Ultrastar will exit now.');
+ Log.LogError( 'No Cover Image is damage. Could not Workaround Song Loading, Ultrastar will exit now.' );
+ {$ENDIF}
+ Halt;
+ end;
+ I := Pet + 1;
+ end;
+ end;
+
+ if (I <> -1) then
+ GoTo CreateSongButtons;
+
+ end;
+
+ // Randomize Patch
+ Randomize;
+ //Equalizer
+ SetLength(EqualizerBands, Theme.Song.Equalizer.Bands);
+ //ClearArray
+ For I := low(EqualizerBands) to high(EqualizerBands) do
+ EqualizerBands[I] := 3;
+
+ if (Length(CatSongs.Song) > 0) then
+ Interaction := 0;
+end;
+
+procedure TScreenSong.SetScroll;
+var
+ VS, B: Integer;
+begin
+ VS := CatSongs.VisibleSongs;
+ if VS > 0 then
+ begin
+ //Set Positions
+ Case Theme.Song.Cover.Style of
+ 3: SetScroll3;
+ 5:begin
+ if VS > 5 then
+ SetScroll5
+ else
+ SetScroll4;
+ end;
+ 6: SetScroll6;
+ else SetScroll4;
+ end;
+ //Set Visibility of Video Icon
+ Static[VideoIcon].Visible := (CatSongs.Song[Interaction].Video <> '');
+
+ //Set Texts:
+ Text[TextArtist].Text := CatSongs.Song[Interaction].Artist;
+ Text[TextTitle].Text := CatSongs.Song[Interaction].Title;
+ if (Ini.Tabs_at_startup = 1) And (CatSongs.CatNumShow = -1) then
+ begin
+ Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].OrderNum) + '/' + IntToStr(CatSongs.CatCount);
+ Text[TextTitle].Text := '(' + IntToStr(CatSongs.Song[Interaction].CatNumber) + ' ' + Language.Translate('SING_SONGS_IN_CAT') + ')';
+ end
+ else if (CatSongs.CatNumShow = -2) then
+ Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS)
+ else if (CatSongs.CatNumShow = -3) then
+ Text[TextNumber].Text := IntToStr(CatSongs.VisibleIndex(Interaction)+1) + '/' + IntToStr(VS)
+ else if (Ini.Tabs_at_startup = 1) then
+ Text[TextNumber].Text := IntToStr(CatSongs.Song[Interaction].CatNumber) + '/' + IntToStr(CatSongs.Song[Interaction - CatSongs.Song[Interaction].CatNumber].CatNumber)
+ else
+ Text[TextNumber].Text := IntToStr(Interaction+1) + '/' + IntToStr(Length(CatSongs.Song));
+ end
+ else
+ begin
+ Text[TextNumber].Text := '0/0';
+ Text[TextArtist].Text := '';
+ Text[TextTitle].Text := '';
+ for B := 0 to High(Button) do
+ Button[B].Visible := False;
+
+ end;
+end;
+
+procedure TScreenSong.SetScroll1;
+var
+ B: integer; // button
+ BMin: integer; // button min
+ BMax: integer; // button max
+ Src: integer;
+// Dst: integer;
+ Count: integer; // Dst is not used. Count is used.
+ Ready: boolean;
+
+ VisCount: integer; // count of visible (or selectable) buttons
+ VisInt: integer; // visible position of interacted button
+ Typ: integer; // 0 when all songs fits the screen
+ Placed: integer; // number of placed visible buttons
+begin
+// Src := 0;
+// Dst := -1;
+ Count := 1;
+ Typ := 0;
+ Ready := false;
+ Placed := 0;
+
+ VisCount := 0;
+ for B := 0 to High(Button) do
+ if CatSongs.Song[B].Visible then Inc(VisCount);
+
+ VisInt := 0;
+ for B := 0 to Interaction-1 do
+ if CatSongs.Song[B].Visible then Inc(VisInt);
+
+
+ if VisCount <= 6 then begin
+ Typ := 0;
+ end else begin
+ if VisInt <= 3 then begin
+ Typ := 1;
+ Count := 7;
+ Ready := true;
+ end;
+
+ if (VisCount - VisInt) <= 3 then begin
+ Typ := 2;
+ Count := 7;
+ Ready := true;
+ end;
+
+ if not Ready then begin
+ Typ := 3;
+ Src := Interaction;
+ end;
+ end;
+
+
+
+ // hide all buttons
+ for B := 0 to High(Button) do begin
+ Button[B].Visible := false;
+ Button[B].Selectable := CatSongs.Song[B].Visible;
+ end;
+
+{ for B := Src to Dst do begin
+// Button[B].Visible := true;
+ Button[B].Visible := CatSongs.Song[B].Visible;
+ Button[B].Selectable := Button[B].Visible;
+ Button[B].Y := 140 + (B-Src) * 60;
+ end;}
+
+
+ if Typ = 0 then begin
+ for B := 0 to High(Button) do begin
+ if CatSongs.Song[B].Visible then begin
+ Button[B].Visible := true;
+ Button[B].Y := 140 + (Placed) * 60;
+ Inc(Placed);
+ end;
+ end;
+ end;
+
+ if Typ = 1 then begin
+ B := 0;
+ while (Count > 0) do begin
+ if CatSongs.Song[B].Visible then begin
+ Button[B].Visible := true;
+ Button[B].Y := 140 + (Placed) * 60;
+ Inc(Placed);
+ Dec(Count);
+ end;
+ Inc(B);
+ end;
+ end;
+
+ if Typ = 2 then begin
+ B := High(Button);
+ while (Count > 0) do begin
+ if CatSongs.Song[B].Visible then begin
+ Button[B].Visible := true;
+ Button[B].Y := 140 + (6-Placed) * 60;
+ Inc(Placed);
+ Dec(Count);
+ end;
+ Dec(B);
+ end;
+ end;
+
+ if Typ = 3 then begin
+ B := Src;
+ Count := 4;
+ while (Count > 0) do begin
+ if CatSongs.Song[B].Visible then begin
+ Button[B].Visible := true;
+ Button[B].Y := 140 + (3+Placed) * 60;
+ Inc(Placed);
+ Dec(Count);
+ end;
+ Inc(B);
+ end;
+
+ B := Src-1;
+ Placed := 0;
+ Count := 3;
+ while (Count > 0) do begin
+ if CatSongs.Song[B].Visible then begin
+ Button[B].Visible := true;
+ Button[B].Y := 140 + (2-Placed) * 60;
+ Inc(Placed);
+ Dec(Count);
+ end;
+ Dec(B);
+ end;
+
+ end;
+
+ if Length(Button) > 0 then
+ Static[1].Texture.Y := Button[Interaction].Y - 5; // selection texture
+end;
+
+procedure TScreenSong.SetScroll2;
+var
+ B: integer;
+ Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu
+ Wsp2: real;
+begin
+ // liniowe
+ for B := 0 to High(Button) do
+ Button[B].X := 300 + (B - Interaction) * 260;
+
+ if Length(Button) >= 3 then begin
+ if Interaction = 0 then
+ Button[High(Button)].X := 300 - 260;
+
+ if Interaction = High(Button) then
+ Button[0].X := 300 + 260;
+ end;
+
+ // kolowe
+{ for B := 0 to High(Button) do begin
+ Wsp := (B - Interaction); // 0 dla srodka, -1 dla lewego, +1 dla prawego itd.
+ Wsp2 := Wsp / Length(Button);
+ Button[B].X := 300 + 10000 * sin(2*pi*Wsp2);
+// Button[B].Y := 140 + 50 * ;
+ end;}
+end;
+
+procedure TScreenSong.SetScroll3; // with slide
+var
+ B: integer;
+ Wsp: integer; // wspolczynnik przesuniecia wzgledem srodka ekranu
+ Wsp2: real;
+begin
+ SongTarget := Interaction;
+
+ // liniowe
+ for B := 0 to High(Button) do
+ begin
+ Button[B].X := 300 + (B - SongCurrent) * 260;
+ if (Button[B].X < -Button[B].W) OR (Button[B].X > 800) then
+ Button[B].Visible := False
+ else
+ Button[B].Visible := True;
+ end;
+
+{ if Length(Button) >= 3 then begin
+ if Interaction = 0 then
+ Button[High(Button)].X := 300 - 260;
+
+ if Interaction = High(Button) then
+ Button[0].X := 300 + 260;
+ end;}
+
+ // kolowe
+{ for B := 0 to High(Button) do begin
+ Wsp := (B - Interaction); // 0 dla srodka, -1 dla lewego, +1 dla prawego itd.
+ Wsp2 := Wsp / Length(Button);
+ Button[B].X := 300 + 10000 * sin(2*pi*Wsp2);
+// Button[B].Y := 140 + 50 * ;
+ end;}
+end;
+
+procedure TScreenSong.SetScroll4; // rotate
+var
+ B: integer;
+ Wsp: real;
+ Z, Z2: real;
+ VS: integer;
+begin
+ VS := CatSongs.VisibleSongs; // 0.5.0 (I): cached, very important
+
+ // kolowe
+ for B := 0 to High(Button) do begin
+ Button[B].Visible := CatSongs.Song[B].Visible; // nowe
+ if Button[B].Visible then begin // 0.5.0 optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed
+
+ Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / VS {CatSongs.VisibleSongs};// 0.5.0 (II): takes another 16ms
+
+ Z := (1 + cos(Wsp)) / 2;
+ Z2 := (1 + 2*Z) / 3;
+
+
+ Button[B].X := Theme.Song.Cover.X + (0.185 * Theme.Song.Cover.H * VS * sin(Wsp)) * Z2 - ((Button[B].H - Theme.Song.Cover.H)/2); // 0.5.0 (I): 2 times faster by not calling CatSongs.VisibleSongs
+ Button[B].Z := Z / 2 + 0.3;
+
+ Button[B].W := Theme.Song.Cover.H * Z2;
+
+// Button[B].Y := {50 +} 140 + 50 - 50 * Z2;
+ Button[B].Y := Theme.Song.Cover.Y + (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7 ;
+ Button[B].H := Button[B].W;
+ end;
+ end;
+end;
+
+(*
+procedure TScreenSong.SetScroll4; // rotate
+var
+ B: integer;
+ Wsp: real;
+ Z: real;
+ Z2, Z3: real;
+ VS: integer;
+ function modreal (const X, Y: real):real;
+ begin
+ Result := Frac(x / y) * y;
+ if Result < -3 then
+ Result := Result + Y
+ else if Result > 3 then
+ Result := Result - Y;
+ end;
+begin
+ VS := CatSongs.VisibleSongs; // 0.5.0 (I): cached, very important
+ Z3 := 1;
+ if VS < 12 then
+ Z2 := VS
+ else
+ Z2 := 12;
+
+ // kolowe
+ for B := 0 to High(Button) do begin
+ Button[B].Visible := CatSongs.Song[B].Visible; // nowe
+ if Button[B].Visible then begin // 0.5.0 optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed
+ if ((ModReal(CatSongs.VisibleIndex(B) - SongCurrent, VS)>-3) AND (ModReal(CatSongs.VisibleIndex(B) - SongCurrent, VS)<3)) then
+ begin
+ if CatSongs.VisibleIndex(B)> SongCurrent then
+ Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / Z2
+ else
+ Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / Z2;
+
+ Z3 := 2;
+ Z := (1 + cos(Wsp)) / 2;
+ //Z2 := (1 + 2*Z) / 3;
+ //Z2 := (0.5 + Z/2);
+ //Z2 := sin(Wsp);
+
+ //Z2 := Power (Z2,Z3);
+
+ Button[B].W := Theme.Song.CoverW * Power(cos(Wsp), Z3);//Power(Z2, 3);
+
+ //Button[B].X := Theme.Song.CoverX + ({Theme.Song.CoverX + Theme.Song.CoverW/2 + Theme.Song.CoverW*0.18 * VS {CatSongs.VisibleSongs {Length(Button) * sin(Wsp) {- Theme.Song.CoverX - Theme.Song.CoverW) * Z2; // 0.5.0 (I): 2 times faster by not calling CatSongs.VisibleSongs
+ if (sin(Wsp)<0) then
+ Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX + Theme.Song.CoverW - Button[B].W
+ else //*Theme.Song.CoverW*0.004*Z3
+ Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX;
+ Button[B].Z := Z-0.00001;
+
+// Button[B].Y := {50 + 140 + 50 - 50 * Z2;
+ // Button[B].Y := (Theme.Song.CoverY + 40 + 50 - 50 * Z2);
+ Button[B].Y := (Theme.Song.CoverY + Theme.Song.CoverW - Button[B].W);
+ Button[B].H := Button[B].W;
+ Button[B].Visible := True;
+ end
+ {else if (((CatSongs.VisibleIndex(B) - SongCurrent)>-3) AND ((CatSongs.VisibleIndex(B) - SongCurrent)<3)) OR ((round (CatSongs.VisibleIndex(B) - SongCurrent) mod VS > -3) AND ((CatSongs.VisibleIndex(B) - SongCurrent)<3)) then
+ begin
+ Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / 12 ;// 0.5.0 (II): takes another 16ms
+
+ Z := (1 + cos(Wsp)) / 2 -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
+
+ Button[B].W := Theme.Song.CoverW * Power(cos(Wsp), Z3);//Power(Z2, 3);
+
+ if (sin(Wsp)<0) then
+ Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX + Theme.Song.CoverW - Button[B].W
+ else
+ Button[B].X := sin(Wsp)*Theme.Song.CoverX*Theme.Song.CoverW*0.007 + Theme.Song.CoverX;
+
+ Button[B].Z := Z;
+
+ Button[B].Y := (Theme.Song.CoverY + Theme.Song.CoverW - Button[B].W);
+
+ Button[B].H := Button[B].W;
+ Button[B].Visible := True;
+ end
+ else Button[B].Visible := False;
+ end;
+ end;
+end; *)
+
+procedure TScreenSong.SetScroll5; // rotate
+var
+ B: integer;
+ Angle: real;
+ Pos: Real;
+ VS: integer;
+ diff: real;
+ X: Real;
+ helper: real;
+begin
+ VS := CatSongs.VisibleSongs; // cache Visible Songs
+ {Vars
+ Theme.Song.CoverW: Radius des Kreises
+ Theme.Song.CoverX: X Pos Linke Kante des gewählten Covers
+ Theme.Song.CoverX: Y Pos Obere Kante des gewählten Covers
+ Theme.Song.CoverH: Höhe der Cover
+
+ (CatSongs.VisibleIndex(B) - SongCurrent)/VS = Abstand zum MIttleren Cover in %
+ }
+
+ //Change Pos of all Buttons
+ for B := low(Button) to high(Button) do
+ begin
+ Button[B].Visible := CatSongs.Song[B].Visible; //Adjust Visibility
+ if Button[B].Visible then //Only Change Pos for Visible Buttons
+ begin
+ Pos := (CatSongs.VisibleIndex(B) - SongCurrent);
+ if (Pos < -VS/2) then
+ Pos := Pos + VS
+ else if (Pos > VS/2) then
+ Pos := Pos - VS;
+
+ if (Abs(Pos) < 2.5) then {fixed Positions}
+ begin
+ Angle := Pi * (Pos / 5);
+// Button[B].Visible := False;
+
+ Button[B].H := Abs(Theme.Song.Cover.H * cos(Angle*0.8));//Power(Z2, 3);
+
+// Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+ Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+
+ Button[B].Z := 0.95 - Abs(Pos) * 0.01;
+
+ Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Abs(Theme.Song.Cover.H * cos(Angle))) * 0.5);
+
+ Button[B].W := Button[B].H;
+
+ Diff := (Button[B].H - Theme.Song.Cover.H)/2;
+
+
+ X := Sin(Angle*1.3)*0.9;
+
+ Button[B].X := Theme.Song.Cover.X + Theme.Song.Cover.W * X - Diff;
+
+ end
+ else
+ begin {Behind the Front Covers}
+
+ // limit-bg-covers hack
+ if (abs(abs(Pos)-VS/2)>10) then Button[B].Visible:=False;
+ // end of limit-bg-covers hack
+
+ if Pos < 0 then
+ Pos := (Pos - VS/2)/VS
+ else
+ Pos := (Pos + VS/2)/VS;
+
+ Angle := pi * Pos*2;
+ if VS > 24 then
+ begin
+ if Angle < 0 then helper:=-1 else helper:=1;
+ Angle:=2*pi-abs(Angle);
+ Angle:=Angle*(VS/24);
+ Angle:=(2*pi-Angle)*helper;
+ end;
+
+ Button[B].Z := (0.4 - Abs(Pos/4)) -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
+
+ Button[B].H :=0.6*(Theme.Song.Cover.H-Abs(Theme.Song.Cover.H * cos(Angle/2)*0.8));//Power(Z2, 3);
+
+ Button[B].W := Button[B].H;
+
+ Button[B].Y := Theme.Song.Cover.Y - (Button[B].H - Theme.Song.Cover.H)*0.75;
+
+// Button[B].Reflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+ Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+
+ Diff := (Button[B].H - Theme.Song.Cover.H)/2;
+
+ Button[B].X := Theme.Song.Cover.X+Theme.Song.Cover.H/2-Button[b].H/2+Theme.Song.Cover.W/320*((Theme.Song.Cover.H)*sin(Angle/2)*1.52);
+
+ end;
+
+ //Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Button[B].H)/1.5); //Cover at down border of the change field
+// Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Button[B].H) * 0.7);
+
+ end;
+ end;
+end;
+
+procedure TScreenSong.SetScroll6; // rotate (slotmachine style)
+var
+ B: integer;
+ Angle: real;
+ Pos: Real;
+ VS: integer;
+ diff: real;
+ X: Real;
+ Wsp: real;
+ Z, Z2: real;
+begin
+ VS := CatSongs.VisibleSongs; // cache Visible Songs
+ if VS <=5 then begin
+ // kolowe
+ for B := 0 to High(Button) do
+ begin
+ Button[B].Visible := CatSongs.Song[B].Visible; // nowe
+ if Button[B].Visible then begin // 0.5.0 optimization for 1000 songs - updates only visible songs, hiding in tabs becomes useful for maintaing good speed
+
+ Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - SongCurrent) / VS {CatSongs.VisibleSongs};// 0.5.0 (II): takes another 16ms
+
+ Z := (1 + cos(Wsp)) / 2;
+ Z2 := (1 + 2*Z) / 3;
+
+
+ Button[B].Y := Theme.Song.Cover.Y + (0.185 * Theme.Song.Cover.H * VS * sin(Wsp)) * Z2 - ((Button[B].H - Theme.Song.Cover.H)/2); // 0.5.0 (I): 2 times faster by not calling CatSongs.VisibleSongs
+ Button[B].Z := Z / 2 + 0.3;
+
+ Button[B].W := Theme.Song.Cover.H * Z2;
+
+// Button[B].Y := {50 +} 140 + 50 - 50 * Z2;
+ Button[B].X := Theme.Song.Cover.X + (Theme.Song.Cover.H - Abs(Button[B].H)) * 0.7 ;
+ Button[B].H := Button[B].W;
+ end;
+ end;
+ end
+ else begin
+
+ //Change Pos of all Buttons
+ for B := low(Button) to high(Button) do
+ begin
+ Button[B].Visible := CatSongs.Song[B].Visible; //Adjust Visibility
+ if Button[B].Visible then //Only Change Pos for Visible Buttons
+ begin
+ Pos := (CatSongs.VisibleIndex(B) - SongCurrent);
+ if (Pos < -VS/2) then
+ Pos := Pos + VS
+ else if (Pos > VS/2) then
+ Pos := Pos - VS;
+
+ if (Abs(Pos) < 2.5) then {fixed Positions}
+ begin
+ Angle := Pi * (Pos / 5);
+// Button[B].Visible := False;
+
+ Button[B].H := Abs(Theme.Song.Cover.H * cos(Angle*0.8));//Power(Z2, 3);
+
+ Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+
+ Button[B].Z := 0.95 - Abs(Pos) * 0.01;
+
+ Button[B].X := (Theme.Song.Cover.X + (Theme.Song.Cover.H - Abs(Theme.Song.Cover.H * cos(Angle))) * 0.5);
+
+ Button[B].W := Button[B].H;
+
+ Diff := (Button[B].H - Theme.Song.Cover.H)/2;
+
+
+ X := Sin(Angle*1.3)*0.9;
+
+ Button[B].Y := Theme.Song.Cover.Y + Theme.Song.Cover.W * X - Diff;
+ end
+ else
+ begin {Behind the Front Covers}
+
+ // limit-bg-covers hack
+ if (abs(VS/2-abs(Pos))>10) then Button[B].Visible:=False;
+ if VS > 25 then VS:=25;
+ // end of limit-bg-covers hack
+
+ if Pos < 0 then
+ Pos := (Pos - VS/2)/VS
+ else
+ Pos := (Pos + VS/2)/VS;
+
+ Angle := pi * Pos*2;
+
+ Button[B].Z := (0.4 - Abs(Pos/4)) -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
+
+ Button[B].H :=0.6*(Theme.Song.Cover.H-Abs(Theme.Song.Cover.H * cos(Angle/2)*0.8));//Power(Z2, 3);
+
+ Button[B].W := Button[B].H;
+
+ Button[B].X := Theme.Song.Cover.X - (Button[B].H - Theme.Song.Cover.H)*0.5;
+
+
+ Button[B].DeSelectReflectionspacing := 15 * Button[B].H/Theme.Song.Cover.H;
+
+ Button[B].Y := Theme.Song.Cover.Y+Theme.Song.Cover.H/2-Button[b].H/2+Theme.Song.Cover.W/320*(Theme.Song.Cover.H*sin(Angle/2)*1.52);
+ end;
+ end;
+ end;
+ end;
+end;
+
+
+procedure TScreenSong.onShow;
+begin
+ Music.Stop;
+
+ if Ini.Players <= 3 then PlayersPlay := Ini.Players + 1;
+ if Ini.Players = 4 then PlayersPlay := 6;
+
+ //Cat Mod etc
+ if (Ini.Tabs_at_startup = 1) AND (CatSongs.CatNumShow = -1) then
+ begin
+ CatSongs.ShowCategoryList;
+ FixSelected;
+ //Show Cat in Top Left Mod
+ HideCatTL;
+ end;
+
+
+ if Length(CatSongs.Song) > 0 then begin
+ //Load Music only when Song Preview is activated
+ if (Ini.PreviewVolume <> 0) then
+ begin
+ Music.SetLoop(false);
+ Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3);
+ Music.MoveTo(Music.Length / 4);
+ Music.Play;
+
+ //Set Preview Volume
+ Music.SetMusicVolume (Ini.PreviewVolume * 10);
+ {//if Music Fade is activated, Set Volume to 0 %
+ if (Ini.PreviewFading <> 0) then
+ Music.SetMusicVolume(0);}
+ end;
+
+ SetScroll;
+ UpdateLCD;
+ end;
+
+ //Playlist Mode
+ if (Mode = 0) then
+ begin
+ //If Playlist Shown -> Select Next automatically
+ if (CatSongs.CatNumShow = -3) then
+ begin
+ SelectNext;
+ ChangeMusic;
+ end;
+ end
+ //Party Mode
+ else if (Mode = 1) then
+ begin
+
+ SelectRandomSong;
+ //Show Menu directly in PartyMode
+ //But only if selected in Options
+ if (Ini.PartyPopup = 1) then
+ begin
+ ScreenSongMenu.MenuShow(SM_Party_Main);
+ end;
+
+
+ end;
+
+ SetJoker;
+ SetStatics;
+end;
+
+procedure TScreenSong.onHide;
+begin
+ //When Music Fading is activated, Turn Music to 100 %
+ If (Ini.PreviewVolume <> 100) or (Ini.PreviewFading <> 0) then
+ Music.SetMusicVolume(100);
+
+ //If Preview is deactivated: Load MUsicfile now
+ If (Ini.PreviewVolume = 0) then
+ Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3);
+
+ //When hide then Stop Music (For Party Mode Popup on Exit)
+ if (Display.NextScreen <> @ScreenSing) and (Display.NextScreen <> @ScreenSingModi) and (Music <> nil) then
+ Music.Stop;
+end;
+
+procedure TScreenSong.DrawExtensions;
+begin
+ //Draw Song Menu
+ if (ScreenSongMenu.Visible) then
+ begin
+ ScreenSongMenu.Draw;
+ end
+ else if (ScreenSongJumpto.Visible) then
+ begin
+ ScreenSongJumpto.Draw;
+ end
+end;
+
+function TScreenSong.Draw: boolean;
+var
+ dx: real;
+ dt: real;
+ I: Integer;
+begin
+ dx := SongTarget-SongCurrent;
+ dt := TimeSkip*7;
+ if dt > 1 then dt := 1;
+ SongCurrent := SongCurrent + dx*dt;
+
+{ if SongCurrent > Catsongs.VisibleSongs then begin
+ SongCurrent := SongCurrent - Catsongs.VisibleSongs;
+ SongTarget := SongTarget - Catsongs.VisibleSongs;
+ end;}
+
+// Log.BenchmarkStart(5);
+ SetScroll;
+// Log.BenchmarkEnd(5);
+// Log.LogBenchmark('SetScroll4', 5);
+
+ //Fading Functions, Only if Covertime is under 5 Seconds
+ If (CoverTime < 5) then
+ begin
+ // 0.5.0: cover fade
+ if (CoverTime < 1) and (CoverTime + TimeSkip >= 1) then begin
+ // load new texture
+ Texture.GetTexture(Button[Interaction].Texture.Name, 'Plain', false);
+ Button[Interaction].Texture.Alpha := 1;
+ Button[Interaction].Texture2 := Texture.GetTexture(Button[Interaction].Texture.Name, 'Plain', false);
+ Button[Interaction].Texture2.Alpha := 1;
+ end;
+
+ //Song Fade
+ if (CatSongs.VisibleSongs > 0) AND (Ini.PreviewVolume <> 0) AND (Not CatSongs.Song[Interaction].Main) AND (Ini.PreviewFading <> 0) then
+ begin
+ //Start Song Fade after a little Time, to prevent Song to be Played on Scrolling
+ if (CoverTime < 0.2) and (CoverTime + TimeSkip >= 0.2) then
+ Music.Play;
+
+ //Update Song Volume
+ if (CoverTime < Ini.PreviewFading) then
+ Music.SetMusicVolume(Round (CoverTime * Ini.PreviewVolume / Ini.PreviewFading * 10))
+ else
+ Music.SetMusicVolume(Ini.PreviewVolume * 10);
+
+ end;
+
+
+ //Update Fading Time
+ CoverTime := CoverTime + TimeSkip;
+
+ //Update Fading Texture
+ Button[Interaction].Texture2.Alpha := (CoverTime - 1) * 1.5;
+ if Button[Interaction].Texture2.Alpha > 1 then Button[Interaction].Texture2.Alpha := 1;
+
+ end;
+
+ //inherited Draw;
+ //heres a little Hack, that causes the Statics
+ //are Drawn after the Buttons because of some Blending Problems.
+ //This should cause no Problems because all Buttons on this screen
+ //Has Z Position.
+ //Draw BG
+ DrawBG;
+
+ //Instead of Draw FG Procedure:
+ //We draw Buttons for our own
+ for I := 0 to Length(Button) - 1 do
+ Button[I].Draw;
+
+ // Statics
+ for I := 0 to Length(Static) - 1 do
+ Static[I].Draw;
+
+ // and texts
+ for I := 0 to Length(Text) - 1 do
+ Text[I].Draw;
+
+
+ //Draw Equalizer
+ if Theme.Song.Equalizer.Visible then
+ DrawEqualizer;
+
+ DrawExtensions;
+
+end;
+
+procedure TScreenSong.SelectNext;
+var
+ Skip: integer;
+ I: integer;
+ VS: Integer;
+begin
+ VS := CatSongs.VisibleSongs;
+
+ if VS > 0 then
+ begin
+ UnLoadDetailedCover;
+
+ Skip := 1;
+
+ // this 1 could be changed by CatSongs.FindNextVisible
+ while (not CatSongs.Song[(Interaction + Skip) mod Length(Interactions)].Visible) do Inc(Skip);
+
+ SongTarget := SongTarget + 1;//Skip;
+
+ Interaction := (Interaction + Skip) mod Length(Interactions);
+
+ // try to keep all at the beginning
+ if SongTarget > VS-1 then begin
+ SongTarget := SongTarget - VS;
+ SongCurrent := SongCurrent - VS;
+ end;
+
+ end;
+ // Interaction -> Button, ktorego okladke przeczytamy
+ // Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, 'Plain', false); // 0.5.0: show uncached texture
+end;
+
+procedure TScreenSong.SelectPrev;
+var
+ Skip: integer;
+ I: integer;
+ VS: Integer;
+begin
+ VS := CatSongs.VisibleSongs;
+
+ if VS > 0 then
+ begin
+ UnLoadDetailedCover;
+
+ Skip := 1;
+
+ while (not CatSongs.Song[(Interaction - Skip + Length(Interactions)) mod Length(Interactions)].Visible) do Inc(Skip);
+ SongTarget := SongTarget - 1;//Skip;
+
+ Interaction := (Interaction - Skip + Length(Interactions)) mod Length(Interactions);
+
+ // try to keep all at the beginning
+ if SongTarget < 0 then begin
+ SongTarget := SongTarget + CatSongs.VisibleSongs;
+ SongCurrent := SongCurrent + CatSongs.VisibleSongs;
+ end;
+
+ // Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, 'Plain', false); // 0.5.0: show uncached texture
+ end;
+end;
+
+procedure TScreenSong.UpdateLCD;
+begin
+ LCD.HideCursor;
+ LCD.Clear;
+ LCD.WriteText(1, Text[TextArtist].Text);
+ LCD.WriteText(2, Text[TextTitle].Text);
+end;
+
+//Procedure Change current played Preview
+procedure TScreenSong.ChangeMusic;
+begin
+ //When Music Preview is avtivated -> then Change Music
+ if (Ini.PreviewVolume <> 0) then
+ begin
+ if (NOT CatSongs.Song[Interaction].Main) AND(CatSongs.VisibleSongs > 0) then
+ begin
+ Music.Close;
+ if Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3) then begin
+ Music.MoveTo(Music.Length / 4);
+ //If Song Fading is activated then don't Play directly, and Set Volume to Null, else Play normal
+ if (Ini.PreviewFading = 0) then
+ Music.Play
+ else
+ Music.SetMusicVolume(0);
+ end;
+ end
+ else
+ Music.Stop;
+ end;
+end;
+
+procedure TScreenSong.SkipTo(Target: Cardinal); // 0.5.0
+var
+ Skip: integer;
+ I: integer;
+begin
+ UnLoadDetailedCover;
+
+ Interaction := High(CatSongs.Song);
+ SongTarget := 0;
+
+ for I := 1 to Target+1 do
+ SelectNext;
+
+ FixSelected2;
+end;
+
+procedure TScreenSong.DrawEqualizer;
+var
+ Data: TFFTData; //Audio Data
+ I, J: Integer;
+ Res: byte;
+ A, B: Integer;
+ PosX, PosY: Integer;
+ Pos: Real;
+begin
+if (not Music.Finished) AND (Theme.Song.Equalizer.Length > 0) then
+begin
+
+
+ A := GetTickCount div 44;
+
+ if (A <> EqualizerTime) then
+ begin
+ EqualizerTime := A;
+ Data := Music.GetFFTData;
+
+ B:=0;
+ Pos := 0;
+ Res := ceil(92/Theme.Song.Equalizer.Bands);//How much channels are used for one Band
+
+ //Change Lengths
+ for I := 0 to (Res * Theme.Song.Equalizer.Bands - 1) do
+ begin
+ A := floor(I/Res);
+
+ if (A<>B) then //Band changed
+ begin
+ if (Pos <= Theme.Song.Equalizer.Length) then
+ begin
+ if ((Pos < EqualizerBands[B]) AND (EqualizerBands[B]>1)) then
+ EqualizerBands[B] := EqualizerBands[B] - 1
+ else
+ EqualizerBands[B] := floor(Pos);
+ end
+ else
+ EqualizerBands[B] := 1;
+
+ B := A;
+ Pos := 0;
+ end;
+
+ if I > 35 then
+ Data[i] := Data[i] * 8
+ else if I > 11 then
+ Data[i] := Data[i] * 4.5
+ else
+ Data[i] := Data[i] * 1.1;
+
+ if (Data[i] >= 1) then
+ Data[i] := 0.9999999999999;
+
+ if Data[i]*Theme.Song.Equalizer.Length > Pos then
+ Pos := Data[i]*Theme.Song.Equalizer.Length;
+ end;
+
+ //Change Last Band
+ if (EqualizerBands[B] <= Theme.Song.Equalizer.Length) then
+ begin
+ if ((Pos < EqualizerBands[B]) AND (EqualizerBands[B]>1)) then
+ EqualizerBands[B] := EqualizerBands[B] - 1
+ else
+ EqualizerBands[B] := floor(Pos)
+ end
+ else
+ EqualizerBands[B] := 1;
+ end;
+
+ //Draw every Channel
+ glColor4f(Theme.Song.Equalizer.ColR, Theme.Song.Equalizer.ColG, Theme.Song.Equalizer.ColB, Theme.Song.Equalizer.Alpha); //Set Color
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+
+ PosY := Theme.Song.Equalizer.Y;
+ PosX := Theme.Song.Equalizer.X;
+
+ For I := 0 to Theme.Song.Equalizer.Bands-1 do
+ begin
+ if Theme.Song.Equalizer.Direction then
+ PosY := Theme.Song.Equalizer.Y //+ (Theme.Song.Equalizer.H + Theme.Song.Equalizer.Space) * Theme.Song.Equalizer.Length
+ else
+ PosX := Theme.Song.Equalizer.X;
+ //Draw for every visible quad
+ for J := 1 to EqualizerBands[I] do
+ begin
+ glBegin(GL_QUADS);
+ glVertex3f(PosX, PosY, Theme.Song.Equalizer.Z);
+ glVertex3f(PosX, PosY+Theme.Song.Equalizer.H, Theme.Song.Equalizer.Z);
+ glVertex3f(PosX+Theme.Song.Equalizer.W, PosY+Theme.Song.Equalizer.H, Theme.Song.Equalizer.Z);
+ glVertex3f(PosX+Theme.Song.Equalizer.W, PosY, Theme.Song.Equalizer.Z);
+ glEnd;
+
+ if Theme.Song.Equalizer.Direction then //Vertically
+ PosY := PosY - Theme.Song.Equalizer.H - Theme.Song.Equalizer.Space
+ else //Horizontally
+ PosX := PosX + Theme.Song.Equalizer.W + Theme.Song.Equalizer.Space;
+ end;
+ if Theme.Song.Equalizer.Direction then //Horizontally
+ PosX := PosX + Theme.Song.Equalizer.W + Theme.Song.Equalizer.Space
+ else //Vertically
+ PosY := PosY + Theme.Song.Equalizer.H + Theme.Song.Equalizer.Space;
+ end;
+end;
+end;
+
+Procedure TScreenSong.SelectRandomSong;
+var
+ I, I2: Integer;
+begin
+ Case PlaylistMan.Mode of
+ 0: //All Songs Just Select Random Song
+ begin
+ //When Tabs are activated then use Tab Method
+ if (Ini.Tabs_at_startup = 1) then
+ begin
+ repeat
+ I2 := Random(high(CatSongs.Song)+1) - low(CatSongs.Song)+1;
+ until CatSongs.Song[I2].Main = false;
+
+ //Search Cat
+ for I := I2 downto low(CatSongs.Song) do
+ begin
+ if CatSongs.Song[I].Main then
+ break;
+ end;
+ //In I ist jetzt die Kategorie in I2 der Song
+ //I is the CatNum, I2 is the No of the Song within this Cat
+
+ //Choose Cat
+ CatSongs.ShowCategoryList;
+
+ //Show Cat in Top Left Mod
+ ShowCatTL (I);
+
+ CatSongs.ClickCategoryButton(I);
+ SelectNext;
+
+ //Choose Song
+ SkipTo(I2-I);
+ end
+ //When Tabs are deactivated use easy Method
+ else
+ SkipTo(Random(CatSongs.VisibleSongs));
+ end;
+ 1: //One Category Select Category and Select Random Song
+ begin
+ CatSongs.ShowCategoryList;
+ CatSongs.ClickCategoryButton(PlaylistMan.CurPlayList);
+ ShowCatTL(PlaylistMan.CurPlayList);
+
+ SelectNext;
+ FixSelected2;
+
+ SkipTo(Random(CatSongs.VisibleSongs));
+ end;
+ 2: //Playlist: Select Playlist and Select Random Song
+ begin
+ PlaylistMan.SetPlayList(PlaylistMan.CurPlayList);
+
+ SkipTo(Random(CatSongs.VisibleSongs));
+ FixSelected2;
+ end;
+ end;
+
+ Music.PlayChange;
+ ChangeMusic;
+ SetScroll;
+ UpdateLCD;
+end;
+
+procedure TScreenSong.SetJoker;
+begin
+ //If Party Mode
+ if Mode = 1 then //Show Joker that are available
+ begin
+ if (PartySession.Teams.NumTeams >= 1) then
+ begin
+ Static[StaticTeam1Joker1].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 1);
+ Static[StaticTeam1Joker2].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 2);
+ Static[StaticTeam1Joker3].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 3);
+ Static[StaticTeam1Joker4].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 4);
+ Static[StaticTeam1Joker5].Visible := (PartySession.Teams.Teaminfo[0].Joker >= 5);
+ end
+ else
+ begin
+ Static[StaticTeam1Joker1].Visible := False;
+ Static[StaticTeam1Joker2].Visible := False;
+ Static[StaticTeam1Joker3].Visible := False;
+ Static[StaticTeam1Joker4].Visible := False;
+ Static[StaticTeam1Joker5].Visible := False;
+ end;
+
+ if (PartySession.Teams.NumTeams >= 2) then
+ begin
+ Static[StaticTeam2Joker1].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 1);
+ Static[StaticTeam2Joker2].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 2);
+ Static[StaticTeam2Joker3].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 3);
+ Static[StaticTeam2Joker4].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 4);
+ Static[StaticTeam2Joker5].Visible := (PartySession.Teams.Teaminfo[1].Joker >= 5);
+ end
+ else
+ begin
+ Static[StaticTeam2Joker1].Visible := False;
+ Static[StaticTeam2Joker2].Visible := False;
+ Static[StaticTeam2Joker3].Visible := False;
+ Static[StaticTeam2Joker4].Visible := False;
+ Static[StaticTeam2Joker5].Visible := False;
+ end;
+
+ if (PartySession.Teams.NumTeams >= 3) then
+ begin
+ Static[StaticTeam3Joker1].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 1);
+ Static[StaticTeam3Joker2].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 2);
+ Static[StaticTeam3Joker3].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 3);
+ Static[StaticTeam3Joker4].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 4);
+ Static[StaticTeam3Joker5].Visible := (PartySession.Teams.Teaminfo[2].Joker >= 5);
+ end
+ else
+ begin
+ Static[StaticTeam3Joker1].Visible := False;
+ Static[StaticTeam3Joker2].Visible := False;
+ Static[StaticTeam3Joker3].Visible := False;
+ Static[StaticTeam3Joker4].Visible := False;
+ Static[StaticTeam3Joker5].Visible := False;
+ end;
+ end
+ else
+ begin //Hide all
+ Static[StaticTeam1Joker1].Visible := False;
+ Static[StaticTeam1Joker2].Visible := False;
+ Static[StaticTeam1Joker3].Visible := False;
+ Static[StaticTeam1Joker4].Visible := False;
+ Static[StaticTeam1Joker5].Visible := False;
+
+ Static[StaticTeam2Joker1].Visible := False;
+ Static[StaticTeam2Joker2].Visible := False;
+ Static[StaticTeam2Joker3].Visible := False;
+ Static[StaticTeam2Joker4].Visible := False;
+ Static[StaticTeam2Joker5].Visible := False;
+
+ Static[StaticTeam3Joker1].Visible := False;
+ Static[StaticTeam3Joker2].Visible := False;
+ Static[StaticTeam3Joker3].Visible := False;
+ Static[StaticTeam3Joker4].Visible := False;
+ Static[StaticTeam3Joker5].Visible := False;
+ end;
+end;
+
+procedure TScreenSong.SetStatics;
+var
+ I: Integer;
+ Visible: Boolean;
+begin
+ //Set Visibility of Party Statics and Text
+ Visible := (Mode = 1);
+
+ For I := 0 to high(StaticParty) do
+ Static[StaticParty[I]].Visible := Visible;
+
+ For I := 0 to high(TextParty) do
+ Text[TextParty[I]].Visible := Visible;
+
+ //Set Visibility of Non Party Statics and Text
+ Visible := not Visible;
+
+ For I := 0 to high(StaticNonParty) do
+ Static[StaticNonParty[I]].Visible := Visible;
+
+ For I := 0 to high(TextNonParty) do
+ Text[TextNonParty[I]].Visible := Visible;
+end;
+
+//Procedures for Menu
+
+procedure TScreenSong.StartSong;
+begin
+ CatSongs.Selected := Interaction;
+ Music.Stop;
+ //Party Mode
+ if (Mode = 1) then
+ begin
+ FadeTo(@ScreenSingModi);
+ end
+ else
+ begin
+ FadeTo(@ScreenSing);
+ end;
+end;
+
+procedure TScreenSong.SelectPlayers;
+begin
+ CatSongs.Selected := Interaction;
+ Music.Stop;
+
+ ScreenName.Goto_SingScreen := True;
+ FadeTo(@ScreenName);
+end;
+
+procedure TScreenSong.OpenEditor;
+begin
+ if (Length(Songs.Song) > 0) and (not CatSongs.Song[Interaction].Main) AND (Mode = 0) then begin
+ Music.Stop;
+ Music.PlayStart;
+ ScreenEditSub.Path := CatSongs.Song[Interaction].Path;
+ ScreenEditSub.FileName := CatSongs.Song[Interaction].FileName;
+ FadeTo(@ScreenEditSub);
+ end;
+end;
+
+//Team No of Team (0-5)
+procedure TScreenSong.DoJoker (Team: Byte);
+begin
+ if (Mode = 1) AND (PartySession.Teams.NumTeams >= Team + 1) AND (PartySession.Teams.Teaminfo[Team].Joker > 0) then
+ begin
+ //Joker spielen
+ Dec(PartySession.Teams.Teaminfo[Team].Joker);
+ SelectRandomSong;
+ SetJoker;
+ end;
+end;
+
+//Detailed Cover Unloading. Unloads the Detailed, uncached Cover of the cur. Song
+procedure TScreenSong.UnLoadDetailedCover;
+begin
+ CoverTime := 0;
+
+ Button[Interaction].Texture := Texture.GetTexture(Button[Interaction].Texture.Name, 'Plain', true); // 0.5.0: show cached texture
+ Button[Interaction].Texture2.Alpha := 0;
+
+ if Button[Interaction].Texture.Name <> Skin.GetTextureFileName('SongCover') then
+ Texture.UnloadTexture(Button[Interaction].Texture.Name, false);
+end;
+
+procedure TScreenSong.Refresh;
+begin {
+CatSongs.Refresh;
+CatSongs.ShowCategoryList;
+Interaction := 0;
+SelectNext;
+FixSelected; }
+
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenSongMenu.pas b/Game/Code/Screens/UScreenSongMenu.pas
index 41432356..ce331e2f 100644
--- a/Game/Code/Screens/UScreenSongMenu.pas
+++ b/Game/Code/Screens/UScreenSongMenu.pas
@@ -1,619 +1,632 @@
-unit UScreenSongMenu;
-
-interface
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, SysUtils, UThemes;
-
-type
- TScreenSongMenu = class(TMenu)
- private
- CurMenu: Byte; //Num of the cur. Shown Menu
- public
- Visible: Boolean; //Whether the Menu should be Drawn
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- function Draw: boolean; override;
- procedure MenuShow(sMenu: Byte);
- procedure HandleReturn;
- end;
-
-const
- SM_Main = 1;
-
- SM_PlayList = 64 or 1;
- SM_Playlist_Add = 64 or 2;
- SM_Playlist_New = 64 or 3;
-
- SM_Playlist_DelItem = 64 or 5;
-
- SM_Playlist_Load = 64 or 8 or 1;
- SM_Playlist_Del = 64 or 8 or 5;
-
-
- SM_Party_Main = 128 or 1;
- SM_Party_Joker = 128 or 2;
-
-var
- ISelections: Array of String;
- SelectValue: Integer;
-
-
-implementation
-
-uses UGraphic, UMain, UIni, UTexture, ULanguage, UParty, UPlaylist, USongs;
-
-function TScreenSongMenu.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- if (CurMenu = SM_Playlist_New) AND (Interaction=0) then
- begin
- 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:
- begin
- Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + chr(ScanCode);
- exit;
- end;
-
- SDLK_BACKSPACE:
- begin
- Button[Interaction].Text[0].DeleteLastL;
- exit;
- end;
- end;
- end;
-
- case PressedKey of
- SDLK_Q:
- begin
- Result := false;
- end;
-
-
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- Music.PlayBack;
- Visible := False;
- end;
-
- SDLK_RETURN:
- begin
- HandleReturn;
- end;
-
- SDLK_DOWN: InteractNext;
- SDLK_UP: InteractPrev;
-
- SDLK_RIGHT:
- begin
- if (Interaction=3) then
- InteractInc;
- end;
- SDLK_LEFT:
- begin
- if (Interaction=3) then
- InteractDec;
- end;
-
- SDLK_1:
- begin //Jocker
- //Joker spielen
- case CurMenu of
- SM_Party_Main:
- begin
- ScreenSong.DoJoker(0)
- end;
- end;
- end;
- SDLK_2:
- begin //Jocker
- //Joker spielen
- case CurMenu of
- SM_Party_Main:
- begin
- ScreenSong.DoJoker(1)
- end;
- end;
- end;
- SDLK_3:
- begin //Jocker
- //Joker spielen
- case CurMenu of
- SM_Party_Main:
- begin
- ScreenSong.DoJoker(2)
- end;
- end;
- end;
-
-
- end;
- end;
-end;
-
-constructor TScreenSongMenu.Create;
-var
- I: integer;
-begin
- inherited Create;
-
- //Create Dummy SelectSlide Entrys
- SetLength(ISelections, 1);
- ISelections[0] := 'Dummy';
-
-
- AddText(Theme.SongMenu.TextMenu);
-
- LoadFromTheme(Theme.SongMenu);
-
- AddButton(Theme.SongMenu.Button1);
- if (Length(Button[0].Text) = 0) then
- AddButtonText(14, 20, 'Button 1');
-
- AddButton(Theme.SongMenu.Button2);
- if (Length(Button[1].Text) = 0) then
- AddButtonText(14, 20, 'Button 2');
-
- AddButton(Theme.SongMenu.Button3);
- if (Length(Button[2].Text) = 0) then
- AddButtonText(14, 20, 'Button 3');
-
- AddSelectSlide(Theme.SongMenu.SelectSlide3, SelectValue, ISelections);
-
- AddButton(Theme.SongMenu.Button4);
- if (Length(Button[3].Text) = 0) then
- AddButtonText(14, 20, 'Button 4');
-
-
- Interaction := 0;
-end;
-
-function TScreenSongMenu.Draw: boolean;
-begin
- inherited Draw;
-end;
-
-procedure TScreenSongMenu.onShow;
-begin
-
-end;
-
-procedure TScreenSongMenu.MenuShow(sMenu: Byte);
-begin
- Interaction := 0; //Reset Interaction
- Visible := True; //Set Visible
- Case sMenu of
- SM_Main:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_MAIN');
-
- Button[0].Visible := True;
- Button[1].Visible := True;
- Button[2].Visible := True;
- Button[3].Visible := True;
- SelectsS[0].Visible := False;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAY');
- Button[1].Text[0].Text := Language.Translate('SONG_MENU_CHANGEPLAYERS');
- Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_ADD');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_EDIT');
- end;
-
- SM_PlayList:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST');
-
- Button[0].Visible := True;
- Button[1].Visible := True;
- Button[2].Visible := True;
- Button[3].Visible := True;
- SelectsS[0].Visible := False;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAY');
- Button[1].Text[0].Text := Language.Translate('SONG_MENU_CHANGEPLAYERS');
- Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_DEL');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_EDIT');
- end;
-
- SM_Playlist_Add:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_ADD');
-
- Button[0].Visible := True;
- Button[1].Visible := False;
- Button[2].Visible := False;
- Button[3].Visible := True;
- SelectsS[0].Visible := True;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_ADD_NEW');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_ADD_EXISTING');
-
- SetLength(ISelections, Length(PlaylistMan.Playlists));
- PlaylistMan.GetNames(ISelections);
-
- if (Length(ISelections)>=1) then
- begin
- UpdateSelectSlideOptions(Theme.SongMenu.SelectSlide3, 0, ISelections, SelectValue);
- end
- else
- begin
- Button[3].Visible := False;
- SelectsS[0].Visible := False;
- Button[2].Visible := True;
- Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NOEXISTING');
- end;
- end;
-
- SM_Playlist_New:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_NEW');
-
- Button[0].Visible := True;
- Button[1].Visible := False;
- Button[2].Visible := True;
- Button[3].Visible := True;
- SelectsS[0].Visible := False;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NEW_UNNAMED');
- Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NEW_CREATE');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
- end;
-
- SM_Playlist_DelItem:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_DELITEM');
-
- Button[0].Visible := True;
- Button[1].Visible := False;
- Button[2].Visible := False;
- Button[3].Visible := True;
- SelectsS[0].Visible := False;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_YES');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
- end;
-
- SM_Playlist_Load:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_LOAD');
-
- //Show Delete Curent Playlist Button when Playlist is opened
- Button[0].Visible := (CatSongs.CatNumShow = -3);
-
- Button[1].Visible := False;
- Button[2].Visible := False;
- Button[3].Visible := True;
- SelectsS[0].Visible := True;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_DELCURRENT');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_LOAD');
-
- SetLength(ISelections, Length(PlaylistMan.Playlists));
- PlaylistMan.GetNames(ISelections);
-
- if (Length(ISelections)>=1) then
- begin
- UpdateSelectSlideOptions(Theme.SongMenu.SelectSlide3, 0, ISelections, SelectValue);
- Interaction := 3;
- end
- else
- begin
- Button[3].Visible := False;
- SelectsS[0].Visible := False;
- Button[2].Visible := True;
- Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NOEXISTING');
- Interaction := 2;
- end;
- end;
-
- SM_Playlist_Del:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_DEL');
-
- Button[0].Visible := True;
- Button[1].Visible := False;
- Button[2].Visible := False;
- Button[3].Visible := True;
- SelectsS[0].Visible := False;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_YES');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
- end;
-
-
- SM_Party_Main:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PARTY_MAIN');
-
- Button[0].Visible := True;
- Button[1].Visible := False;
- Button[2].Visible := False;
- Button[3].Visible := True;
- SelectsS[0].Visible := False;
-
- Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAY');
- //Button[1].Text[0].Text := Language.Translate('SONG_MENU_JOKER');
- //Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYMODI');
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_JOKER');
- end;
-
- SM_Party_Joker:
- begin
- CurMenu := sMenu;
- Text[0].Text := Language.Translate('SONG_MENU_NAME_PARTY_JOKER');
-
- Button[0].Visible := (PartySession.Teams.NumTeams >= 1) AND (PartySession.Teams.Teaminfo[0].Joker > 0);
- Button[1].Visible := (PartySession.Teams.NumTeams >= 2) AND (PartySession.Teams.Teaminfo[1].Joker > 0);
- Button[2].Visible := (PartySession.Teams.NumTeams >= 3) AND (PartySession.Teams.Teaminfo[2].Joker > 0);
- Button[3].Visible := True;
- SelectsS[0].Visible := False;
-
- Button[0].Text[0].Text := String(PartySession.Teams.Teaminfo[0].Name);
- Button[1].Text[0].Text := String(PartySession.Teams.Teaminfo[1].Name);
- Button[2].Text[0].Text := String(PartySession.Teams.Teaminfo[2].Name);
- Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
-
- //Set right Interaction
- if (not Button[0].Visible) then
- begin
- if (not Button[1].Visible) then
- begin
- if (not Button[2].Visible) then
- begin
- Interaction := 4;
- end
- else Interaction := 2;
- end
- else Interaction := 1;
- end;
-
- end;
- end;
-end;
-
-procedure TScreenSongMenu.HandleReturn;
-begin
- Case CurMenu of
- SM_Main:
- begin
- Case Interaction of
- 0: //Button 1
- begin
- ScreenSong.StartSong;
- Visible := False;
- end;
-
- 1: //Button 2
- begin
- //Select New Players then Sing:
- ScreenSong.SelectPlayers;
- Visible := False;
- end;
-
- 2: //Button 3
- begin
- //Show add to Playlist Menu
- MenuShow(SM_Playlist_Add);
- end;
-
- 3: //SelectSlide 3
- begin
- //Dummy
- end;
-
- 4: //Button 4
- begin
- ScreenSong.OpenEditor;
- Visible := False;
- end;
- end;
- end;
-
- SM_PlayList:
- begin
- Visible := False;
- Case Interaction of
- 0: //Button 1
- begin
- ScreenSong.StartSong;
- Visible := False;
- end;
-
- 1: //Button 2
- begin
- //Select New Players then Sing:
- ScreenSong.SelectPlayers;
- Visible := False;
- end;
-
- 2: //Button 3
- begin
- //Show add to Playlist Menu
- MenuShow(SM_Playlist_DelItem);
- end;
-
- 3: //SelectSlide 3
- begin
- //Dummy
- end;
-
- 4: //Button 4
- begin
- ScreenSong.OpenEditor;
- Visible := False;
- end;
- end;
- end;
-
- SM_Playlist_Add:
- begin
- Case Interaction of
- 0: //Button 1
- begin
- MenuShow(SM_Playlist_New);
- end;
-
- 3: //SelectSlide 3
- begin
- //Dummy
- end;
-
- 4: //Button 4
- begin
- PlaylistMan.AddItem(ScreenSong.Interaction, SelectValue);
- Visible := False;
- end;
- end;
- end;
-
- SM_Playlist_New:
- begin
- Case Interaction of
- 0: //Button 1
- begin
- //Nothing, Button for Entering Name
- end;
-
- 2: //Button 3
- begin
- //Create Playlist and Add Song
- PlaylistMan.AddItem(
- ScreenSong.Interaction,
- PlaylistMan.AddPlaylist(Button[0].Text[0].Text));
- Visible := False;
- end;
-
- 3: //SelectSlide 3
- begin
- //Cancel -> Go back to Add screen
- MenuShow(SM_Playlist_Add);
- end;
-
- 4: //Button 4
- begin
- Visible := False;
- end;
- end;
- end;
-
- SM_Playlist_DelItem:
- begin
- Visible := False;
- Case Interaction of
- 0: //Button 1
- begin
- //Delete
- PlayListMan.DelItem(PlayListMan.GetIndexbySongID(ScreenSong.Interaction));
- Visible := False;
- end;
-
- 4: //Button 4
- begin
- MenuShow(SM_Playlist);
- end;
- end;
- end;
-
- SM_Playlist_Load:
- begin
- Case Interaction of
- 0: //Button 1 (Delete Playlist)
- begin
- MenuShow(SM_Playlist_Del);
- end;
- 4: //Button 4
- begin
- //Load Playlist
- PlaylistMan.SetPlayList(SelectValue);
- Visible := False;
- end;
- end;
- end;
-
- SM_Playlist_Del:
- begin
- Visible := False;
- Case Interaction of
- 0: //Button 1
- begin
- //Delete
- PlayListMan.DelPlaylist(PlaylistMan.CurPlayList);
- Visible := False;
- end;
-
- 4: //Button 4
- begin
- MenuShow(SM_Playlist_Load);
- end;
- end;
- end;
-
- SM_Party_Main:
- begin
- Case Interaction of
- 0: //Button 1
- begin
- //Start Singing
- ScreenSong.StartSong;
- Visible := False;
- end;
-
- 4: //Button 4
- begin
- //Joker
- MenuShow(SM_Party_Joker);
- end;
- end;
- end;
-
- SM_Party_Joker:
- begin
- Visible := False;
- Case Interaction of
- 0: //Button 1
- begin
- //Joker Team 1
- ScreenSong.DoJoker(0);
- end;
-
- 1: //Button 2
- begin
- //Joker Team 2
- ScreenSong.DoJoker(1);
- end;
-
- 2: //Button 3
- begin
- //Joker Team 3
- ScreenSong.DoJoker(2);
- end;
-
- 4: //Button 4
- begin
- //Cancel... (Fo back to old Menu)
- MenuShow(SM_Party_Main);
- end;
- end;
- end;
- end;
-end;
-
-end.
-
+unit UScreenSongMenu;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+{$ENDIF}
+
+uses
+ UMenu,
+ SDL,
+ UDisplay,
+ UMusic,
+ UFiles,
+ SysUtils,
+ UThemes;
+
+type
+ TScreenSongMenu = class(TMenu)
+ private
+ CurMenu: Byte; //Num of the cur. Shown Menu
+ public
+ Visible: Boolean; //Whether the Menu should be Drawn
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ function Draw: boolean; override;
+ procedure MenuShow(sMenu: Byte);
+ procedure HandleReturn;
+ end;
+
+const
+ SM_Main = 1;
+
+ SM_PlayList = 64 or 1;
+ SM_Playlist_Add = 64 or 2;
+ SM_Playlist_New = 64 or 3;
+
+ SM_Playlist_DelItem = 64 or 5;
+
+ SM_Playlist_Load = 64 or 8 or 1;
+ SM_Playlist_Del = 64 or 8 or 5;
+
+
+ SM_Party_Main = 128 or 1;
+ SM_Party_Joker = 128 or 2;
+
+var
+ ISelections: Array of String;
+ SelectValue: Integer;
+
+
+implementation
+
+uses UGraphic,
+ UMain,
+ UIni,
+ UTexture,
+ ULanguage,
+ UParty,
+ UPlaylist,
+ USongs;
+
+function TScreenSongMenu.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ if (CurMenu = SM_Playlist_New) AND (Interaction=0) then
+ begin
+ 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:
+ begin
+ Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + chr(ScanCode);
+ exit;
+ end;
+
+ SDLK_BACKSPACE:
+ begin
+ Button[Interaction].Text[0].DeleteLastL;
+ exit;
+ end;
+ end;
+ end;
+
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+
+
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ Music.PlayBack;
+ Visible := False;
+ end;
+
+ SDLK_RETURN:
+ begin
+ HandleReturn;
+ end;
+
+ SDLK_DOWN: InteractNext;
+ SDLK_UP: InteractPrev;
+
+ SDLK_RIGHT:
+ begin
+ if (Interaction=3) then
+ InteractInc;
+ end;
+ SDLK_LEFT:
+ begin
+ if (Interaction=3) then
+ InteractDec;
+ end;
+
+ SDLK_1:
+ begin //Jocker
+ //Joker spielen
+ case CurMenu of
+ SM_Party_Main:
+ begin
+ ScreenSong.DoJoker(0)
+ end;
+ end;
+ end;
+ SDLK_2:
+ begin //Jocker
+ //Joker spielen
+ case CurMenu of
+ SM_Party_Main:
+ begin
+ ScreenSong.DoJoker(1)
+ end;
+ end;
+ end;
+ SDLK_3:
+ begin //Jocker
+ //Joker spielen
+ case CurMenu of
+ SM_Party_Main:
+ begin
+ ScreenSong.DoJoker(2)
+ end;
+ end;
+ end;
+
+
+ end;
+ end;
+end;
+
+constructor TScreenSongMenu.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ //Create Dummy SelectSlide Entrys
+ SetLength(ISelections, 1);
+ ISelections[0] := 'Dummy';
+
+
+ AddText(Theme.SongMenu.TextMenu);
+
+ LoadFromTheme(Theme.SongMenu);
+
+ AddButton(Theme.SongMenu.Button1);
+ if (Length(Button[0].Text) = 0) then
+ AddButtonText(14, 20, 'Button 1');
+
+ AddButton(Theme.SongMenu.Button2);
+ if (Length(Button[1].Text) = 0) then
+ AddButtonText(14, 20, 'Button 2');
+
+ AddButton(Theme.SongMenu.Button3);
+ if (Length(Button[2].Text) = 0) then
+ AddButtonText(14, 20, 'Button 3');
+
+ AddSelectSlide(Theme.SongMenu.SelectSlide3, SelectValue, ISelections);
+
+ AddButton(Theme.SongMenu.Button4);
+ if (Length(Button[3].Text) = 0) then
+ AddButtonText(14, 20, 'Button 4');
+
+
+ Interaction := 0;
+end;
+
+function TScreenSongMenu.Draw: boolean;
+begin
+ inherited Draw;
+end;
+
+procedure TScreenSongMenu.onShow;
+begin
+
+end;
+
+procedure TScreenSongMenu.MenuShow(sMenu: Byte);
+begin
+ Interaction := 0; //Reset Interaction
+ Visible := True; //Set Visible
+ Case sMenu of
+ SM_Main:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_MAIN');
+
+ Button[0].Visible := True;
+ Button[1].Visible := True;
+ Button[2].Visible := True;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := False;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAY');
+ Button[1].Text[0].Text := Language.Translate('SONG_MENU_CHANGEPLAYERS');
+ Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_ADD');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_EDIT');
+ end;
+
+ SM_PlayList:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST');
+
+ Button[0].Visible := True;
+ Button[1].Visible := True;
+ Button[2].Visible := True;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := False;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAY');
+ Button[1].Text[0].Text := Language.Translate('SONG_MENU_CHANGEPLAYERS');
+ Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_DEL');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_EDIT');
+ end;
+
+ SM_Playlist_Add:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_ADD');
+
+ Button[0].Visible := True;
+ Button[1].Visible := False;
+ Button[2].Visible := False;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := True;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_ADD_NEW');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_ADD_EXISTING');
+
+ SetLength(ISelections, Length(PlaylistMan.Playlists));
+ PlaylistMan.GetNames(ISelections);
+
+ if (Length(ISelections)>=1) then
+ begin
+ UpdateSelectSlideOptions(Theme.SongMenu.SelectSlide3, 0, ISelections, SelectValue);
+ end
+ else
+ begin
+ Button[3].Visible := False;
+ SelectsS[0].Visible := False;
+ Button[2].Visible := True;
+ Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NOEXISTING');
+ end;
+ end;
+
+ SM_Playlist_New:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_NEW');
+
+ Button[0].Visible := True;
+ Button[1].Visible := False;
+ Button[2].Visible := True;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := False;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NEW_UNNAMED');
+ Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NEW_CREATE');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
+ end;
+
+ SM_Playlist_DelItem:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_DELITEM');
+
+ Button[0].Visible := True;
+ Button[1].Visible := False;
+ Button[2].Visible := False;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := False;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_YES');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
+ end;
+
+ SM_Playlist_Load:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_LOAD');
+
+ //Show Delete Curent Playlist Button when Playlist is opened
+ Button[0].Visible := (CatSongs.CatNumShow = -3);
+
+ Button[1].Visible := False;
+ Button[2].Visible := False;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := True;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_DELCURRENT');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_LOAD');
+
+ SetLength(ISelections, Length(PlaylistMan.Playlists));
+ PlaylistMan.GetNames(ISelections);
+
+ if (Length(ISelections)>=1) then
+ begin
+ UpdateSelectSlideOptions(Theme.SongMenu.SelectSlide3, 0, ISelections, SelectValue);
+ Interaction := 3;
+ end
+ else
+ begin
+ Button[3].Visible := False;
+ SelectsS[0].Visible := False;
+ Button[2].Visible := True;
+ Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYLIST_NOEXISTING');
+ Interaction := 2;
+ end;
+ end;
+
+ SM_Playlist_Del:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST_DEL');
+
+ Button[0].Visible := True;
+ Button[1].Visible := False;
+ Button[2].Visible := False;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := False;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_YES');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
+ end;
+
+
+ SM_Party_Main:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PARTY_MAIN');
+
+ Button[0].Visible := True;
+ Button[1].Visible := False;
+ Button[2].Visible := False;
+ Button[3].Visible := True;
+ SelectsS[0].Visible := False;
+
+ Button[0].Text[0].Text := Language.Translate('SONG_MENU_PLAY');
+ //Button[1].Text[0].Text := Language.Translate('SONG_MENU_JOKER');
+ //Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYMODI');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_JOKER');
+ end;
+
+ SM_Party_Joker:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PARTY_JOKER');
+
+ Button[0].Visible := (PartySession.Teams.NumTeams >= 1) AND (PartySession.Teams.Teaminfo[0].Joker > 0);
+ Button[1].Visible := (PartySession.Teams.NumTeams >= 2) AND (PartySession.Teams.Teaminfo[1].Joker > 0);
+ Button[2].Visible := (PartySession.Teams.NumTeams >= 3) AND (PartySession.Teams.Teaminfo[2].Joker > 0);
+ Button[3].Visible := True;
+ SelectsS[0].Visible := False;
+
+ Button[0].Text[0].Text := String(PartySession.Teams.Teaminfo[0].Name);
+ Button[1].Text[0].Text := String(PartySession.Teams.Teaminfo[1].Name);
+ Button[2].Text[0].Text := String(PartySession.Teams.Teaminfo[2].Name);
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
+
+ //Set right Interaction
+ if (not Button[0].Visible) then
+ begin
+ if (not Button[1].Visible) then
+ begin
+ if (not Button[2].Visible) then
+ begin
+ Interaction := 4;
+ end
+ else Interaction := 2;
+ end
+ else Interaction := 1;
+ end;
+
+ end;
+ end;
+end;
+
+procedure TScreenSongMenu.HandleReturn;
+begin
+ Case CurMenu of
+ SM_Main:
+ begin
+ Case Interaction of
+ 0: //Button 1
+ begin
+ ScreenSong.StartSong;
+ Visible := False;
+ end;
+
+ 1: //Button 2
+ begin
+ //Select New Players then Sing:
+ ScreenSong.SelectPlayers;
+ Visible := False;
+ end;
+
+ 2: //Button 3
+ begin
+ //Show add to Playlist Menu
+ MenuShow(SM_Playlist_Add);
+ end;
+
+ 3: //SelectSlide 3
+ begin
+ //Dummy
+ end;
+
+ 4: //Button 4
+ begin
+ ScreenSong.OpenEditor;
+ Visible := False;
+ end;
+ end;
+ end;
+
+ SM_PlayList:
+ begin
+ Visible := False;
+ Case Interaction of
+ 0: //Button 1
+ begin
+ ScreenSong.StartSong;
+ Visible := False;
+ end;
+
+ 1: //Button 2
+ begin
+ //Select New Players then Sing:
+ ScreenSong.SelectPlayers;
+ Visible := False;
+ end;
+
+ 2: //Button 3
+ begin
+ //Show add to Playlist Menu
+ MenuShow(SM_Playlist_DelItem);
+ end;
+
+ 3: //SelectSlide 3
+ begin
+ //Dummy
+ end;
+
+ 4: //Button 4
+ begin
+ ScreenSong.OpenEditor;
+ Visible := False;
+ end;
+ end;
+ end;
+
+ SM_Playlist_Add:
+ begin
+ Case Interaction of
+ 0: //Button 1
+ begin
+ MenuShow(SM_Playlist_New);
+ end;
+
+ 3: //SelectSlide 3
+ begin
+ //Dummy
+ end;
+
+ 4: //Button 4
+ begin
+ PlaylistMan.AddItem(ScreenSong.Interaction, SelectValue);
+ Visible := False;
+ end;
+ end;
+ end;
+
+ SM_Playlist_New:
+ begin
+ Case Interaction of
+ 0: //Button 1
+ begin
+ //Nothing, Button for Entering Name
+ end;
+
+ 2: //Button 3
+ begin
+ //Create Playlist and Add Song
+ PlaylistMan.AddItem(
+ ScreenSong.Interaction,
+ PlaylistMan.AddPlaylist(Button[0].Text[0].Text));
+ Visible := False;
+ end;
+
+ 3: //SelectSlide 3
+ begin
+ //Cancel -> Go back to Add screen
+ MenuShow(SM_Playlist_Add);
+ end;
+
+ 4: //Button 4
+ begin
+ Visible := False;
+ end;
+ end;
+ end;
+
+ SM_Playlist_DelItem:
+ begin
+ Visible := False;
+ Case Interaction of
+ 0: //Button 1
+ begin
+ //Delete
+ PlayListMan.DelItem(PlayListMan.GetIndexbySongID(ScreenSong.Interaction));
+ Visible := False;
+ end;
+
+ 4: //Button 4
+ begin
+ MenuShow(SM_Playlist);
+ end;
+ end;
+ end;
+
+ SM_Playlist_Load:
+ begin
+ Case Interaction of
+ 0: //Button 1 (Delete Playlist)
+ begin
+ MenuShow(SM_Playlist_Del);
+ end;
+ 4: //Button 4
+ begin
+ //Load Playlist
+ PlaylistMan.SetPlayList(SelectValue);
+ Visible := False;
+ end;
+ end;
+ end;
+
+ SM_Playlist_Del:
+ begin
+ Visible := False;
+ Case Interaction of
+ 0: //Button 1
+ begin
+ //Delete
+ PlayListMan.DelPlaylist(PlaylistMan.CurPlayList);
+ Visible := False;
+ end;
+
+ 4: //Button 4
+ begin
+ MenuShow(SM_Playlist_Load);
+ end;
+ end;
+ end;
+
+ SM_Party_Main:
+ begin
+ Case Interaction of
+ 0: //Button 1
+ begin
+ //Start Singing
+ ScreenSong.StartSong;
+ Visible := False;
+ end;
+
+ 4: //Button 4
+ begin
+ //Joker
+ MenuShow(SM_Party_Joker);
+ end;
+ end;
+ end;
+
+ SM_Party_Joker:
+ begin
+ Visible := False;
+ Case Interaction of
+ 0: //Button 1
+ begin
+ //Joker Team 1
+ ScreenSong.DoJoker(0);
+ end;
+
+ 1: //Button 2
+ begin
+ //Joker Team 2
+ ScreenSong.DoJoker(1);
+ end;
+
+ 2: //Button 3
+ begin
+ //Joker Team 3
+ ScreenSong.DoJoker(2);
+ end;
+
+ 4: //Button 4
+ begin
+ //Cancel... (Fo back to old Menu)
+ MenuShow(SM_Party_Main);
+ end;
+ end;
+ end;
+ end;
+end;
+
+end.
+
diff --git a/Game/Code/Screens/UScreenStatMain.pas b/Game/Code/Screens/UScreenStatMain.pas
index f7961727..223ad2b2 100644
--- a/Game/Code/Screens/UScreenStatMain.pas
+++ b/Game/Code/Screens/UScreenStatMain.pas
@@ -1,231 +1,285 @@
-unit UScreenStatMain;
-
-interface
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-
-uses
- UMenu, SDL, SysUtils, UDisplay, UMusic, UIni, UThemes;
-
-type
- TScreenStatMain = class(TMenu)
- private
- //Some Stat Value that don't need to be calculated 2 times
- SongswithVid: Cardinal;
- public
- TextOverview: integer;
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure SetAnimationProgress(Progress: real); override;
-
- procedure SetOverview;
- end;
-
-implementation
-
-uses UGraphic, UDataBase, USongs, ULanguage, windows, ULog;
-
-function TScreenStatMain.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
-begin
- Result := true;
- If (PressedDown) Then
- begin // Key Down
- case PressedKey of
- SDLK_Q:
- begin
- Result := false;
- end;
-
- SDLK_ESCAPE,
- SDLK_BACKSPACE :
- begin
- Ini.Save;
- Music.PlayBack;
- FadeTo(@ScreenMain);
- end;
- SDLK_RETURN:
- begin
- //Exit Button Pressed
- if Interaction = 4 then begin
- Music.PlayBack;
- FadeTo(@ScreenMain);
- end
- else //One of the Stats Buttons Pressed
- begin
- Music.PlayBack;
- ScreenStatDetail.Typ := Interaction;
- FadeTo(@ScreenStatDetail);
- end;
- end;
- SDLK_LEFT:
- begin
- InteractPrev;
- end;
- SDLK_RIGHT:
- begin
- InteractNext;
- end;
- SDLK_UP:
- begin
- InteractPrev;
- end;
- SDLK_DOWN:
- begin
- InteractNext;
- end;
- end;
- end;
-end;
-
-constructor TScreenStatMain.Create;
-var
- I: integer;
-begin
- inherited Create;
-
- TextOverview := AddText(Theme.StatMain.TextOverview);
-
- LoadFromTheme(Theme.StatMain);
-
- AddButton(Theme.StatMain.ButtonScores);
- if (Length(Button[0].Text)=0) then
- AddButtonText(14, 20, Theme.StatDetail.Description[0]);
-
- AddButton(Theme.StatMain.ButtonSingers);
- if (Length(Button[1].Text)=0) then
- AddButtonText(14, 20, Theme.StatDetail.Description[1]);
-
- AddButton(Theme.StatMain.ButtonSongs);
- if (Length(Button[2].Text)=0) then
- AddButtonText(14, 20, Theme.StatDetail.Description[2]);
-
- AddButton(Theme.StatMain.ButtonBands);
- if (Length(Button[3].Text)=0) then
- AddButtonText(14, 20, Theme.StatDetail.Description[3]);
-
- AddButton(Theme.StatMain.ButtonExit);
- if (Length(Button[4].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[4]);
-
- Interaction := 0;
-
- //Set Songs with Vid
- SongswithVid := 0;
- For I := 0 to high(Songs.Song) do
- if (Songs.Song[I].Video <> '') then
- Inc(SongswithVid);
-end;
-
-procedure TScreenStatMain.onShow;
-begin
- //Set Overview Text:
- SetOverview;
-end;
-
-procedure TScreenStatMain.SetOverview;
-var
- Overview, Formatstr: String;
- I: Integer;
- //Some Vars to Save Attributes to
- A1, A2, A3: Integer;
- A4, A5: String;
- Result1, Result2: AStatResult;
- ResetTime: TSystemTime;
- function GetFileCreation(Filename: String): TSystemTime;
- var
- FindData: TWin32FindData;
- Handle: THandle;
- begin
- Handle := FindFirstFile(PChar(Filename), FindData);
- if Handle <> INVALID_HANDLE_VALUE then
- begin
- FileTimeToSystemTime(FindData.ftCreationTime, Result);
- Windows.FindClose(Handle);
- end;
- end;
-begin
- //Song Overview
-
- //Introduction
- Formatstr := Language.Translate ('STAT_OVERVIEW_INTRO');
- {Format:
- %0:d Ultrastar Version
- %1:d Day of Reset (A1)
- %2:d Month of Reset (A2)
- %3:d Year of Reset (A3)}
-
- ResetTime := GetFileCreation(Database.Filename);
-
- A1 := ResetTime.wDay;
- A2 := ResetTime.wMonth;
- A3 := ResetTime.wYear;
- try
- Overview := Format(Formatstr, [Language.Translate('US_VERSION'), A1, A2, A3]);
- except
- on E: EConvertError do
- Log.LogError('Error Parsing FormatString "STAT_OVERVIEW_INTRO": ' + E.Message);
- end;
-
- Formatstr := Language.Translate ('STAT_OVERVIEW_SONG');
- {Format:
- %0:d Count Songs (A1)
- %1:d Count of Sung Songs (A2)
- %2:d Count of UnSung Songs
- %3:d Count of Songs with Video (A3)
- %4:s Name of the most popular Song}
- A1 := Length(Songs.Song);
- A2 := Database.GetTotalEntrys(2);
-
- A3 := SongswithVid;
-
- SetLength(Result1, 1);
- Database.GetStats(Result1, 2, 1, 0, False);
- A4 := Result1[0].Artist;
- A5 := Result1[0].Title;
-
- try
- Overview := Overview + '\n \n' + Format(Formatstr, [A1, A2, A1-A2, A3, A4, A5]);
- except
- on E: EConvertError do
- Log.LogError('Error Parsing FormatString "STAT_OVERVIEW_SONG": ' + E.Message);
- end;
-
- //Player Overview
- Formatstr := Language.Translate ('STAT_OVERVIEW_PLAYER');
- {Format:
- %0:d Count Players (A1)
- %1:s Best Player (Result)
- %2:d Best Players Score
- %3:s Best Score Player (Result2)
- %4:d Best Score}
- A1 := Database.GetTotalEntrys(1);
-
- SetLength(Result1, 1);
- Database.GetStats(Result1, 1, 1, 0, False);
-
- SetLength(Result2, 1);
- Database.GetStats(Result2, 0, 1, 0, False);
-
- try
- Overview := Overview + '\n \n' + Format(Formatstr, [A1, Result1[0].Player, Result1[0].AverageScore, Result2[0].Singer, Result2[0].Score]);
- except
- on E: EConvertError do
- Log.LogError('Error Parsing FormatString "STAT_OVERVIEW_PLAYER": ' + E.Message);
- end;
-
- Text[0].Text := Overview;
-end;
-
-
-procedure TScreenStatMain.SetAnimationProgress(Progress: real);
-var I: Integer;
-begin
- For I := 0 to high(Button) do
- Button[I].Texture.ScaleW := Progress;
-end;
-
-end.
+unit UScreenStatMain;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE DELPHI}
+{$ENDIF}
+
+
+uses
+ UMenu,
+ SDL,
+ SysUtils,
+ UDisplay,
+ UMusic,
+ UIni,
+ UThemes;
+
+type
+ TScreenStatMain = class(TMenu)
+ private
+ //Some Stat Value that don't need to be calculated 2 times
+ SongswithVid: Cardinal;
+ public
+ TextOverview: integer;
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+
+ procedure SetOverview;
+ end;
+
+implementation
+
+uses UGraphic,
+ UDataBase,
+ USongs,
+ ULanguage,
+ UCommon,
+ {$IFDEF win32}
+ windows,
+ {$ELSE}
+ sysconst,
+ {$ENDIF}
+ ULog;
+
+function TScreenStatMain.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+
+ SDLK_ESCAPE,
+ SDLK_BACKSPACE :
+ begin
+ Ini.Save;
+ Music.PlayBack;
+ FadeTo(@ScreenMain);
+ end;
+ SDLK_RETURN:
+ begin
+ //Exit Button Pressed
+ if Interaction = 4 then begin
+ Music.PlayBack;
+ FadeTo(@ScreenMain);
+ end
+ else //One of the Stats Buttons Pressed
+ begin
+ Music.PlayBack;
+ ScreenStatDetail.Typ := Interaction;
+ FadeTo(@ScreenStatDetail);
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ InteractPrev;
+ end;
+ SDLK_RIGHT:
+ begin
+ InteractNext;
+ end;
+ SDLK_UP:
+ begin
+ InteractPrev;
+ end;
+ SDLK_DOWN:
+ begin
+ InteractNext;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenStatMain.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ TextOverview := AddText(Theme.StatMain.TextOverview);
+
+ LoadFromTheme(Theme.StatMain);
+
+ AddButton(Theme.StatMain.ButtonScores);
+ if (Length(Button[0].Text)=0) then
+ AddButtonText(14, 20, Theme.StatDetail.Description[0]);
+
+ AddButton(Theme.StatMain.ButtonSingers);
+ if (Length(Button[1].Text)=0) then
+ AddButtonText(14, 20, Theme.StatDetail.Description[1]);
+
+ AddButton(Theme.StatMain.ButtonSongs);
+ if (Length(Button[2].Text)=0) then
+ AddButtonText(14, 20, Theme.StatDetail.Description[2]);
+
+ AddButton(Theme.StatMain.ButtonBands);
+ if (Length(Button[3].Text)=0) then
+ AddButtonText(14, 20, Theme.StatDetail.Description[3]);
+
+ AddButton(Theme.StatMain.ButtonExit);
+ if (Length(Button[4].Text)=0) then
+ AddButtonText(14, 20, Theme.Options.Description[4]);
+
+ Interaction := 0;
+
+ //Set Songs with Vid
+ SongswithVid := 0;
+ For I := 0 to high(Songs.Song) do
+ if (Songs.Song[I].Video <> '') then
+ Inc(SongswithVid);
+end;
+
+procedure TScreenStatMain.onShow;
+begin
+ //Set Overview Text:
+ SetOverview;
+end;
+
+procedure TScreenStatMain.SetOverview;
+type
+ TwSystemTime = record
+ wYear,
+ wMonth,
+ wDayOfWeek,
+ wDay,
+ wHour,
+ wMinute,
+ wSecond,
+ wMilliseconds: Word;
+ end;
+var
+ Overview, Formatstr: String;
+ I: Integer;
+ //Some Vars to Save Attributes to
+ A1, A2, A3: Integer;
+ A4, A5: String;
+ Result1, Result2: AStatResult;
+ ResetTime: TSystemTime;
+
+ {$IFDEF win32}
+ function GetFileCreation(Filename: String): TSystemTime;
+ var
+ FindData: TWin32FindData;
+ Handle: THandle;
+ begin
+ Handle := FindFirstFile(PChar(Filename), FindData);
+ if Handle <> INVALID_HANDLE_VALUE then
+ begin
+ FileTimeToSystemTime(FindData.ftCreationTime, Result);
+ windows.FindClose(Handle);
+ end;
+ end;
+
+ {$ELSE}
+
+ function GetFileCreation(Filename: String): TSystemTime;
+ Var
+ F,D : Longint;
+ Begin
+ F:=FileCreate( Filename );
+ try
+ D:=FileGetDate(F);
+ DateTimeToSystemTime( FileDateToDateTime(D) , result);
+ finally
+ FileClose(F);
+ end;
+ end;
+ {$ENDIF}
+
+begin
+ //Song Overview
+
+ //Introduction
+ Formatstr := Language.Translate ('STAT_OVERVIEW_INTRO');
+ (*Format:
+ %0:d Ultrastar Version
+ %1:d Day of Reset (A1)
+ %2:d Month of Reset (A2)
+ %3:d Year of Reset (A3)*)
+
+ ResetTime := GetFileCreation(Database.Filename);
+
+ {$IFDEF win32}
+ A1 := ResetTime.wDay;
+ A2 := ResetTime.wMonth;
+ A3 := ResetTime.wYear;
+ {$ELSE}
+ A1 := ResetTime.Day;
+ A2 := ResetTime.Month;
+ A3 := ResetTime.Year;
+ {$ENDIF}
+
+
+ try
+ Overview := Format(Formatstr, [Language.Translate('US_VERSION'), A1, A2, A3]);
+ except
+ on E: EConvertError do
+ Log.LogError('Error Parsing FormatString "STAT_OVERVIEW_INTRO": ' + E.Message);
+ end;
+
+ Formatstr := Language.Translate ('STAT_OVERVIEW_SONG');
+ {Format:
+ %0:d Count Songs (A1)
+ %1:d Count of Sung Songs (A2)
+ %2:d Count of UnSung Songs
+ %3:d Count of Songs with Video (A3)
+ %4:s Name of the most popular Song}
+ A1 := Length(Songs.Song);
+ A2 := Database.GetTotalEntrys(2);
+
+ A3 := SongswithVid;
+
+ SetLength(Result1, 1);
+ Database.GetStats(Result1, 2, 1, 0, False);
+ A4 := Result1[0].Artist;
+ A5 := Result1[0].Title;
+
+ try
+ Overview := Overview + '\n \n' + Format(Formatstr, [A1, A2, A1-A2, A3, A4, A5]);
+ except
+ on E: EConvertError do
+ Log.LogError('Error Parsing FormatString "STAT_OVERVIEW_SONG": ' + E.Message);
+ end;
+
+ //Player Overview
+ Formatstr := Language.Translate ('STAT_OVERVIEW_PLAYER');
+ {Format:
+ %0:d Count Players (A1)
+ %1:s Best Player (Result)
+ %2:d Best Players Score
+ %3:s Best Score Player (Result2)
+ %4:d Best Score}
+ A1 := Database.GetTotalEntrys(1);
+
+ SetLength(Result1, 1);
+ Database.GetStats(Result1, 1, 1, 0, False);
+
+ SetLength(Result2, 1);
+ Database.GetStats(Result2, 0, 1, 0, False);
+
+ try
+ Overview := Overview + '\n \n' + Format(Formatstr, [A1, Result1[0].Player, Result1[0].AverageScore, Result2[0].Singer, Result2[0].Score]);
+ except
+ on E: EConvertError do
+ Log.LogError('Error Parsing FormatString "STAT_OVERVIEW_PLAYER": ' + E.Message);
+ end;
+
+ Text[0].Text := Overview;
+end;
+
+
+procedure TScreenStatMain.SetAnimationProgress(Progress: real);
+var I: Integer;
+begin
+ For I := 0 to high(Button) do
+ Button[I].Texture.ScaleW := Progress;
+end;
+
+end.
diff --git a/Game/Code/UltraStar.lpi b/Game/Code/UltraStar.lpi
index 84980b53..97a25a66 100644
--- a/Game/Code/UltraStar.lpi
+++ b/Game/Code/UltraStar.lpi
@@ -12,7 +12,7 @@
<MainUnit Value="0"/>
<IconPath Value="./"/>
<TargetFileExt Value=".exe"/>
- <ActiveEditorIndexAtStart Value="5"/>
+ <ActiveEditorIndexAtStart Value="1"/>
</General>
<VersionInfo>
<ProjectVersion Value=""/>
@@ -36,62 +36,62 @@
<PackageName Value="ImagesForLazarus"/>
</Item1>
</RequiredPackages>
- <Units Count="60">
+ <Units Count="71">
<Unit0>
<Filename Value="UltraStar.lpr"/>
<IsPartOfProject Value="True"/>
- <CursorPos X="18" Y="36"/>
- <TopLine Value="11"/>
+ <CursorPos X="36" Y="106"/>
+ <TopLine Value="85"/>
<EditorIndex Value="0"/>
- <UsageCount Value="72"/>
+ <UsageCount Value="86"/>
<Loaded Value="True"/>
</Unit0>
<Unit1>
<Filename Value="lib/JEDI-SDLv1.0/OpenGL/Pas/opengl12.pas"/>
<UnitName Value="opengl12"/>
- <CursorPos X="2" Y="256"/>
- <TopLine Value="236"/>
- <UsageCount Value="6"/>
+ <CursorPos X="10" Y="269"/>
+ <TopLine Value="248"/>
+ <UsageCount Value="10"/>
</Unit1>
<Unit2>
<Filename Value="Classes/UTexture.pas"/>
<UnitName Value="UTexture"/>
- <CursorPos X="36" Y="458"/>
- <TopLine Value="883"/>
- <EditorIndex Value="14"/>
- <UsageCount Value="12"/>
- <Loaded Value="True"/>
+ <CursorPos X="7" Y="23"/>
+ <TopLine Value="2"/>
+ <UsageCount Value="16"/>
</Unit2>
<Unit3>
<Filename Value="Classes/UCommandLine.pas"/>
<UnitName Value="UCommandLine"/>
<CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
- <UsageCount Value="33"/>
+ <UsageCount Value="32"/>
</Unit3>
<Unit4>
<Filename Value="Classes/UIni.pas"/>
<UnitName Value="UIni"/>
- <CursorPos X="9" Y="7"/>
+ <CursorPos X="52" Y="33"/>
<TopLine Value="1"/>
- <UsageCount Value="33"/>
+ <EditorIndex Value="1"/>
+ <UsageCount Value="32"/>
+ <Loaded Value="True"/>
</Unit4>
<Unit5>
<Filename Value="Classes/ULog.pas"/>
<UnitName Value="ULog"/>
- <CursorPos X="41" Y="204"/>
- <TopLine Value="186"/>
- <EditorIndex Value="9"/>
- <UsageCount Value="11"/>
+ <CursorPos X="5" Y="5"/>
+ <TopLine Value="13"/>
+ <EditorIndex Value="6"/>
+ <UsageCount Value="12"/>
<Loaded Value="True"/>
</Unit5>
<Unit6>
<Filename Value="Classes/UFiles.pas"/>
<UnitName Value="UFiles"/>
- <CursorPos X="8" Y="132"/>
- <TopLine Value="96"/>
- <EditorIndex Value="12"/>
- <UsageCount Value="12"/>
+ <CursorPos X="9" Y="56"/>
+ <TopLine Value="46"/>
+ <EditorIndex Value="3"/>
+ <UsageCount Value="11"/>
<Loaded Value="True"/>
</Unit6>
<Unit7>
@@ -99,26 +99,28 @@
<UnitName Value="USongs"/>
<CursorPos X="57" Y="115"/>
<TopLine Value="91"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="5"/>
</Unit7>
<Unit8>
<Filename Value="../../../../../lazarus/fpc/2.0.4/source/rtl/objpas/sysutils/sysinth.inc"/>
<CursorPos X="3" Y="95"/>
<TopLine Value="75"/>
- <UsageCount Value="5"/>
+ <UsageCount Value="4"/>
</Unit8>
<Unit9>
<Filename Value="Classes/UMain.pas"/>
<UnitName Value="UMain"/>
- <CursorPos X="5" Y="9"/>
- <TopLine Value="1"/>
+ <CursorPos X="99" Y="785"/>
+ <TopLine Value="595"/>
+ <EditorIndex Value="4"/>
<UsageCount Value="10"/>
+ <Loaded Value="True"/>
</Unit9>
<Unit10>
<Filename Value="Classes/UGraphic.pas"/>
<UnitName Value="UGraphic"/>
- <CursorPos X="3" Y="56"/>
- <TopLine Value="19"/>
+ <CursorPos X="8" Y="245"/>
+ <TopLine Value="224"/>
<UsageCount Value="33"/>
</Unit10>
<Unit11>
@@ -126,169 +128,170 @@
<UnitName Value="UThemes"/>
<CursorPos X="29" Y="1746"/>
<TopLine Value="1691"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
</Unit11>
<Unit12>
<Filename Value="Classes/UCovers.pas"/>
<UnitName Value="UCovers"/>
- <CursorPos X="12" Y="7"/>
+ <CursorPos X="7" Y="11"/>
<TopLine Value="1"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="11"/>
</Unit12>
<Unit13>
<Filename Value="Classes/UMusic.pas"/>
<UnitName Value="UMusic"/>
- <CursorPos X="46" Y="219"/>
- <TopLine Value="198"/>
- <UsageCount Value="10"/>
+ <CursorPos X="1" Y="14"/>
+ <TopLine Value="1"/>
+ <UsageCount Value="15"/>
</Unit13>
<Unit14>
<Filename Value="Classes/ULyrics.pas"/>
<UnitName Value="ULyrics"/>
<CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="5"/>
</Unit14>
<Unit15>
<Filename Value="Screens/UScreenLoading.pas"/>
<UnitName Value="UScreenLoading"/>
<CursorPos X="8" Y="6"/>
<TopLine Value="1"/>
- <UsageCount Value="6"/>
+ <UsageCount Value="5"/>
</Unit15>
<Unit16>
<Filename Value="Menu/UMenu.pas"/>
<UnitName Value="UMenu"/>
<CursorPos X="1" Y="8"/>
<TopLine Value="1"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
</Unit16>
<Unit17>
<Filename Value="Menu/UMenuText.pas"/>
<UnitName Value="UMenuText"/>
- <CursorPos X="1" Y="8"/>
- <TopLine Value="1"/>
- <UsageCount Value="6"/>
+ <CursorPos X="14" Y="60"/>
+ <TopLine Value="37"/>
+ <UsageCount Value="11"/>
</Unit17>
<Unit18>
<Filename Value="Menu/UMenuSelectSlide.pas"/>
<UnitName Value="UMenuSelectSlide"/>
<CursorPos X="6" Y="12"/>
<TopLine Value="2"/>
- <UsageCount Value="5"/>
+ <UsageCount Value="4"/>
</Unit18>
<Unit19>
<Filename Value="Screens/UScreenMain.pas"/>
<UnitName Value="UScreenMain"/>
- <CursorPos X="3" Y="14"/>
- <TopLine Value="1"/>
- <UsageCount Value="32"/>
+ <CursorPos X="13" Y="37"/>
+ <TopLine Value="16"/>
+ <UsageCount Value="31"/>
</Unit19>
<Unit20>
<Filename Value="Menu/UDisplay.pas"/>
<UnitName Value="UDisplay"/>
- <CursorPos X="7" Y="65"/>
- <TopLine Value="165"/>
- <EditorIndex Value="13"/>
- <UsageCount Value="12"/>
- <Loaded Value="True"/>
+ <CursorPos X="54" Y="21"/>
+ <TopLine Value="1"/>
+ <UsageCount Value="14"/>
</Unit20>
<Unit21>
<Filename Value="Classes/ULight.pas"/>
<UnitName Value="ULight"/>
- <CursorPos X="81" Y="55"/>
- <TopLine Value="51"/>
- <UsageCount Value="5"/>
+ <CursorPos X="1" Y="1"/>
+ <TopLine Value="13"/>
+ <UsageCount Value="10"/>
+ <Bookmarks Count="1">
+ <Item0 X="19" Y="66" ID="1"/>
+ </Bookmarks>
</Unit21>
<Unit22>
<Filename Value="Screens/UScreenSing.pas"/>
<UnitName Value="UScreenSing"/>
- <CursorPos X="40" Y="21"/>
- <TopLine Value="1"/>
- <UsageCount Value="11"/>
+ <CursorPos X="1" Y="1027"/>
+ <TopLine Value="1006"/>
+ <UsageCount Value="10"/>
</Unit22>
<Unit23>
<Filename Value="Classes/UVideo.pas"/>
<UnitName Value="UVideo"/>
<CursorPos X="1" Y="8"/>
<TopLine Value="2"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="10"/>
</Unit23>
<Unit24>
<Filename Value="Screens/UScreenScore.pas"/>
<UnitName Value="UScreenScore"/>
<CursorPos X="9" Y="7"/>
<TopLine Value="1"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="10"/>
</Unit24>
<Unit25>
<Filename Value="Screens/UScreenEditSub.pas"/>
<UnitName Value="UScreenEditSub"/>
<CursorPos X="11" Y="1339"/>
<TopLine Value="1330"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="10"/>
</Unit25>
<Unit26>
<Filename Value="switches.inc"/>
- <CursorPos X="10" Y="3"/>
+ <CursorPos X="19" Y="12"/>
<TopLine Value="1"/>
- <UsageCount Value="5"/>
+ <UsageCount Value="11"/>
</Unit26>
<Unit27>
<Filename Value="lib/midi/Midiout.pas"/>
<UnitName Value="MidiOut"/>
<CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
</Unit27>
<Unit28>
<Filename Value="Screens/UScreenEditConvert.pas"/>
<UnitName Value="UScreenEditConvert"/>
<CursorPos X="22" Y="26"/>
<TopLine Value="1"/>
- <EditorIndex Value="10"/>
- <UsageCount Value="33"/>
- <Loaded Value="True"/>
+ <UsageCount Value="32"/>
</Unit28>
<Unit29>
<Filename Value="Screens/UScreenSingModi.pas"/>
<UnitName Value="UScreenSingModi"/>
- <CursorPos X="6" Y="26"/>
- <TopLine Value="6"/>
- <UsageCount Value="32"/>
+ <CursorPos X="1" Y="24"/>
+ <TopLine Value="1"/>
+ <UsageCount Value="31"/>
</Unit29>
<Unit30>
<Filename Value="Screens/UScreenCredits.pas"/>
<UnitName Value="UScreenCredits"/>
- <CursorPos X="1" Y="1"/>
- <TopLine Value="1"/>
+ <CursorPos X="13" Y="119"/>
+ <TopLine Value="98"/>
<UsageCount Value="32"/>
</Unit30>
<Unit31>
<Filename Value="Classes/URecord.pas"/>
<UnitName Value="URecord"/>
- <CursorPos X="1" Y="1"/>
- <TopLine Value="1"/>
- <UsageCount Value="32"/>
+ <CursorPos X="21" Y="293"/>
+ <TopLine Value="271"/>
+ <UsageCount Value="31"/>
</Unit31>
<Unit32>
<Filename Value="lib/JEDI-SDLv1.0/SDL/Pas/jedi-sdl.inc"/>
<CursorPos X="4" Y="237"/>
<TopLine Value="217"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="10"/>
</Unit32>
<Unit33>
<Filename Value="../../Modis/SDK/ModiSDK.pas"/>
<UnitName Value="ModiSDK"/>
- <CursorPos X="41" Y="8"/>
- <TopLine Value="1"/>
- <UsageCount Value="32"/>
+ <CursorPos X="79" Y="145"/>
+ <TopLine Value="104"/>
+ <EditorIndex Value="2"/>
+ <UsageCount Value="31"/>
+ <Loaded Value="True"/>
</Unit33>
<Unit34>
<Filename Value="Classes/UDLLManager.pas"/>
<UnitName Value="UDLLManager"/>
- <CursorPos X="12" Y="5"/>
- <TopLine Value="1"/>
+ <CursorPos X="7" Y="56"/>
+ <TopLine Value="25"/>
<UsageCount Value="32"/>
</Unit34>
<Unit35>
@@ -296,76 +299,79 @@
<UnitName Value="UPlaylist"/>
<CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
- <UsageCount Value="32"/>
+ <UsageCount Value="31"/>
</Unit35>
<Unit36>
<Filename Value="Classes/UDataBase.pas"/>
<UnitName Value="UDataBase"/>
- <CursorPos X="1" Y="8"/>
- <TopLine Value="1"/>
- <UsageCount Value="32"/>
+ <CursorPos X="10" Y="211"/>
+ <TopLine Value="189"/>
+ <UsageCount Value="31"/>
</Unit36>
<Unit37>
<Filename Value="Screens/UScreenStatMain.pas"/>
<UnitName Value="UScreenStatMain"/>
- <CursorPos X="1" Y="8"/>
- <TopLine Value="1"/>
+ <CursorPos X="76" Y="167"/>
+ <TopLine Value="155"/>
<UsageCount Value="32"/>
+ <Bookmarks Count="1">
+ <Item0 X="21" Y="216" ID="1"/>
+ </Bookmarks>
</Unit37>
<Unit38>
<Filename Value="Screens/UScreenPartyOptions.pas"/>
<UnitName Value="UScreenPartyOptions"/>
<CursorPos X="42" Y="233"/>
<TopLine Value="213"/>
- <UsageCount Value="32"/>
+ <UsageCount Value="31"/>
</Unit38>
<Unit39>
<Filename Value="Screens/UScreenPartyNewRound.pas"/>
<UnitName Value="UScreenPartyNewRound"/>
<CursorPos X="5" Y="422"/>
<TopLine Value="382"/>
- <UsageCount Value="32"/>
+ <UsageCount Value="31"/>
</Unit39>
<Unit40>
<Filename Value="Classes/UParty.pas"/>
<UnitName Value="UParty"/>
<CursorPos X="1" Y="8"/>
<TopLine Value="1"/>
- <UsageCount Value="32"/>
+ <UsageCount Value="31"/>
</Unit40>
<Unit41>
<Filename Value="Classes/UDraw.pas"/>
<UnitName Value="UDraw"/>
- <CursorPos X="1" Y="1"/>
- <TopLine Value="1"/>
- <UsageCount Value="32"/>
+ <CursorPos X="7" Y="67"/>
+ <TopLine Value="43"/>
+ <UsageCount Value="31"/>
</Unit41>
<Unit42>
<Filename Value="Screens/UScreenSongMenu.pas"/>
<UnitName Value="UScreenSongMenu"/>
- <CursorPos X="1" Y="5"/>
+ <CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
- <UsageCount Value="32"/>
+ <UsageCount Value="31"/>
</Unit42>
<Unit43>
<Filename Value="Screens/UScreenTop5.pas"/>
<UnitName Value="UScreenTop5"/>
<CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="10"/>
</Unit43>
<Unit44>
<Filename Value="Classes/UGraphicClasses.pas"/>
<UnitName Value="UGraphicClasses"/>
- <CursorPos X="1" Y="1"/>
+ <CursorPos X="1" Y="7"/>
<TopLine Value="1"/>
<UsageCount Value="11"/>
</Unit44>
<Unit45>
<Filename Value="Screens/UScreenSong.pas"/>
<UnitName Value="UScreenSong"/>
- <CursorPos X="13" Y="1162"/>
- <TopLine Value="1135"/>
+ <CursorPos X="13" Y="126"/>
+ <TopLine Value="105"/>
<UsageCount Value="10"/>
</Unit45>
<Unit46>
@@ -373,217 +379,305 @@
<UnitName Value="Delphmcb"/>
<CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
</Unit46>
<Unit47>
<Filename Value="Classes/UCommon.pas"/>
<UnitName Value="UCommon"/>
- <CursorPos X="55" Y="22"/>
- <TopLine Value="7"/>
- <UsageCount Value="10"/>
+ <CursorPos X="3" Y="75"/>
+ <TopLine Value="34"/>
+ <EditorIndex Value="10"/>
+ <UsageCount Value="14"/>
+ <Loaded Value="True"/>
</Unit47>
<Unit48>
<Filename Value="../../../../../lazarus/fpc/2.0.4/source/rtl/objpas/math.pp"/>
<UnitName Value="math"/>
<CursorPos X="1" Y="1041"/>
<TopLine Value="1036"/>
- <UsageCount Value="10"/>
+ <UsageCount Value="9"/>
</Unit48>
<Unit49>
<Filename Value="Classes/Ulazjpeg.pas"/>
<UnitName Value="Ulazjpeg"/>
<CursorPos X="44" Y="15"/>
<TopLine Value="63"/>
- <UsageCount Value="12"/>
+ <UsageCount Value="11"/>
</Unit49>
<Unit50>
<Filename Value="Classes/TextGL.pas"/>
<UnitName Value="TextGL"/>
- <CursorPos X="36" Y="372"/>
- <TopLine Value="335"/>
- <EditorIndex Value="11"/>
- <UsageCount Value="11"/>
- <Bookmarks Count="1">
- <Item0 X="1" Y="124" ID="1"/>
- </Bookmarks>
- <Loaded Value="True"/>
+ <CursorPos X="7" Y="64"/>
+ <TopLine Value="43"/>
+ <UsageCount Value="13"/>
</Unit50>
<Unit51>
<Filename Value="UltraStar.lrs"/>
<CursorPos X="17" Y="1"/>
<TopLine Value="1"/>
- <UsageCount Value="11"/>
+ <UsageCount Value="10"/>
</Unit51>
<Unit52>
<Filename Value="lib/JEDI-SDLv1.0/SDL/Pas/moduleloader.pas"/>
<UnitName Value="moduleloader"/>
- <CursorPos X="1" Y="1"/>
- <TopLine Value="1"/>
- <EditorIndex Value="8"/>
+ <CursorPos X="10" Y="64"/>
+ <TopLine Value="55"/>
<UsageCount Value="10"/>
- <Loaded Value="True"/>
</Unit52>
<Unit53>
<Filename Value="lib/bass/delphi/bass.pas"/>
<UnitName Value="Bass"/>
<CursorPos X="1" Y="1"/>
<TopLine Value="1"/>
- <EditorIndex Value="7"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
+ <UsageCount Value="9"/>
</Unit53>
<Unit54>
<Filename Value="lib/ffmpeg/avcodec.pas"/>
<UnitName Value="avcodec"/>
- <CursorPos X="1" Y="31"/>
- <TopLine Value="1"/>
- <EditorIndex Value="1"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
+ <CursorPos X="69" Y="1519"/>
+ <TopLine Value="1492"/>
+ <UsageCount Value="12"/>
</Unit54>
<Unit55>
<Filename Value="lib/ffmpeg/rational.pas"/>
<UnitName Value="rational"/>
<CursorPos X="40" Y="33"/>
<TopLine Value="1"/>
- <EditorIndex Value="2"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
+ <UsageCount Value="12"/>
</Unit55>
<Unit56>
<Filename Value="lib/ffmpeg/opt.pas"/>
<UnitName Value="opt"/>
<CursorPos X="37" Y="46"/>
<TopLine Value="17"/>
- <EditorIndex Value="3"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
+ <UsageCount Value="9"/>
</Unit56>
<Unit57>
<Filename Value="lib/ffmpeg/avformat.pas"/>
<UnitName Value="avformat"/>
<CursorPos X="10" Y="357"/>
<TopLine Value="335"/>
- <EditorIndex Value="4"/>
- <UsageCount Value="10"/>
- <Loaded Value="True"/>
+ <UsageCount Value="9"/>
</Unit57>
<Unit58>
<Filename Value="lib/ffmpeg/avio.pas"/>
<UnitName Value="avio"/>
<CursorPos X="1" Y="34"/>
<TopLine Value="1"/>
- <EditorIndex Value="6"/>
<UsageCount Value="10"/>
- <Loaded Value="True"/>
</Unit58>
<Unit59>
<Filename Value="lib/SQLite/SQLiteTable3.pas"/>
<UnitName Value="SQLiteTable3"/>
<CursorPos X="24" Y="16"/>
<TopLine Value="2"/>
+ <UsageCount Value="9"/>
+ </Unit59>
+ <Unit60>
+ <Filename Value="Menu/UMenuButton.pas"/>
+ <UnitName Value="UMenuButton"/>
+ <CursorPos X="13" Y="90"/>
+ <TopLine Value="69"/>
+ <UsageCount Value="11"/>
+ </Unit60>
+ <Unit61>
+ <Filename Value="Classes/UTime.pas"/>
+ <UnitName Value="UTime"/>
+ <CursorPos X="41" Y="44"/>
+ <TopLine Value="35"/>
+ <EditorIndex Value="7"/>
+ <UsageCount Value="14"/>
+ <Loaded Value="True"/>
+ </Unit61>
+ <Unit62>
+ <Filename Value="Classes/UJoystick.pas"/>
+ <UnitName Value="UJoystick"/>
+ <CursorPos X="1" Y="6"/>
+ <TopLine Value="1"/>
+ <UsageCount Value="11"/>
+ </Unit62>
+ <Unit63>
+ <Filename Value="Classes/ULanguage.pas"/>
+ <UnitName Value="ULanguage"/>
+ <CursorPos X="29" Y="106"/>
+ <TopLine Value="96"/>
<EditorIndex Value="5"/>
+ <UsageCount Value="11"/>
+ <Loaded Value="True"/>
+ </Unit63>
+ <Unit64>
+ <Filename Value="/usr/share/fpcsrc/rtl/unix/sysutils.pp"/>
+ <UnitName Value="sysutils"/>
+ <CursorPos X="7" Y="93"/>
+ <TopLine Value="72"/>
+ <UsageCount Value="10"/>
+ </Unit64>
+ <Unit65>
+ <Filename Value="/usr/share/fpcsrc/rtl/objpas/sysutils/sysutilh.inc"/>
+ <CursorPos X="45" Y="30"/>
+ <TopLine Value="13"/>
<UsageCount Value="10"/>
+ </Unit65>
+ <Unit66>
+ <Filename Value="/usr/share/fpcsrc/rtl/objpas/sysutils/sysutils.inc"/>
+ <CursorPos X="86" Y="90"/>
+ <TopLine Value="73"/>
+ <UsageCount Value="10"/>
+ </Unit66>
+ <Unit67>
+ <Filename Value="Classes/ULCD.pas"/>
+ <UnitName Value="ULCD"/>
+ <CursorPos X="1" Y="1"/>
+ <TopLine Value="1"/>
+ <UsageCount Value="10"/>
+ </Unit67>
+ <Unit68>
+ <Filename Value="lib/JEDI-SDLv1.0/SDL/Pas/sdl.pas"/>
+ <UnitName Value="sdl"/>
+ <CursorPos X="52" Y="2092"/>
+ <TopLine Value="2071"/>
+ <UsageCount Value="10"/>
+ </Unit68>
+ <Unit69>
+ <Filename Value="/usr/share/fpcsrc/packages/base/libc/libc.pp"/>
+ <UnitName Value="libc"/>
+ <CursorPos X="7" Y="41"/>
+ <TopLine Value="19"/>
+ <EditorIndex Value="9"/>
+ <UsageCount Value="11"/>
<Loaded Value="True"/>
- </Unit59>
+ </Unit69>
+ <Unit70>
+ <Filename Value="/usr/share/fpcsrc/fv/time.pas"/>
+ <UnitName Value="Time"/>
+ <CursorPos X="3" Y="222"/>
+ <TopLine Value="424"/>
+ <EditorIndex Value="8"/>
+ <UsageCount Value="11"/>
+ <Loaded Value="True"/>
+ </Unit70>
</Units>
- <JumpHistory Count="24" HistoryIndex="23">
+ <JumpHistory Count="30" HistoryIndex="29">
<Position1>
<Filename Value="UltraStar.lpr"/>
- <Caret Line="72" Column="32" TopLine="52"/>
+ <Caret Line="1" Column="1" TopLine="1"/>
</Position1>
<Position2>
- <Filename Value="UltraStar.lpr"/>
- <Caret Line="1" Column="1" TopLine="1"/>
+ <Filename Value="Classes/UTime.pas"/>
+ <Caret Line="23" Column="97" TopLine="13"/>
</Position2>
<Position3>
<Filename Value="UltraStar.lpr"/>
- <Caret Line="66" Column="30" TopLine="44"/>
+ <Caret Line="193" Column="64" TopLine="180"/>
</Position3>
<Position4>
- <Filename Value="lib/JEDI-SDLv1.0/SDL/Pas/moduleloader.pas"/>
+ <Filename Value="UltraStar.lpr"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position4>
<Position5>
- <Filename Value="UltraStar.lpr"/>
- <Caret Line="16" Column="68" TopLine="1"/>
+ <Filename Value="Classes/UCommon.pas"/>
+ <Caret Line="82" Column="96" TopLine="39"/>
</Position5>
<Position6>
- <Filename Value="lib/bass/delphi/bass.pas"/>
+ <Filename Value="Classes/UCommon.pas"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position6>
<Position7>
- <Filename Value="lib/bass/delphi/bass.pas"/>
- <Caret Line="25" Column="55" TopLine="1"/>
+ <Filename Value="UltraStar.lpr"/>
+ <Caret Line="98" Column="41" TopLine="77"/>
</Position7>
<Position8>
- <Filename Value="lib/bass/delphi/bass.pas"/>
- <Caret Line="968" Column="1" TopLine="925"/>
+ <Filename Value="UltraStar.lpr"/>
+ <Caret Line="1" Column="1" TopLine="1"/>
</Position8>
<Position9>
- <Filename Value="lib/bass/delphi/bass.pas"/>
- <Caret Line="957" Column="115" TopLine="925"/>
+ <Filename Value="Classes/UTime.pas"/>
+ <Caret Line="36" Column="6" TopLine="13"/>
</Position9>
<Position10>
- <Filename Value="lib/ffmpeg/avcodec.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
+ <Filename Value="/usr/share/fpcsrc/packages/base/libc/libc.pp"/>
+ <Caret Line="12" Column="105" TopLine="1"/>
</Position10>
<Position11>
- <Filename Value="lib/ffmpeg/rational.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
+ <Filename Value="/usr/share/fpcsrc/packages/base/libc/libc.pp"/>
+ <Caret Line="39" Column="15" TopLine="18"/>
</Position11>
<Position12>
- <Filename Value="UltraStar.lpr"/>
- <Caret Line="41" Column="11" TopLine="2"/>
+ <Filename Value="Classes/UTime.pas"/>
+ <Caret Line="37" Column="5" TopLine="13"/>
</Position12>
<Position13>
- <Filename Value="UltraStar.lpr"/>
- <Caret Line="1" Column="1" TopLine="1"/>
+ <Filename Value="/usr/share/fpcsrc/fv/time.pas"/>
+ <Caret Line="12" Column="46" TopLine="181"/>
</Position13>
<Position14>
- <Filename Value="lib/ffmpeg/opt.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
+ <Filename Value="Classes/UTime.pas"/>
+ <Caret Line="109" Column="109" TopLine="87"/>
</Position14>
<Position15>
- <Filename Value="lib/ffmpeg/avformat.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
+ <Filename Value="Classes/ULog.pas"/>
+ <Caret Line="57" Column="7" TopLine="36"/>
</Position15>
<Position16>
- <Filename Value="lib/ffmpeg/avio.pas"/>
- <Caret Line="1" Column="1" TopLine="1"/>
+ <Filename Value="UltraStar.lpr"/>
+ <Caret Line="123" Column="88" TopLine="101"/>
</Position16>
<Position17>
- <Filename Value="lib/ffmpeg/avformat.pas"/>
- <Caret Line="29" Column="10" TopLine="4"/>
+ <Filename Value="UltraStar.lpr"/>
+ <Caret Line="7" Column="26" TopLine="1"/>
</Position17>
<Position18>
- <Filename Value="lib/ffmpeg/avformat.pas"/>
- <Caret Line="401" Column="27" TopLine="336"/>
+ <Filename Value="Classes/ULanguage.pas"/>
+ <Caret Line="53" Column="56" TopLine="30"/>
</Position18>
<Position19>
- <Filename Value="lib/ffmpeg/avformat.pas"/>
- <Caret Line="41" Column="1" TopLine="1"/>
+ <Filename Value="Classes/ULanguage.pas"/>
+ <Caret Line="64" Column="22" TopLine="48"/>
</Position19>
<Position20>
- <Filename Value="lib/ffmpeg/avformat.pas"/>
- <Caret Line="422" Column="34" TopLine="280"/>
+ <Filename Value="Classes/ULanguage.pas"/>
+ <Caret Line="1" Column="1" TopLine="1"/>
</Position20>
<Position21>
- <Filename Value="lib/ffmpeg/avformat.pas"/>
- <Caret Line="30" Column="10" TopLine="6"/>
+ <Filename Value="UltraStar.lpr"/>
+ <Caret Line="108" Column="47" TopLine="87"/>
</Position21>
<Position22>
- <Filename Value="lib/ffmpeg/avformat.pas"/>
- <Caret Line="416" Column="1" TopLine="584"/>
+ <Filename Value="UltraStar.lpr"/>
+ <Caret Line="1" Column="1" TopLine="1"/>
</Position22>
<Position23>
- <Filename Value="lib/ffmpeg/avformat.pas"/>
- <Caret Line="355" Column="27" TopLine="334"/>
+ <Filename Value="Classes/UFiles.pas"/>
+ <Caret Line="118" Column="51" TopLine="96"/>
</Position23>
<Position24>
- <Filename Value="lib/SQLite/SQLiteTable3.pas"/>
+ <Filename Value="Classes/UFiles.pas"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position24>
+ <Position25>
+ <Filename Value="Classes/UFiles.pas"/>
+ <Caret Line="38" Column="16" TopLine="17"/>
+ </Position25>
+ <Position26>
+ <Filename Value="Classes/UMain.pas"/>
+ <Caret Line="1" Column="1" TopLine="1"/>
+ </Position26>
+ <Position27>
+ <Filename Value="Classes/UMain.pas"/>
+ <Caret Line="105" Column="16" TopLine="84"/>
+ </Position27>
+ <Position28>
+ <Filename Value="UltraStar.lpr"/>
+ <Caret Line="103" Column="41" TopLine="82"/>
+ </Position28>
+ <Position29>
+ <Filename Value="UltraStar.lpr"/>
+ <Caret Line="176" Column="49" TopLine="155"/>
+ </Position29>
+ <Position30>
+ <Filename Value="UltraStar.lpr"/>
+ <Caret Line="1" Column="1" TopLine="1"/>
+ </Position30>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>
diff --git a/Game/Code/UltraStar.lpr b/Game/Code/UltraStar.lpr
index 31207bcb..bb3b50b3 100644
--- a/Game/Code/UltraStar.lpr
+++ b/Game/Code/UltraStar.lpr
@@ -34,155 +34,154 @@ uses
//------------------------------
// SDL / OpenGL
- sdl in 'lib\JEDI-SDLv1.0\SDL\Pas\sdl.pas',
- moduleloader in 'lib\JEDI-SDLv1.0\SDL\Pas\moduleloader.pas',
- opengl12 in 'lib\JEDI-SDLv1.0\OpenGL\Pas\opengl12.pas',
+ moduleloader in 'lib\JEDI-SDLv1.0\SDL\Pas\moduleloader.pas',
+ opengl12 in 'lib\JEDI-SDLv1.0\OpenGL\Pas\opengl12.pas',
+ sdl in 'lib\JEDI-SDLv1.0\SDL\Pas\sdl.pas',
// Bass
- {$IFDEF win32}
- bass in 'lib\bass\delphi\bass.pas',
+ {$IFDEF UseBASS}
+ bass in 'lib\bass\delphi\bass.pas',
{$ENDIF}
// Midi Units
{$IFDEF UseMIDIPort}
- midiout in 'lib\midi\midiout.pas',
- midiin in 'lib\midi\midiin.pas',
- Circbuf in 'lib\midi\CIRCBUF.PAS',
- MidiType in 'lib\midi\MidiType.PAS',
- MidiDefs in 'lib\midi\MidiDefs.PAS',
- MidiCons in 'lib\midi\MidiCons.PAS',
- MidiFile in 'lib\midi\MidiFile.PAS',
- Delphmcb in 'lib\midi\Delphmcb.PAS',
+ Circbuf in 'lib\midi\CIRCBUF.PAS',
+ Delphmcb in 'lib\midi\Delphmcb.PAS',
+ MidiCons in 'lib\midi\MidiCons.PAS',
+ MidiDefs in 'lib\midi\MidiDefs.PAS',
+ MidiFile in 'lib\midi\MidiFile.PAS',
+ midiin in 'lib\midi\midiin.pas',
+ midiout in 'lib\midi\midiout.pas',
+ MidiType in 'lib\midi\MidiType.PAS',
{$ENDIF}
// FFMpeg units
- avcodec in 'lib\ffmpeg\avcodec.pas',
- avformat in 'lib\ffmpeg\avformat.pas',
- avutil in 'lib\ffmpeg\avutil.pas',
- rational in 'lib\ffmpeg\rational.pas',
- opt in 'lib\ffmpeg\opt.pas',
- avio in 'lib\ffmpeg\avio.pas',
+ avcodec in 'lib\ffmpeg\avcodec.pas',
+ avformat in 'lib\ffmpeg\avformat.pas',
+ avio in 'lib\ffmpeg\avio.pas',
+ avutil in 'lib\ffmpeg\avutil.pas',
+ opt in 'lib\ffmpeg\opt.pas',
+ rational in 'lib\ffmpeg\rational.pas',
+
// Sql Lite
- SQLiteTable3 in 'lib\SQLite\SQLiteTable3.pas',
- SQLite3 in 'lib\SQLite\SQLite3.pas',
+ SQLiteTable3 in 'lib\SQLite\SQLiteTable3.pas',
+ SQLite3 in 'lib\SQLite\SQLite3.pas',
//------------------------------
//Includes - Menu System
//------------------------------
- UMenu in 'Menu\UMenu.pas',
- UDisplay in 'Menu\UDisplay.pas',
- UMenuStatic in 'Menu\UMenuStatic.pas',
- UMenuText in 'Menu\UMenuText.pas',
- UMenuButton in 'Menu\UMenuButton.pas',
- UMenuInteract in 'Menu\UMenuInteract.pas',
- UMenuSelect in 'Menu\UMenuSelect.pas',
- UMenuSelectSlide in 'Menu\UMenuSelectSlide.pas',
- UDrawTexture in 'Menu\UDrawTexture.pas',
- UMenuButtonCollection in 'Menu\UMenuButtonCollection.pas',
-
+
+ UDisplay in 'Menu\UDisplay.pas',
+ UDrawTexture in 'Menu\UDrawTexture.pas',
+ UMenu in 'Menu\UMenu.pas',
+ UMenuButton in 'Menu\UMenuButton.pas',
+ UMenuButtonCollection in 'Menu\UMenuButtonCollection.pas',
+ UMenuInteract in 'Menu\UMenuInteract.pas',
+ UMenuSelect in 'Menu\UMenuSelect.pas',
+ UMenuSelectSlide in 'Menu\UMenuSelectSlide.pas',
+ UMenuStatic in 'Menu\UMenuStatic.pas',
+ UMenuText in 'Menu\UMenuText.pas',
//------------------------------
//Includes - Classes
//------------------------------
{$IFDEF FPC}
- ulazjpeg in 'Classes\ulazjpeg.pas',
+ ulazjpeg in 'Classes\ulazjpeg.pas',
{$ENDIF}
-
- UCommon in 'Classes\UCommon.pas',
- UTime in 'Classes\UTime.pas',
- UCommandLine in 'Classes\UCommandLine.pas',
- ULog in 'Classes\ULog.pas',
- UMain in 'Classes\UMain.pas',
-
- UIni in 'Classes\UIni.pas',
- UTexture in 'Classes\UTexture.pas',
-
- UGraphic in 'Classes\UGraphic.pas',
- UMusic in 'Classes\UMusic.pas',
- ULanguage in 'Classes\ULanguage.pas',
- UDraw in 'Classes\UDraw.pas',
- URecord in 'Classes\URecord.pas',
- TextGL in 'Classes\TextGL.pas',
- USongs in 'Classes\USongs.pas',
- ULyrics in 'Classes\ULyrics.pas',
- USkins in 'Classes\USkins.pas',
- UThemes in 'Classes\UThemes.pas',
- UJoystick in 'Classes\UJoystick.pas',
- ULCD in 'Classes\ULCD.pas',
- ULight in 'Classes\ULight.pas',
- UDataBase in 'Classes\UDataBase.pas',
- UCovers in 'Classes\UCovers.pas',
- UCatCovers in 'Classes\UCatCovers.pas',
- UFiles in 'Classes\UFiles.pas',
- UGraphicClasses in 'Classes\UGraphicClasses.pas',
- UDLLManager in 'Classes\UDLLManager.pas',
- UParty in 'Classes\UParty.pas',
- UPlaylist in 'Classes\UPlaylist.pas',
+ TextGL in 'Classes\TextGL.pas',
+ UCatCovers in 'Classes\UCatCovers.pas',
+ UCommandLine in 'Classes\UCommandLine.pas',
+ UCommon in 'Classes\UCommon.pas',
+ UCovers in 'Classes\UCovers.pas',
+ UDataBase in 'Classes\UDataBase.pas',
+ UDLLManager in 'Classes\UDLLManager.pas',
+ UDraw in 'Classes\UDraw.pas',
+ UFiles in 'Classes\UFiles.pas',
+ UGraphic in 'Classes\UGraphic.pas',
+ UGraphicClasses in 'Classes\UGraphicClasses.pas',
+ UIni in 'Classes\UIni.pas',
+ UJoystick in 'Classes\UJoystick.pas',
+ ULanguage in 'Classes\ULanguage.pas',
+ ULCD in 'Classes\ULCD.pas',
+ ULight in 'Classes\ULight.pas',
+ ULog in 'Classes\ULog.pas',
+ ULyrics in 'Classes\ULyrics.pas',
+ UMain in 'Classes\UMain.pas',
+ UMusic in 'Classes\UMusic.pas',
+ UParty in 'Classes\UParty.pas',
+ UPlaylist in 'Classes\UPlaylist.pas',
+ URecord in 'Classes\URecord.pas',
+ USkins in 'Classes\USkins.pas',
+ USongs in 'Classes\USongs.pas',
+ UTexture in 'Classes\UTexture.pas',
+ UThemes in 'Classes\UThemes.pas',
+ UTime in 'Classes\UTime.pas',
+
//------------------------------
//Includes - Video Support
//------------------------------
- UVideo in 'Classes\UVideo.pas',
+ UVideo in 'Classes\UVideo.pas',
//------------------------------
//Includes - Screens
//------------------------------
- UScreenLoading in 'Screens\UScreenLoading.pas',
- UScreenWelcome in 'Screens\UScreenWelcome.pas',
- UScreenMain in 'Screens\UScreenMain.pas',
- UScreenName in 'Screens\UScreenName.pas',
- UScreenLevel in 'Screens\UScreenLevel.pas',
- UScreenSong in 'Screens\UScreenSong.pas',
- UScreenSing in 'Screens\UScreenSing.pas',
- UScreenScore in 'Screens\UScreenScore.pas',
- UScreenOptions in 'Screens\UScreenOptions.pas',
- UScreenOptionsGame in 'Screens\UScreenOptionsGame.pas',
- UScreenOptionsGraphics in 'Screens\UScreenOptionsGraphics.pas',
- UScreenOptionsSound in 'Screens\UScreenOptionsSound.pas',
- UScreenOptionsLyrics in 'Screens\UScreenOptionsLyrics.pas',
- UScreenOptionsThemes in 'Screens\UScreenOptionsThemes.pas',
- UScreenOptionsRecord in 'Screens\UScreenOptionsRecord.pas',
+ UScreenCredits in 'Screens\UScreenCredits.pas',
+ UScreenEdit in 'Screens\UScreenEdit.pas',
+ UScreenEditConvert in 'Screens\UScreenEditConvert.pas',
+ UScreenEditHeader in 'Screens\UScreenEditHeader.pas',
+ UScreenEditSub in 'Screens\UScreenEditSub.pas',
+ UScreenLevel in 'Screens\UScreenLevel.pas',
+ UScreenLoading in 'Screens\UScreenLoading.pas',
+ UScreenMain in 'Screens\UScreenMain.pas',
+ UScreenName in 'Screens\UScreenName.pas',
+ UScreenOpen in 'Screens\UScreenOpen.pas',
+ UScreenOptions in 'Screens\UScreenOptions.pas',
UScreenOptionsAdvanced in 'Screens\UScreenOptionsAdvanced.pas',
- UScreenEditSub in 'Screens\UScreenEditSub.pas',
- UScreenEdit in 'Screens\UScreenEdit.pas',
- UScreenEditConvert in 'Screens\UScreenEditConvert.pas',
- UScreenEditHeader in 'Screens\UScreenEditHeader.pas',
- UScreenOpen in 'Screens\UScreenOpen.pas',
- UScreenTop5 in 'Screens\UScreenTop5.pas',
- UScreenSongMenu in 'Screens\UScreenSongMenu.pas',
- UScreenSongJumpto in 'Screens\UScreenSongJumpto.pas',
- UScreenStatMain in 'Screens\UScreenStatMain.pas',
- UScreenStatDetail in 'Screens\UScreenStatDetail.pas',
- UScreenCredits in 'Screens\UScreenCredits.pas',
- UScreenPopup in 'Screens\UScreenPopup.pas',
-
+ UScreenOptionsGame in 'Screens\UScreenOptionsGame.pas',
+ UScreenOptionsGraphics in 'Screens\UScreenOptionsGraphics.pas',
+ UScreenOptionsLyrics in 'Screens\UScreenOptionsLyrics.pas',
+ UScreenOptionsRecord in 'Screens\UScreenOptionsRecord.pas',
+ UScreenOptionsSound in 'Screens\UScreenOptionsSound.pas',
+ UScreenOptionsThemes in 'Screens\UScreenOptionsThemes.pas',
+ UScreenPopup in 'Screens\UScreenPopup.pas',
+ UScreenScore in 'Screens\UScreenScore.pas',
+ UScreenSing in 'Screens\UScreenSing.pas',
+ UScreenSong in 'Screens\UScreenSong.pas',
+ UScreenSongJumpto in 'Screens\UScreenSongJumpto.pas',
+ UScreenSongMenu in 'Screens\UScreenSongMenu.pas',
+ UScreenStatDetail in 'Screens\UScreenStatDetail.pas',
+ UScreenStatMain in 'Screens\UScreenStatMain.pas',
+ UScreenTop5 in 'Screens\UScreenTop5.pas',
+ UScreenWelcome in 'Screens\UScreenWelcome.pas',
//------------------------------
//Includes - Screens PartyMode
//------------------------------
- UScreenSingModi in 'Screens\UScreenSingModi.pas',
- UScreenPartyNewRound in 'Screens\UScreenPartyNewRound.pas',
- UScreenPartyScore in 'Screens\UScreenPartyScore.pas',
- UScreenPartyPlayer in 'Screens\UScreenPartyPlayer.pas',
- UScreenPartyOptions in 'Screens\UScreenPartyOptions.pas',
- UScreenPartyWin in 'Screens\UScreenPartyWin.pas',
-
+ UScreenPartyNewRound in 'Screens\UScreenPartyNewRound.pas',
+ UScreenPartyOptions in 'Screens\UScreenPartyOptions.pas',
+ UScreenPartyPlayer in 'Screens\UScreenPartyPlayer.pas',
+ UScreenPartyScore in 'Screens\UScreenPartyScore.pas',
+ UScreenPartyWin in 'Screens\UScreenPartyWin.pas',
+ UScreenSingModi in 'Screens\UScreenSingModi.pas',
//------------------------------
//Includes - Modi SDK
//------------------------------
- ModiSDK in '..\..\Modis\SDK\ModiSDK.pas',
+ ModiSDK in '..\..\Modis\SDK\ModiSDK.pas',
//------------------------------
//Includes - Delphi
//------------------------------
+ {$IFDEF win32}
Windows,
+ {$ENDIF}
SysUtils;
const
@@ -196,6 +195,7 @@ var
begin
WndTitle := Version;
+ {$ifdef Win32}
//------------------------------
//Start more than One Time Prevention
//------------------------------
@@ -217,6 +217,7 @@ begin
else
Exit;
end;
+ {$endif}
//------------------------------
//StartUp - Create Classes and Load Files
diff --git a/Game/Code/switches.inc b/Game/Code/switches.inc
index 8bfbff34..0bace1cb 100644
--- a/Game/Code/switches.inc
+++ b/Game/Code/switches.inc
@@ -1,7 +1,13 @@
-{$IFDEF FPC}
- {$UNDEF UseSerialPort}
- {$UNDEF UseMIDIPort}
-{$ELSE}
- {$DEFINE UseSerialPort}
- {$DEFINE UseMIDIPort}
-{$ENDIF}
+{$IFDEF FPC}
+ {$UNDEF UseSerialPort}
+ {$UNDEF UseMIDIPort}
+{$ELSE}
+ {$DEFINE UseSerialPort}
+ {$DEFINE UseMIDIPort}
+{$ENDIF}
+
+{$IFDEF win32}
+ {$DEFINE UseBASS}
+{$ELSE}
+ {$UNDEF UseBASS}
+{$ENDIF}