aboutsummaryrefslogtreecommitdiffstats
path: root/Game
diff options
context:
space:
mode:
Diffstat (limited to 'Game')
-rw-r--r--Game/Code/Classes/TextGL.dcubin0 -> 8556 bytes
-rw-r--r--Game/Code/Classes/TextGL.pas345
-rw-r--r--Game/Code/Classes/UCatCovers.dcubin0 -> 4945 bytes
-rw-r--r--Game/Code/Classes/UCatCovers.pas143
-rw-r--r--Game/Code/Classes/UCovers.dcubin0 -> 6055 bytes
-rw-r--r--Game/Code/Classes/UCovers.pas226
-rw-r--r--Game/Code/Classes/UDLLManager.dcubin0 -> 6021 bytes
-rw-r--r--Game/Code/Classes/UDLLManager.pas216
-rw-r--r--Game/Code/Classes/UDraw.dcubin0 -> 41304 bytes
-rw-r--r--Game/Code/Classes/UDraw.pas1613
-rw-r--r--Game/Code/Classes/UFiles.dcubin0 -> 4673 bytes
-rw-r--r--Game/Code/Classes/UFiles.pas326
-rw-r--r--Game/Code/Classes/UGraphic.dcubin0 -> 18647 bytes
-rw-r--r--Game/Code/Classes/UGraphic.pas405
-rw-r--r--Game/Code/Classes/UGraphicClasses.dcubin0 -> 341 bytes
-rw-r--r--Game/Code/Classes/UGraphicClasses.pas7
-rw-r--r--Game/Code/Classes/UIni.dcubin0 -> 22355 bytes
-rw-r--r--Game/Code/Classes/UIni.pas693
-rw-r--r--Game/Code/Classes/UJoystick.dcubin0 -> 2268 bytes
-rw-r--r--Game/Code/Classes/UJoystick.pas124
-rw-r--r--Game/Code/Classes/ULCD.dcubin0 -> 5497 bytes
-rw-r--r--Game/Code/Classes/ULCD.pas287
-rw-r--r--Game/Code/Classes/ULCD.~pas287
-rw-r--r--Game/Code/Classes/ULanguage.dcubin0 -> 6519 bytes
-rw-r--r--Game/Code/Classes/ULanguage.pas222
-rw-r--r--Game/Code/Classes/ULight.dcubin0 -> 2389 bytes
-rw-r--r--Game/Code/Classes/ULight.pas116
-rw-r--r--Game/Code/Classes/ULog.dcubin0 -> 6217 bytes
-rw-r--r--Game/Code/Classes/ULog.pas227
-rw-r--r--Game/Code/Classes/ULyrics.dcubin0 -> 9029 bytes
-rw-r--r--Game/Code/Classes/ULyrics.pas383
-rw-r--r--Game/Code/Classes/UMain.dcubin0 -> 11501 bytes
-rw-r--r--Game/Code/Classes/UMain.pas673
-rw-r--r--Game/Code/Classes/UMusic.dcubin0 -> 15179 bytes
-rw-r--r--Game/Code/Classes/UMusic.pas783
-rw-r--r--Game/Code/Classes/UParty.dcubin0 -> 4129 bytes
-rw-r--r--Game/Code/Classes/UParty.pas204
-rw-r--r--Game/Code/Classes/UPliki.dcubin0 -> 19679 bytes
-rw-r--r--Game/Code/Classes/UPliki.pas830
-rw-r--r--Game/Code/Classes/URecord.dcubin0 -> 6913 bytes
-rw-r--r--Game/Code/Classes/URecord.pas371
-rw-r--r--Game/Code/Classes/UScores.dcubin0 -> 4811 bytes
-rw-r--r--Game/Code/Classes/UScores.pas144
-rw-r--r--Game/Code/Classes/USkins.dcubin0 -> 5747 bytes
-rw-r--r--Game/Code/Classes/USkins.pas158
-rw-r--r--Game/Code/Classes/USongs.dcubin0 -> 13980 bytes
-rw-r--r--Game/Code/Classes/USongs.pas667
-rw-r--r--Game/Code/Classes/UTexture.dcubin0 -> 19192 bytes
-rw-r--r--Game/Code/Classes/UTexture.pas811
-rw-r--r--Game/Code/Classes/UThemes.dcubin0 -> 59165 bytes
-rw-r--r--Game/Code/Classes/UThemes.pas1837
-rw-r--r--Game/Code/Classes/UTime.dcubin0 -> 2083 bytes
-rw-r--r--Game/Code/Classes/UTime.pas81
-rw-r--r--Game/Code/Menu/UDisplay.dcubin0 -> 7030 bytes
-rw-r--r--Game/Code/Menu/UDisplay.pas289
-rw-r--r--Game/Code/Menu/UDrawTexture.dcubin0 -> 3640 bytes
-rw-r--r--Game/Code/Menu/UDrawTexture.pas101
-rw-r--r--Game/Code/Menu/UMenu.dcubin0 -> 31672 bytes
-rw-r--r--Game/Code/Menu/UMenu.pas1136
-rw-r--r--Game/Code/Menu/UMenuButton.dcubin0 -> 5472 bytes
-rw-r--r--Game/Code/Menu/UMenuButton.pas238
-rw-r--r--Game/Code/Menu/UMenuInteract.dcubin0 -> 404 bytes
-rw-r--r--Game/Code/Menu/UMenuInteract.pas14
-rw-r--r--Game/Code/Menu/UMenuSelect.dcubin0 -> 3922 bytes
-rw-r--r--Game/Code/Menu/UMenuSelect.pas198
-rw-r--r--Game/Code/Menu/UMenuSelectSlide.dcubin0 -> 6108 bytes
-rw-r--r--Game/Code/Menu/UMenuSelectSlide.pas335
-rw-r--r--Game/Code/Menu/UMenuStatic.dcubin0 -> 1594 bytes
-rw-r--r--Game/Code/Menu/UMenuStatic.pas32
-rw-r--r--Game/Code/Menu/UMenuText.dcubin0 -> 3155 bytes
-rw-r--r--Game/Code/Menu/UMenuText.pas96
-rw-r--r--Game/Code/SMpeg/USmpeg.alt.pas292
-rw-r--r--Game/Code/SMpeg/USmpeg.dcubin0 -> 6074 bytes
-rw-r--r--Game/Code/SMpeg/USmpeg.pas299
-rw-r--r--Game/Code/Screens/UScreenEdit.dcubin0 -> 2915 bytes
-rw-r--r--Game/Code/Screens/UScreenEdit.pas104
-rw-r--r--Game/Code/Screens/UScreenEditConvert.dcubin0 -> 13604 bytes
-rw-r--r--Game/Code/Screens/UScreenEditConvert.pas500
-rw-r--r--Game/Code/Screens/UScreenEditHeader.dcubin0 -> 9398 bytes
-rw-r--r--Game/Code/Screens/UScreenEditHeader.pas362
-rw-r--r--Game/Code/Screens/UScreenEditSub.dcubin0 -> 29283 bytes
-rw-r--r--Game/Code/Screens/UScreenEditSub.pas1236
-rw-r--r--Game/Code/Screens/UScreenLevel.dcubin0 -> 3407 bytes
-rw-r--r--Game/Code/Screens/UScreenLevel.pas101
-rw-r--r--Game/Code/Screens/UScreenLoading.dcubin0 -> 2525 bytes
-rw-r--r--Game/Code/Screens/UScreenLoading.pas48
-rw-r--r--Game/Code/Screens/UScreenMain.dcubin0 -> 9661 bytes
-rw-r--r--Game/Code/Screens/UScreenMain.pas384
-rw-r--r--Game/Code/Screens/UScreenName.dcubin0 -> 4199 bytes
-rw-r--r--Game/Code/Screens/UScreenName.pas114
-rw-r--r--Game/Code/Screens/UScreenOpen.dcubin0 -> 4756 bytes
-rw-r--r--Game/Code/Screens/UScreenOpen.pas151
-rw-r--r--Game/Code/Screens/UScreenOptions.dcubin0 -> 4834 bytes
-rw-r--r--Game/Code/Screens/UScreenOptions.pas221
-rw-r--r--Game/Code/Screens/UScreenOptionsGame.dcubin0 -> 4049 bytes
-rw-r--r--Game/Code/Screens/UScreenOptionsGame.pas107
-rw-r--r--Game/Code/Screens/UScreenOptionsGraphics.dcubin0 -> 3911 bytes
-rw-r--r--Game/Code/Screens/UScreenOptionsGraphics.pas101
-rw-r--r--Game/Code/Screens/UScreenOptionsLyrics.dcubin0 -> 3566 bytes
-rw-r--r--Game/Code/Screens/UScreenOptionsLyrics.pas91
-rw-r--r--Game/Code/Screens/UScreenOptionsRecord.dcubin0 -> 4885 bytes
-rw-r--r--Game/Code/Screens/UScreenOptionsRecord.pas136
-rw-r--r--Game/Code/Screens/UScreenOptionsSound.dcubin0 -> 3629 bytes
-rw-r--r--Game/Code/Screens/UScreenOptionsSound.pas93
-rw-r--r--Game/Code/Screens/UScreenOptionsThemes.dcubin0 -> 4188 bytes
-rw-r--r--Game/Code/Screens/UScreenOptionsThemes.pas118
-rw-r--r--Game/Code/Screens/UScreenPartyNewRound.dcubin0 -> 9085 bytes
-rw-r--r--Game/Code/Screens/UScreenPartyNewRound.pas397
-rw-r--r--Game/Code/Screens/UScreenPartyOptions.dcubin0 -> 5884 bytes
-rw-r--r--Game/Code/Screens/UScreenPartyOptions.pas164
-rw-r--r--Game/Code/Screens/UScreenPartyPlayer.dcubin0 -> 6068 bytes
-rw-r--r--Game/Code/Screens/UScreenPartyPlayer.pas210
-rw-r--r--Game/Code/Screens/UScreenPartyScore.dcubin0 -> 5605 bytes
-rw-r--r--Game/Code/Screens/UScreenPartyScore.pas183
-rw-r--r--Game/Code/Screens/UScreenPartyWin.dcubin0 -> 4642 bytes
-rw-r--r--Game/Code/Screens/UScreenPartyWin.pas157
-rw-r--r--Game/Code/Screens/UScreenScore.dcubin0 -> 10273 bytes
-rw-r--r--Game/Code/Screens/UScreenScore.pas586
-rw-r--r--Game/Code/Screens/UScreenSing.dcubin0 -> 23327 bytes
-rw-r--r--Game/Code/Screens/UScreenSing.pas1121
-rw-r--r--Game/Code/Screens/UScreenSingModi.dcubin0 -> 15109 bytes
-rw-r--r--Game/Code/Screens/UScreenSingModi.pas1088
-rw-r--r--Game/Code/Screens/UScreenSong.dcubin0 -> 29384 bytes
-rw-r--r--Game/Code/Screens/UScreenSong.pas1690
-rw-r--r--Game/Code/Screens/UScreenSongMenu.dcubin0 -> 7346 bytes
-rw-r--r--Game/Code/Screens/UScreenSongMenu.pas355
-rw-r--r--Game/Code/Screens/UScreenTop5.dcubin0 -> 4531 bytes
-rw-r--r--Game/Code/Screens/UScreenTop5.pas166
-rw-r--r--Game/Code/Screens/UScreenWelcome.dcubin0 -> 3228 bytes
-rw-r--r--Game/Code/Screens/UScreenWelcome.pas117
-rw-r--r--Game/Code/UltraStar.RESbin0 -> 1341060 bytes
-rw-r--r--Game/Code/UltraStar.bdsproj168
-rw-r--r--Game/Code/UltraStar.bdsproj.local2
-rw-r--r--Game/Code/UltraStar.cfg41
-rw-r--r--Game/Code/UltraStar.dof148
-rw-r--r--Game/Code/UltraStar.dpr286
-rw-r--r--Game/Code/UltraStar.identcache2bin0 -> 3983 bytes
-rw-r--r--Game/Code/UltraStar.rc15
-rw-r--r--Game/Code/UltraStar.~dpr285
-rw-r--r--Game/Code/rccompillieren.bat1
-rw-r--r--Game/Fonts/512x512 Normal.datbin0 -> 512 bytes
-rw-r--r--Game/Fonts/Backup/Bold/Font 1024 Bold 16.bmpbin0 -> 524408 bytes
-rw-r--r--Game/Fonts/Backup/Bold/Font 1024 Bold.datbin0 -> 256 bytes
-rw-r--r--Game/Fonts/Backup/Bold/Thumbs.dbbin0 -> 9216 bytes
-rw-r--r--Game/Fonts/Backup/Normal/Font Normal 16.bmpbin0 -> 131192 bytes
-rw-r--r--Game/Fonts/Backup/Normal/Font Normal.datbin0 -> 256 bytes
-rw-r--r--Game/Fonts/Backup/Normal/Thumbs.dbbin0 -> 8704 bytes
-rw-r--r--Game/Fonts/Backup/Outline 1/Outline 36 (1024) 16c.bmpbin0 -> 524408 bytes
-rw-r--r--Game/Fonts/Backup/Outline 1/Outline 36 (1024).datbin0 -> 256 bytes
-rw-r--r--Game/Fonts/Backup/Outline 1/Thumbs.dbbin0 -> 9728 bytes
-rw-r--r--Game/Fonts/Backup/Outline 2/5 - Outline dark edited 16c.bmpbin0 -> 131192 bytes
-rw-r--r--Game/Fonts/Backup/Outline 2/Outline.datbin0 -> 256 bytes
-rw-r--r--Game/Fonts/Backup/Outline 2/Thumbs.dbbin0 -> 9216 bytes
-rw-r--r--Game/Fonts/Bold/Font 1024 Bold 16.bmpbin0 -> 524406 bytes
-rw-r--r--Game/Fonts/Bold/Font 1024 Bold 16.old.bmpbin0 -> 524408 bytes
-rw-r--r--Game/Fonts/Bold/Font 1024 Bold.datbin0 -> 256 bytes
-rw-r--r--Game/Fonts/Bold/Thumbs.dbbin0 -> 9216 bytes
-rw-r--r--Game/Fonts/Normal/Font Normal 16.bmpbin0 -> 131190 bytes
-rw-r--r--Game/Fonts/Normal/Font Normal 16.old.bmpbin0 -> 131192 bytes
-rw-r--r--Game/Fonts/Normal/Font Normal.datbin0 -> 256 bytes
-rw-r--r--Game/Fonts/Normal/Thumbs.dbbin0 -> 20992 bytes
-rw-r--r--Game/Fonts/Outline 1/Outline 36 (1024) 16c.bmpbin0 -> 524406 bytes
-rw-r--r--Game/Fonts/Outline 1/Outline 36 (1024).datbin0 -> 256 bytes
-rw-r--r--Game/Fonts/Outline 1/Photoshop.psdbin0 -> 952610 bytes
-rw-r--r--Game/Fonts/Outline 1/Thumbs.dbbin0 -> 9728 bytes
-rw-r--r--Game/Fonts/Outline 2/5 - Outline dark edited 16c.bmpbin0 -> 131190 bytes
-rw-r--r--Game/Fonts/Outline 2/Outline.datbin0 -> 256 bytes
-rw-r--r--Game/Fonts/Outline 2/Thumbs.dbbin0 -> 9216 bytes
-rw-r--r--Game/Graphics/MusicWheelItem song.jpgbin0 -> 27550 bytes
-rw-r--r--Game/Graphics/Thumbs.dbbin0 -> 10752 bytes
-rw-r--r--Game/Graphics/us.icobin0 -> 766 bytes
171 files changed, 26256 insertions, 0 deletions
diff --git a/Game/Code/Classes/TextGL.dcu b/Game/Code/Classes/TextGL.dcu
new file mode 100644
index 00000000..772d09c1
--- /dev/null
+++ b/Game/Code/Classes/TextGL.dcu
Binary files differ
diff --git a/Game/Code/Classes/TextGL.pas b/Game/Code/Classes/TextGL.pas
new file mode 100644
index 00000000..cf09e48b
--- /dev/null
+++ b/Game/Code/Classes/TextGL.pas
@@ -0,0 +1,345 @@
+unit TextGL;
+
+interface
+
+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, UGraphic;
+
+procedure BuildFont; // Build Our Bitmap Font
+var
+ font: HFONT; // Windows Font ID
+ h_dc: hdc;
+ Rejestr: TResourceStream;
+ Pet: integer;
+begin
+ ActFont := 0;
+
+ SetLength(Fonts, 5);
+ Fonts[0].Tex := Texture.LoadTexture(true, 'Font', 'BMP', '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', 'BMP', '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', 'BMP', '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', 'BMP', '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;}
+
+
+ Rejestr := TResourceStream.Create(HInstance, 'Font', 'FNT');
+ Rejestr.Read(Fonts[0].Width, 256);
+ Rejestr.Free;
+
+ Rejestr := TResourceStream.Create(HInstance, 'FontB', 'FNT');
+ Rejestr.Read(Fonts[1].Width, 256);
+ Rejestr.Free;
+
+ Rejestr := TResourceStream.Create(HInstance, 'FontO', 'FNT');
+ Rejestr.Read(Fonts[2].Width, 256);
+ Rejestr.Free;
+
+ Rejestr := TResourceStream.Create(HInstance, 'FontO2', 'FNT');
+ Rejestr.Read(Fonts[3].Width, 256);
+ Rejestr.Free;
+
+{ 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;
+
+end.
diff --git a/Game/Code/Classes/UCatCovers.dcu b/Game/Code/Classes/UCatCovers.dcu
new file mode 100644
index 00000000..2ff7a7d9
--- /dev/null
+++ b/Game/Code/Classes/UCatCovers.dcu
Binary files differ
diff --git a/Game/Code/Classes/UCatCovers.pas b/Game/Code/Classes/UCatCovers.pas
new file mode 100644
index 00000000..00a758c8
--- /dev/null
+++ b/Game/Code/Classes/UCatCovers.pas
@@ -0,0 +1,143 @@
+unit UCatCovers;
+/////////////////////////////////////////////////////////////////////////
+// UCatCovers by Whiteshark //
+// Class for listing and managing the Category Covers //
+/////////////////////////////////////////////////////////////////////////
+
+interface
+uses UIni;
+
+type
+ TCatCovers = class
+ protected
+ cNames: array [low(ISorting)..high(ISorting)] of array of string;
+ cFiles: array [low(ISorting)..high(ISorting)] of array of string;
+ public
+ constructor Create;
+ procedure Load; //Load Cover aus Cover.ini and Cover Folder
+ procedure Add(Sorting: integer; Name, Filename: string); //Add a Cover
+ function CoverExists(Sorting: integer; Name: string): boolean; //Returns True when a cover with the given Name exists
+ function GetCover(Sorting: integer; Name: string): string; //Returns the Filename of a Cover
+ end;
+
+var
+CatCovers: TCatCovers;
+
+implementation
+uses IniFiles, SysUtils, Classes, UPliki, ULog;
+
+constructor TCatCovers.Create;
+begin
+ Load;
+end;
+
+ //Load Cover aus Cover.ini and Cover Folder
+procedure TCatCovers.Load;
+var
+ Ini: TMemIniFile;
+ SR: TSearchRec;
+ List: TStringlist;
+ I, J: Integer;
+ Name, Filename, Temp: string;
+begin
+try
+ Ini := TMemIniFile.Create(CoversPath + 'covers.ini');
+ List := TStringlist.Create;
+
+ //Add every Cover in Covers Ini for Every Sorting option
+ for I := low(ISorting) to high(ISorting) do
+ begin
+ Ini.ReadSection(ISorting[I], List);
+
+ for J := 0 to List.Count - 1 do
+ Add(I, List.Strings[J], CoversPath + Ini.ReadString(ISorting[I], List.Strings[J], 'NoCover.jpg'));
+ end;
+
+finally
+ Ini.Free;
+ List.Free;
+end;
+
+try
+ //Add Covers from Folder
+ if (FindFirst (CoversPath + '*.jpg', faAnyFile, SR) = 0) then
+ repeat
+ //Add Cover if it doesn't exist for every Section
+ Name := SR.Name;
+ Filename := CoversPath + Name;
+ Delete (Name, length(Name) - 3, 4);
+
+ for I := low(ISorting) to high(ISorting) do
+ begin
+ Temp := Name;
+ if ((I = sTitle) or (I = sTitle2)) and (Pos ('Title', Temp) <> 0) then
+ Delete (Temp, Pos ('Title', Temp), 5)
+ else if (I = sArtist) or (I = sArtist2) and (Pos ('Artist', Temp) <> 0) then
+ Delete (Temp, Pos ('Artist', Temp), 6);
+
+ if not CoverExists(I, Temp) then
+ Add (I, Temp, Filename);
+ end;
+ until FindNext (SR) <> 0;
+
+finally
+ FindClose (SR);
+end;
+
+end;
+
+ //Add a Cover
+procedure TCatCovers.Add(Sorting: integer; Name, Filename: string);
+begin
+if FileExists (Filename) then //If Exists -> Add
+begin
+SetLength (CNames[Sorting], Length(CNames[Sorting]) + 1);
+SetLength (CFiles[Sorting], Length(CNames[Sorting]) + 1);
+
+CNames[Sorting][high(cNames[Sorting])] := Uppercase(Name);
+CFiles[Sorting][high(cNames[Sorting])] := FileName;
+end;
+end;
+
+ //Returns True when a cover with the given Name exists
+function TCatCovers.CoverExists(Sorting: integer; Name: string): boolean;
+var
+I: Integer;
+begin
+Result := False;
+Name := Uppercase(Name); //Case Insensitiv
+
+for I := low(cNames[Sorting]) to high(cNames[Sorting]) do
+begin
+ if (cNames[Sorting][I] = Name) then //Found Name
+ begin
+ Result := true;
+ break; //Break For Loop
+ end;
+end;
+end;
+
+ //Returns the Filename of a Cover
+function TCatCovers.GetCover(Sorting: integer; Name: string): string;
+var
+I: Integer;
+begin
+Result := '';
+Name := Uppercase(Name);
+
+for I := low(cNames[Sorting]) to high(cNames[Sorting]) do
+begin
+ if cNames[Sorting][I] = Name then
+ begin
+ Result := cFiles[Sorting][I];
+ Break;
+ end;
+end;
+
+//No Cover
+if (Result = '') AND (FileExists(CoversPath + 'NoCover.jpg')) then
+ Result := CoversPath + 'NoCover.jpg';
+
+end;
+
+end.
diff --git a/Game/Code/Classes/UCovers.dcu b/Game/Code/Classes/UCovers.dcu
new file mode 100644
index 00000000..ca99fc7c
--- /dev/null
+++ b/Game/Code/Classes/UCovers.dcu
Binary files differ
diff --git a/Game/Code/Classes/UCovers.pas b/Game/Code/Classes/UCovers.pas
new file mode 100644
index 00000000..55329fd2
--- /dev/null
+++ b/Game/Code/Classes/UCovers.pas
@@ -0,0 +1,226 @@
+unit UCovers;
+
+interface
+uses OpenGL12, Windows, Math, Classes, SysUtils, Graphics, 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 UPliki, 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;
+
+ 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.dcu b/Game/Code/Classes/UDLLManager.dcu
new file mode 100644
index 00000000..3ba97949
--- /dev/null
+++ b/Game/Code/Classes/UDLLManager.dcu
Binary files differ
diff --git a/Game/Code/Classes/UDLLManager.pas b/Game/Code/Classes/UDLLManager.pas
new file mode 100644
index 00000000..151f0617
--- /dev/null
+++ b/Game/Code/Classes/UDLLManager.pas
@@ -0,0 +1,216 @@
+unit UDLLManager;
+
+interface
+uses ModiSDK, UPliki;
+
+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: fModi_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
+ 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: fModi_PlaySound): boolean;
+begin
+if (@P_Init <> nil) then
+ Result := P_Init (TeamInfo, PlayerInfo, Sentences, LoadTex, Print, LoadSound, PlaySound)
+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/UDraw.dcu b/Game/Code/Classes/UDraw.dcu
new file mode 100644
index 00000000..a3fcecc9
--- /dev/null
+++ b/Game/Code/Classes/UDraw.dcu
Binary files differ
diff --git a/Game/Code/Classes/UDraw.pas b/Game/Code/Classes/UDraw.pas
new file mode 100644
index 00000000..e9433790
--- /dev/null
+++ b/Game/Code/Classes/UDraw.pas
@@ -0,0 +1,1613 @@
+unit UDraw;
+
+interface
+uses UThemes, ModiSDK;
+
+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);
+procedure SingDrawStar(X, Y, A: real);
+procedure SingGoldenStar(X, Y, A: real);
+
+// The Singbar
+procedure SingDrawSingbar(X, Y, W, H: real; Percent: integer);
+
+//Phrasen Bonus - Line Bonus
+procedure SingDrawLineBonus( const X, Y: integer; Color: TRGB; Alpha: Single; Text: string);
+
+//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 Mod
+ TickOld: cardinal;
+ TickOld2:cardinal;
+ //end Singbar Mod
+
+
+
+
+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);
+
+ if (Ini.MovieSize = 0) 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;
+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
+ if not FreeStyle then begin
+
+ // Golden Note Patch
+ case Wartosc of
+ 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(7/8, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(7/8, 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(1/32, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(1/32, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(31/32, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(31/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_Right[Color].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(1/8, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(1/8, 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
+ //case Wartosc of
+ // 2: SingGoldenStar(Rec.Left, Rec.Top, 1, StarfrG);
+ //end; // case
+
+
+ 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
+ // lewa czesc
+ Rec.Left := X + (Start-Czesci[0].Czesc[Czesci[0].Akt].StartNote) * TempR + 0.5 + 10*ScreenX;
+ Rec.Right := Rec.Left + NotesW;
+
+
+ // Half size Notes Patch
+ if Hit then begin
+ NotesH2 := NotesH
+ end else begin
+ NotesH2 := int(NotesH * 0.65);
+ end; //if
+
+
+
+ // if True then
+ Rec.Top := Y - (Ton-Czesci[0].Czesc[Czesci[0].Akt].BaseNote)*Space/2 - NotesH2;
+ Rec.Bottom := Rec.Top + 2 *NotesH2;
+
+ glColor3f(1, 1, 1);
+ glBindTexture(GL_TEXTURE_2D, Tex_Left[NrGracza+1].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(1/8, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(1/8, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(7/8, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(7/8, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+ // srodkowa czesc
+ Rec.Left := Rec.Right;
+ Rec.Right := X + (Start+Dlugosc-Czesci[0].Czesc[Czesci[0].Akt].StartNote) * TempR - NotesW - 0.5 + 10*ScreenX;
+ // (nowe)
+ if (Start+Dlugosc-1 = Czas.AktBeatD) then
+ Rec.Right := Rec.Right - (1-Frac(Czas.MidBeatD)) * TempR;
+
+ if Rec.Right <= Rec.Left then Rec.Right := Rec.Left;
+
+
+// glColor3f(R, G, B);
+// glBindTexture(GL_TEXTURE_2D, Tex_MidGray.TexNum);
+ glBindTexture(GL_TEXTURE_2D, Tex_Mid[NrGracza+1].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(1/8, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(1/8, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(7/8, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(7/8, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+ glColor3f(1, 1, 1);
+
+ // prawa czesc
+ Rec.Left := Rec.Right;
+ Rec.Right := Rec.Right + NotesW;
+
+ glBindTexture(GL_TEXTURE_2D, Tex_Right[NrGracza+1].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(1/8, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(1/8, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(1, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(1, 0); glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+
+
+
+ //Rec.Right := X + (Start+Dlugosc-Czesci[0].Czesc[Czesci[0].Akt].StartNote) * TempR - NotesW - 0.5 + 10*ScreenX;
+ //if (Start+Dlugosc-1 = Czas.AktBeatD) then
+ if Perfect AND (Ini.GMAFix <> 1) then begin
+// A := sqrt((1+sin(Music.Position * 3))/2);
+ 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;
+
+
+ SingDrawStar(Rec.Left+2, Rec.Top+4, A);
+ end;
+
+ // detekt
+{ Rec.Left := Round((Detekt-Czesci.Czesc[Czesci.Akt].Start) * TempR) + 130;
+ glColor3f(1, 0.2, 0.2);
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ glBegin(GL_QUADS);
+ glVertex(Rec.Left, Rec.Top-5);
+ glVertex(Rec.Left, Rec.Bottom+5);
+ glVertex(Rec.Left+1, Rec.Bottom+5);
+ glVertex(Rec.Left+1, Rec.Top-5);
+ glEnd;
+ glColor3f(1, 1, 1);
+ glEnable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);}
+
+ // detekt + FFT length
+{ Rec.Right := (Detekt-Czesci.Czesc[Czesci.Akt].Start) * TempR + 130;
+ // TempR = dlugosc 1 kostki
+ // 60 * 4 / BPM = czas w sekundach na 1 kostke, np. 0,4s
+ // 4096 / 44100 = czas jednego sampla FFT, np. 0,1s
+ // ile to ma kostek? np. 0.25
+ // (4096 / 44100) / (60 * 4 / BPM), np. 0,1s / 0,4s = 0.25
+ // * TempR = dlugosc sampla FFT
+ Rec.Left := Rec.Right - (Sound.n / 44100) / (60 * 4 / Muzyka.BPM) * TempR;
+
+ glColor3f(1, 0.2, 0.2);
+ glVertex(Rec.Left, Rec.Top-4);
+ glVertex(Rec.Left, Rec.Bottom+4);
+ glVertex(Rec.Right, Rec.Bottom+4);
+ glVertex(Rec.Right, Rec.Top-4);}
+
+ end; // with
+ end; // for
+ 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(7/8, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(7/8, 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(1/32, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(1/32, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(31/32, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(31/32, 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(1/8, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(1/8, 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 SingDrawStar(X, Y, A: real);
+var
+ TempR: real;
+ W, H: real;
+ Starframe: real;
+ begin
+ W := 32;
+ H := 32;
+
+ // Golden Star Patch
+// case Z of
+// 1: glColor4f(1, 1, 1, A);
+// 2: glColor4f(1, 1, 0.3, A);
+// end; // case
+
+ glColor4f(1, 1, 1, A);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, Tex_Note_Star.TexNum);
+
+ Starframe := 15 - ((GetTickCount div 33) mod 16);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f((1/16) * Starframe, 0); glVertex2f(X-W, Y-H);
+ glTexCoord2f((1/16) * Starframe + (1/16), 0); glVertex2f(X-W, Y+H);
+ glTexCoord2f((1/16) * Starframe + (1/16), 1); glVertex2f(X+W, Y+H);
+ glTexCoord2f((1/16) * Starframe, 1); glVertex2f(X+W, Y-H);
+ glEnd;
+end;
+
+
+procedure SingGoldenStar(X, Y, A: real);
+var
+ TempR: real;
+ W, H: real;
+ StarfrG2: real;
+ begin
+ W := 16;
+ H := 16;
+ glColor4f(1, 1, 0.3, A);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBindTexture(GL_TEXTURE_2D, Tex_Note_Star.TexNum);
+ StarfrG2 := 15 - ((GetTickCount div 67) mod 16);
+ glBegin(GL_QUADS);
+ //x1
+ glTexCoord2f((1/16) * StarfrG2, 0); glVertex2f(X-W, Y-H);
+ glTexCoord2f((1/16) * StarfrG2 + (1/16), 0); glVertex2f(X-W, Y+H);
+ glTexCoord2f((1/16) * StarfrG2 + (1/16), 1); glVertex2f(X+W, Y+H);
+ glTexCoord2f((1/16) * StarfrG2, 1); glVertex2f(X+W, Y-H);
+ glEnd;
+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;
+
+ // time bar
+// Log.LogStatus('Time Bar', 'SingDraw');
+ glBegin(GL_QUADS);
+ glColor3f(0.9, 0.9, 0.9);
+ glVertex2f(140 + 10*ScreenX, 21);
+ glVertex2f(140 + 10*ScreenX, 29);
+ glVertex2f(330 + 10*ScreenX, 29);
+ glVertex2f(330 + 10*ScreenX, 21);
+ glColor3f(Skin_TimeR, Skin_TimeG, Skin_TimeB);
+ glVertex2f(140 + 10*ScreenX, 21);
+ glVertex2f(140 + 10*ScreenX, 29);
+ glVertex2f(140 + 10*ScreenX+(330-140)*(Czas.Teraz/Czas.Razem), 29);
+ glVertex2f(140 + 10*ScreenX+(330-140)*(Czas.Teraz/Czas.Razem), 21);
+ glEnd;
+
+ // 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_BLEND);
+ glBegin(GL_QUADS);
+ glColor4f(26/255, 165/255, 220/255, 0);
+ glVertex2f(Rec.Left, Rec.Top);
+ glVertex2f(Rec.Left, Rec.Bottom);
+ glColor4f(26/255, 165/255, 220/255, BarAlpha);
+ glVertex2f(Rec.Right, Rec.Bottom);
+ 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
+ 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( 75 + 10*ScreenX, 95, 100, 8, Player[0].ScorePercent);
+ end;
+ if PlayersPlay = 2 then begin
+ SingDrawSingbar( 75 + 10*ScreenX, 95, 100, 8, Player[0].ScorePercent);
+ SingDrawSingbar(620 + 10*ScreenX, 95, 100, 8, Player[1].ScorePercent);
+ end;
+ if PlayersPlay = 3 then begin
+ SingDrawSingbar( 75 + 10*ScreenX, 95, 100, 8, Player[0].ScorePercent);
+ SingDrawSingbar(370 + 10*ScreenX, 95, 100, 8, Player[1].ScorePercent);
+ SingDrawSingbar(670 + 10*ScreenX, 95, 100, 8, Player[2].ScorePercent);
+ end;
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ SingDrawSingbar( 75 + 10*ScreenX, 95, 100, 8, Player[0].ScorePercent);
+ SingDrawSingbar(620 + 10*ScreenX, 95, 100, 8, Player[1].ScorePercent);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawSingbar( 75 + 10*ScreenX, 95, 100, 8, Player[2].ScorePercent);
+ SingDrawSingbar(620 + 10*ScreenX, 95, 100, 8, Player[3].ScorePercent);
+ end;
+ end;
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ SingDrawSingbar( 75 + 10*ScreenX, 95, 100, 8, Player[0].ScorePercent);
+ SingDrawSingbar(370 + 10*ScreenX, 95, 100, 8, Player[1].ScorePercent);
+ SingDrawSingbar(670 + 10*ScreenX, 95, 100, 8, Player[2].ScorePercent);
+ end;
+ if ScreenAct = 2 then begin
+ SingDrawSingbar( 75 + 10*ScreenX, 95, 100, 8, Player[3].ScorePercent);
+ SingDrawSingbar(370 + 10*ScreenX, 95, 100, 8, Player[4].ScorePercent);
+ SingDrawSingbar(670 + 10*ScreenX, 95, 100, 8, 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
+ Player[E].LineBonus_Visible := False
+ else
+ begin
+ //Change Position
+ if (Player[E].LineBonus_PosX < Player[E].LineBonus_TargetX) then
+ Inc(Player[E].LineBonus_PosX,1)
+ else if (Player[E].LineBonus_PosX > Player[E].LineBonus_TargetX) then
+ Dec(Player[E].LineBonus_PosX,1);
+
+ if (Player[E].LineBonus_PosY < Player[E].LineBonus_TargetY) then
+ Inc(Player[E].LineBonus_PosY,1)
+ else if (Player[E].LineBonus_PosY > Player[E].LineBonus_TargetY) then
+ Dec(Player[E].LineBonus_PosY,1);
+
+ end;
+ end;
+ end; //if
+
+ 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);
+ 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);
+ SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text);
+ 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);
+ SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text);
+ SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text);
+ 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);
+ SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text);
+ 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);
+ SingDrawLineBonus( Player[3].LineBonus_PosX, Player[3].LineBonus_PosY, Player[3].LineBonus_Color, Player[3].LineBonus_Alpha, Player[3].LineBonus_Text);
+ 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);
+ SingDrawLineBonus( Player[1].LineBonus_PosX, Player[1].LineBonus_PosY, Player[1].LineBonus_Color, Player[1].LineBonus_Alpha, Player[1].LineBonus_Text);
+ SingDrawLineBonus( Player[2].LineBonus_PosX, Player[2].LineBonus_PosY, Player[2].LineBonus_Color, Player[2].LineBonus_Alpha, Player[2].LineBonus_Text);
+ 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);
+ SingDrawLineBonus( Player[4].LineBonus_PosX, Player[4].LineBonus_PosY, Player[4].LineBonus_Color, Player[4].LineBonus_Alpha, Player[4].LineBonus_Text);
+ SingDrawLineBonus( Player[5].LineBonus_PosX, Player[5].LineBonus_PosY, Player[5].LineBonus_Color, Player[5].LineBonus_Alpha, Player[5].LineBonus_Text);
+ end;
+ end;
+ end;
+ //PhrasenBonus - Line Bonus Mod End
+
+
+ // rysuje paski
+// Log.LogStatus('Original notes', 'SingDraw');
+ 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 PlayersPlay = 1 then begin
+ SingDrawPlayerBGCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 0, 15);
+ SingDrawCzesc(NR.Left + 20, Skin_P2_NotesB, NR.Right - 20, 0, 15);
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 0, 15);
+ 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, 0, 15);
+
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P1_NotesB, Nr.Width - 40, 0, 15);
+ SingDrawPlayerCzesc(Nr.Left + 20, Skin_P2_NotesB, Nr.Width - 40, 1, 15);
+ 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, 0, 12);
+ SingDrawCzesc(NR.Left + 20, 370+95, NR.Right - 20, 0, 12);
+
+ SingDrawPlayerCzesc(Nr.Left + 20, 120+95, Nr.Width - 40, 0, 12);
+ SingDrawPlayerCzesc(Nr.Left + 20, 245+95, Nr.Width - 40, 1, 12);
+ SingDrawPlayerCzesc(Nr.Left + 20, 370+95, Nr.Width - 40, 2, 12);
+ 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;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+end;
+
+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;
+
+ // background //BG Fullsize Mod
+ //SingDrawBackground;
+
+ // time bar
+// Log.LogStatus('Time Bar', 'SingDraw');
+ glBegin(GL_QUADS);
+ glColor3f(0.9, 0.9, 0.9);
+ glVertex2f(140 + 10*ScreenX, 21);
+ glVertex2f(140 + 10*ScreenX, 29);
+ glVertex2f(330 + 10*ScreenX, 29);
+ glVertex2f(330 + 10*ScreenX, 21);
+ glColor3f(Skin_TimeR, Skin_TimeG, Skin_TimeB);
+ glVertex2f(140 + 10*ScreenX, 21);
+ glVertex2f(140 + 10*ScreenX, 29);
+ glVertex2f(140 + 10*ScreenX+(330-140)*(Czas.Teraz/Czas.Razem), 29);
+ glVertex2f(140 + 10*ScreenX+(330-140)*(Czas.Teraz/Czas.Razem), 21);
+ glEnd;
+
+ if DLLMan.Selected.ShowNotes then
+ begin
+ // 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;
+ end;
+
+ // rysuje tekst - new 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 *
+ // (NR.WMid - Czesci[0].Czesc[Czesci[0].Akt].LyricWidth / 2 * FS - 50);
+ (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;
+
+ // 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_BLEND);
+ glBegin(GL_QUADS);
+ glColor4f(26/255, 165/255, 220/255, 0);
+ glVertex2f(Rec.Left, Rec.Top);
+ glVertex2f(Rec.Left, Rec.Bottom);
+ glColor4f(26/255, 165/255, 220/255, BarAlpha);
+ glVertex2f(Rec.Right, Rec.Bottom);
+ glVertex2f(Rec.Right, Rec.Top);
+ glEnd;
+ glDisable(GL_BLEND);
+ end;
+
+ // oscilloscope
+ 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
+ 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( 75 + 10*ScreenX, 95, 100, 8, Player[0].ScorePercent);
+ end;
+ if PlayersPlay = 2 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawSingbar( 75 + 10*ScreenX, 95, 100, 8, Player[0].ScorePercent);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawSingbar(620 + 10*ScreenX, 95, 100, 8, Player[1].ScorePercent);
+ end;
+ if PlayersPlay = 3 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawSingbar( 75 + 10*ScreenX, 95, 100, 8, Player[0].ScorePercent);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawSingbar(370 + 10*ScreenX, 95, 100, 8, Player[1].ScorePercent);
+ if PlayerInfo.Playerinfo[2].Enabled then
+ SingDrawSingbar(670 + 10*ScreenX, 95, 100, 8, Player[2].ScorePercent);
+ end;
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawSingbar( 75 + 10*ScreenX, 95, 100, 8, Player[0].ScorePercent);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawSingbar(620 + 10*ScreenX, 95, 100, 8, Player[1].ScorePercent);
+ end;
+ if ScreenAct = 2 then begin
+ if PlayerInfo.Playerinfo[2].Enabled then
+ SingDrawSingbar( 75 + 10*ScreenX, 95, 100, 8, Player[2].ScorePercent);
+ if PlayerInfo.Playerinfo[3].Enabled then
+ SingDrawSingbar(620 + 10*ScreenX, 95, 100, 8, Player[3].ScorePercent);
+ end;
+ end;
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ if PlayerInfo.Playerinfo[0].Enabled then
+ SingDrawSingbar( 75 + 10*ScreenX, 95, 100, 8, Player[0].ScorePercent);
+ if PlayerInfo.Playerinfo[1].Enabled then
+ SingDrawSingbar(370 + 10*ScreenX, 95, 100, 8, Player[1].ScorePercent);
+ if PlayerInfo.Playerinfo[2].Enabled then
+ SingDrawSingbar(670 + 10*ScreenX, 95, 100, 8, Player[2].ScorePercent);
+ end;
+ if ScreenAct = 2 then begin
+ if PlayerInfo.Playerinfo[3].Enabled then
+ SingDrawSingbar( 75 + 10*ScreenX, 95, 100, 8, Player[3].ScorePercent);
+ if PlayerInfo.Playerinfo[4].Enabled then
+ SingDrawSingbar(370 + 10*ScreenX, 95, 100, 8, Player[4].ScorePercent);
+ if PlayerInfo.Playerinfo[5].Enabled then
+ SingDrawSingbar(670 + 10*ScreenX, 95, 100, 8, 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
+ Player[E].LineBonus_Visible := False
+ else
+ begin
+ //Change Position
+ if (Player[E].LineBonus_PosX < Player[E].LineBonus_TargetX) then
+ Inc(Player[E].LineBonus_PosX,1)
+ else if (Player[E].LineBonus_PosX > Player[E].LineBonus_TargetX) then
+ Dec(Player[E].LineBonus_PosX,1);
+
+ if (Player[E].LineBonus_PosY < Player[E].LineBonus_TargetY) then
+ Inc(Player[E].LineBonus_PosY,1)
+ else if (Player[E].LineBonus_PosY > Player[E].LineBonus_TargetY) then
+ Dec(Player[E].LineBonus_PosY,1);
+
+ end;
+ end;
+ end; //if
+
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ 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);
+ end;
+ end;
+ end;
+ //PhrasenBonus - Line Bonus Mod End
+
+
+ // rysuje paski
+// Log.LogStatus('Original notes', 'SingDraw');
+ 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(1/16, 0); glVertex2f(X, Y);
+ glTexCoord2f(1/16, 1); glVertex2f(X, Y+H);
+ glTexCoord2f(1 - 1/16, 1); glVertex2f(X+W, Y+H);
+ glTexCoord2f(1 - 1/16, 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(1/16, 0); glVertex2f(X, Y);
+ glTexCoord2f(1/16, 1); glVertex2f(X, Y+H);
+ glTexCoord2f(1 - 1/16, 1); glVertex2f(X+(W/100 * (Percent +1)), Y+H);
+ glTexCoord2f(1 - 1/16, 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 Mod
+procedure SingDrawLineBonus( const X, Y: integer; Color: TRGB; Alpha: Single; Text: string);
+var
+Length, X2: Real; //Length of Text
+begin
+if Alpha <> 0 then
+begin
+
+//Set Font Propertys
+SetFontStyle(2); //Font: Outlined1
+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
+
+ //Draw Background
+ glColor4f(Color.R, Color.G, Color.B, Alpha); //Set Color
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ //Old Method with Variable Background
+ {//Draw Left Side
+ glBindTexture(GL_TEXTURE_2D, Tex_SingLineBonusL.TexNum);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(X, Y);
+ glTexCoord2f(0, 1); glVertex2f(X, Y + Tex_SingLineBonusL.H * Tex_SingLineBonusL.ScaleH);
+ glTexCoord2f(1, 1); glVertex2f(X + Tex_SingLineBonusL.W * Tex_SingLineBonusL.scaleW, Y + Tex_SingLineBonusL.H * Tex_SingLineBonusL.scaleH);
+ glTexCoord2f(1, 0); glVertex2f(X + Tex_SingLineBonusL.W * Tex_SingLineBonusL.scaleW, Y);
+ glEnd;
+
+ //Set X of Next Tile
+ X2 := X + Tex_SingLineBonusL.W * Tex_SingLineBonusL.scaleW;
+
+ //Draw Middle
+ glBindTexture(GL_TEXTURE_2D, Tex_SingLineBonusM.TexNum);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(X2, Y);
+ glTexCoord2f(0, 1); glVertex2f(X2, Y + Tex_SingLineBonusM.H * Tex_SingLineBonusM.ScaleH);
+ glTexCoord2f(1, 1); glVertex2f(X2 + Length, Y + Tex_SingLineBonusM.H * Tex_SingLineBonusM.scaleH);
+ glTexCoord2f(1, 0); glVertex2f(X2 + Length, Y);
+ glEnd;
+
+ //Set X of Next Tile
+ X2 := X2 + Length;
+
+ //Draw Rigth Side
+ glBindTexture(GL_TEXTURE_2D, Tex_SingLineBonusR.TexNum);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex2f(X2, Y);
+ glTexCoord2f(0, 1); glVertex2f(X2, Y + Tex_SingLineBonusR.H * Tex_SingLineBonusR.ScaleH);
+ glTexCoord2f(1, 1); glVertex2f(X2 + Tex_SingLineBonusR.W * Tex_SingLineBonusR.scaleW, Y + Tex_SingLineBonusR.H * Tex_SingLineBonusR.scaleH);
+ glTexCoord2f(1, 0); glVertex2f(X2 + Tex_SingLineBonusR.W * Tex_SingLineBonusR.scaleW, Y);
+ glEnd;}
+ //New Method, Not Variable
+ glBindTexture(GL_TEXTURE_2D, Tex_SingLineBonusBack.TexNum);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(1/32, 0); glVertex2f(X, Y);
+ glTexCoord2f(1/32, 1); glVertex2f(X, Y + 50);
+ glTexCoord2f(31/32, 1); glVertex2f(X + 100, Y + 50);
+ glTexCoord2f(31/32, 0); glVertex2f(X + 100, Y);
+ 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(7/8, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(7/8, 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(1/32, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(1/32, 1); glVertex2f(Rec.Left, Rec.Bottom);
+ glTexCoord2f(31/32, 1); glVertex2f(Rec.Right, Rec.Bottom);
+ glTexCoord2f(31/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_Right[Color].TexNum);
+ glBegin(GL_QUADS);
+ glTexCoord2f(1/8, 0); glVertex2f(Rec.Left, Rec.Top);
+ glTexCoord2f(1/8, 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;
+
+end.
+
diff --git a/Game/Code/Classes/UFiles.dcu b/Game/Code/Classes/UFiles.dcu
new file mode 100644
index 00000000..9ed45d8f
--- /dev/null
+++ b/Game/Code/Classes/UFiles.dcu
Binary files differ
diff --git a/Game/Code/Classes/UFiles.pas b/Game/Code/Classes/UFiles.pas
new file mode 100644
index 00000000..61fdab03
--- /dev/null
+++ b/Game/Code/Classes/UFiles.pas
@@ -0,0 +1,326 @@
+unit UFiles;
+
+interface
+
+uses USongs, SysUtils, ULog, UMusic;
+
+//procedure InitializePaths; //Function sets All Absolute Paths eg. for Songs
+function ReadTXTHeader(var Song: TSong): boolean; //Reads Standard TXT Header
+function AnalyseFile(var Song: TSong): boolean; //Analyse Song File and Read Header
+procedure ClearSong(var Song: TSong); //Clears Song Header values
+
+//procedure CzyscNuty;
+//function WczytajCzesci(Name: string): boolean;
+//function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean;
+//function SaveSongDebug(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean;
+
+var
+ {//Absolute Paths
+ GamePath: string;
+ SoundPath: string;
+ SongPath: string;
+ LogPath: string;
+ ThemePath: string;
+ ScreenshotsPath: string;
+ CoversPath: string;
+ LanguagesPath: string; //}
+
+ SongFile: TextFile; // all procedures in this unit operates on this file
+ FileLineNo: integer; //Line which is readed at Last, for error reporting
+
+ {// variables available for all procedures
+ Base: array[0..1] of integer;
+ Rel: array[0..1] of integer;//}
+ Mult: integer = 1;
+ MultBPM: integer = 4;
+
+implementation
+uses TextGL, UIni, UMain, UPliki;
+
+ //Function sets All Absolute Paths eg. for Songs
+{procedure InitializePaths;
+begin
+ GamePath := ExtractFilePath(ParamStr(0));
+ SoundPath := GamePath + 'Sounds\';
+ SongPath := GamePath + 'Songs\';
+ LogPath := GamePath;
+ ThemePath := GamePath + 'Themes\';
+ ScreenshotsPath := GamePath + 'Screenshots\';
+ CoversPath := GamePath + 'Covers\';
+ LanguagesPath := GamePath + 'Languages\';
+
+ DecimalSeparator := ',';
+end;}
+
+ //Clears Song Header values
+procedure ClearSong(var Song: TSong);
+begin
+ //Main Information
+ Song.Title := '';
+ Song.Artist := '';
+
+ //Sortings:
+ Song.Genre := 'Unknown';
+ Song.Edition := 'Unknown';
+ Song.Language := 'Unknown'; //Language Patch
+
+ //Required Information
+ Song.Mp3 := '';
+ Song.BPM := 0;
+ Song.GAP := 0;
+ Song.Start := 0;
+ Song.Finish := 0;
+
+ //Additional Information
+ Song.Background := '';
+ Song.Video := '';
+ Song.VideoGAP := 0;
+ Song.NotesGAP := 0;
+ Song.Resolution := 4;
+ Song.Creator := '';
+end;
+
+ //Reads Standard TXT Header
+function ReadTXTHeader(var Song: TSong): boolean;
+var
+Line, Identifier, Value: String;
+Temp: word;
+Done: byte;
+begin
+ Result := true;
+
+ //Read first Line
+ ReadLn (SongFile, Line);
+
+ if (Length(Line)<=0) then
+ begin
+ Log.LogError('File Starts with Empty Line: ' + Song.FileName);
+ Result := False;
+ Exit;
+ end;
+
+ //Read Lines while Line starts with #
+ While (Line[1] = '#') do
+ begin
+ //Increase Line Number
+ Inc (FileLineNo);
+ Temp := Pos(':', Line);
+
+ //Line has a Seperator-> Headerline
+ if (Temp <> 0) then
+ begin
+ //Read Identifier and Value
+ Identifier := Uppercase(Trim(Copy(Line, 2, Temp - 2))); //Uppercase is for Case Insensitive Checks
+ Value := Trim(Copy(Line, Temp + 1,Length(Line) - Temp));
+
+ //Check the Identifier (If Value is given)
+ if (Length(Value) <> 0) then
+ begin
+
+ //-----------
+ //Required Attributes
+ //-----------
+
+ //Title
+ if (Identifier = 'TITLE') then
+ begin
+ Song.Title := Value;
+
+ //Add Title Flag to Done
+ Done := Done or 1;
+ end
+
+ //Artist
+ else if (Identifier = 'ARTIST') then
+ begin
+ Song.Artist := Value;
+
+ //Add Artist Flag to Done
+ Done := Done or 2;
+ end
+
+ //MP3 File //Test if Exists
+ else if (Identifier = 'MP3') AND (FileExists(Song.Path + Value)) then
+ begin
+ Song.Mp3 := Value;
+
+ //Add Mp3 Flag to Done
+ Done := Done or 4;
+ end
+
+ //Beats per Minute
+ else if (Identifier = 'BPM') then
+ begin
+ // Replace . with ,
+ if (Pos('.', Value) <> 0) then
+ Value[Pos('.', Value)] := ',';
+
+ SetLength(Song.BPM, 1);
+ Song.BPM[0].StartBeat := 0;
+
+ Song.BPM[0].BPM := StrtoFloatDef(Value, 0) * Mult * MultBPM;
+
+ if Song.BPM[0].BPM <> 0 then
+ begin
+ //Add BPM Flag to Done
+ Done := Done or 8;
+ end;
+ end
+
+ //---------
+ //Additional Header Information
+ //---------
+
+ //Cover Picture
+ else if (Identifier = 'COVER') then
+ begin
+ Song.Cover := Value;
+ end
+
+ //Background Picture
+ else if (Identifier = 'BACKGROUND') then
+ begin
+ Song.Background := Value;
+ end
+
+ // Video File
+ else if (Identifier = 'VIDEO') then
+ begin
+ Song.Video := Value;
+ end
+
+ // Video Gap
+ else if (Identifier = 'VIDEOGAP') then
+ begin
+ // Replace . with ,
+ if (Pos('.', Value) <> 0) then
+ Value[Pos('.', Value)] := ',';
+
+ Song.VideoGAP := StrtoFloatDef (Value, 0);
+ end
+
+ //Genre Sorting
+ else if (Identifier = 'GENRE') then
+ begin
+ Song.Genre := Value;
+ end
+
+ //Edition Sorting
+ else if (Identifier = 'EDITION') then
+ begin
+ Song.Edition := Value;
+ end
+
+ //Creator Tag
+ else if (Identifier = 'CREATOR') then
+ begin
+ Song.Creator := Value;
+ end
+
+ //Language Sorting
+ else if (Identifier = 'LANGUAGE') then
+ begin
+ Song.Language := Value;
+ end
+
+ // Song Start
+ else if (Identifier = 'START') then
+ begin
+ // Replace . with ,
+ if (Pos('.', Value) <> 0) then
+ Value[Pos('.', Value)] := ',';
+
+ Song.Start := StrtoFloatDef(Value, 0);
+ end
+
+ // Song Ending
+ else if (Identifier = 'END') then
+ begin
+ TryStrtoInt(Value, Song.Finish);
+ end
+
+ // Resolution
+ else if (Identifier = 'RESOLUTION') then
+ begin
+ TryStrtoInt(Value, Song.Resolution);
+ end
+
+ // Notes Gap
+ else if (Identifier = 'NOTESGAP') then
+ begin
+ TryStrtoInt(Value, Song.NotesGAP);
+ end
+
+ // Relative Notes
+ else if (Identifier = 'RELATIVE') AND (uppercase(Value) = 'YES') then
+ begin
+ Song.Relative := True;
+ end;
+
+ end;
+ end;
+
+ if not EOf(SongFile) then
+ ReadLn (SongFile, Line)
+ else
+ begin
+ Result := False;
+ Log.LogError('File Incomplete or not Ultrastar TxT: ' + Song.FileName);
+ break;
+ end;
+
+ //End on first empty Line
+ if (Length(Line) = 0) then
+ break;
+ end;
+
+ //Check if all Required Values are given
+ if (Done <> 15) then
+ begin
+ Result := False;
+ if (Done and 8) = 0 then //No BMP Flag
+ Log.LogError('BMP Tag Missing: ' + Song.FileName)
+ else if (Done and 4) = 0 then //No MP3 Flag
+ Log.LogError('MP3 Tag/File Missing: ' + Song.FileName)
+ else if (Done and 2) = 0 then //No Artist Flag
+ Log.LogError('Artist Tag Missing: ' + Song.FileName)
+ else if (Done and 1) = 0 then //No Title Flag
+ Log.LogError('Title Tag Missing: ' + Song.FileName)
+ else //unknown Error
+ Log.LogError('File Incomplete or not Ultrastar TxT: ' + Song.FileName);
+ end;
+
+end;
+
+ //Analyse Song File and Read Header
+function AnalyseFile(var Song: TSong): boolean;
+begin
+Result := False;
+{try }
+ //Reset LineNo
+ FileLineNo := 0;
+
+ //Open File and set File Pointer to the beginning
+ AssignFile(SongFile, Song.Path + Song.FileName);
+ Reset(SongFile);
+
+ //Clear old Song Header
+ ClearSong(Song);
+
+ //Read Header
+ Result := ReadTxTHeader(Song);
+
+ //And Close File
+ CloseFile(SongFile);
+{except
+ CloseFile(SongFile);
+
+ Result := False;
+ //Error Reporting
+ Log.LogError('An Error occured reading Line ' + inttostr(FileLineNo) + ' from SongHeader: ' + Song.FileName);
+end;}
+end;
+
+
+
+end. \ No newline at end of file
diff --git a/Game/Code/Classes/UGraphic.dcu b/Game/Code/Classes/UGraphic.dcu
new file mode 100644
index 00000000..c264b16b
--- /dev/null
+++ b/Game/Code/Classes/UGraphic.dcu
Binary files differ
diff --git a/Game/Code/Classes/UGraphic.pas b/Game/Code/Classes/UGraphic.pas
new file mode 100644
index 00000000..05a9fda7
--- /dev/null
+++ b/Game/Code/Classes/UGraphic.pas
@@ -0,0 +1,405 @@
+unit UGraphic;
+
+interface
+uses
+ SDL, OpenGL12, UTexture, TextGL, ULog, SysUtils, ULyrics, UScreenLoading,
+ UScreenWelcome, UScreenMain, UScreenName, UScreenLevel, UScreenOptions, UScreenOptionsGame,
+ UScreenOptionsGraphics, UScreenOptionsSound, UScreenOptionsLyrics, UScreenOptionsThemes, UScreenOptionsRecord,
+ UScreenSong, UScreenSing, UScreenScore, UScreenTop5, UScreenEditSub,
+ UScreenEdit, UScreenEditConvert, UScreenEditHeader, UScreenOpen, UThemes, USkins, UScreenSongMenu,
+ {Party Screens} UScreenSingModi, UScreenPartyNewRound, UScreenPartyScore, UScreenPartyOptions, UScreenPartyWin, UScreenPartyPlayer;
+
+type
+ TRecR = record
+ Top: real;
+ Left: real;
+ Right: real;
+ Bottom: real;
+ end;
+
+var
+ Screen: PSDL_Surface;
+
+ 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;
+ ScreenEditSub: TScreenEditSub;
+ ScreenEdit: TScreenEdit;
+ ScreenEditConvert: TScreenEditConvert;
+ ScreenEditHeader: TScreenEditHeader;
+ ScreenOpen: TScreenOpen;
+
+ ScreenSongMenu: TScreenSongMenu;
+
+ //Party Screens
+ ScreenSingModi: TScreenSingModi;
+ ScreenPartyNewRound: TScreenPartyNewRound;
+ ScreenPartyScore: TScreenPartyScore;
+ ScreenPartyWin: TScreenPartyWin;
+ ScreenPartyOptions: TScreenPartyOptions;
+ ScreenPartyPlayer: TScreenPartyPlayer;
+
+
+ Tex_Left: array[0..6] of TTexture;
+ Tex_Mid: array[0..6] of TTexture;
+ Tex_Right: array[0..6] of TTexture;
+
+ Tex_BG_Left: array[1..6] of TTexture;
+ Tex_BG_Mid: array[1..6] of TTexture;
+ Tex_BG_Right: array[1..6] of TTexture;
+
+ Tex_Note_Star: TTexture;
+
+ Tex_Ball: TTexture;
+ FullScreen: boolean;
+
+
+
+ //Sing Bar Mod
+ Tex_SingBar_Back: TTexture;
+ Tex_SingBar_Bar: TTexture;
+ Tex_SingBar_Front: TTexture;
+ //end Singbar Mod
+
+ //PhrasenBonus - Line Bonus Mod
+ Tex_SingLineBonusBack: 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 = 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 LoadScreens;
+
+
+implementation
+uses UMain, UIni, UDisplay;
+
+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);
+ Tex_Mid[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayMid')), 'BMP', 'Plain', 0);
+ Tex_Right[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayRight')), 'BMP', 'Transparent', 0);
+
+ // 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')), 'BMP', 'Note Transparent', Col);
+ Tex_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayMid')), 'BMP', 'Note Plain', Col);
+ Tex_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayRight')), 'BMP', 'Note Transparent', Col);
+
+ Tex_BG_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGLeft')), 'BMP', 'Alpha Black Colored', Col);
+ Tex_BG_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGMid')), 'BMP', 'Alpha Black Colored', Col);
+ Tex_BG_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGRight')), 'BMP', 'Alpha Black Colored', Col);
+ end;
+
+ Tex_Note_Star := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteStar')), 'JPG', 'Font Black', 0);
+ Tex_Ball := Texture.LoadTexture(pchar(Skin.GetTextureFileName('Ball')), 'BMP', 'Transparent', $FF00FF);
+
+
+
+ //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
+
+ //PhrasenBonus - Line Bonus Mod
+ Tex_SingLineBonusBack := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LineBonusBack')), 'JPG', 'Font Black', 0);
+ {//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);
+begin
+ Log.LogStatus('LoadOpenGL', 'Initialize3D');
+ Log.BenchmarkStart(2);
+
+ LoadOpenGL;
+
+// SDL_WM_SetIcon(SDL_LoadBMP('..\Graphics\us.ico'),0);
+
+ 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;
+
+ SDL_WM_SetCaption(PChar(Title), 'WM_DEFAULT');
+
+ 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);
+
+ LoadScreens;
+ 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, 800, 600, 0, -1, 100);
+ glMatrixMode(GL_MODELVIEW);
+end;
+
+procedure Reinitialize3D;
+begin
+// InitializeScreen;
+// LoadTextures;
+// LoadScreens;
+end;
+
+procedure InitializeScreen;
+var
+ S: string;
+ I: integer;
+ W, H: integer;
+begin
+ 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);
+
+ 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;
+
+
+ Log.LogStatus('SDL_SetVideoMode', 'Initialize3D');
+// SDL_SetRefreshrate(85);
+// SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+ if (Ini.FullScreen = 0) and (ParamStr(1) <> '-fsblack') then
+ screen := SDL_SetVideoMode(W, H, (Ini.Depth+1) * 16, SDL_OPENGL)
+ else begin
+ screen := SDL_SetVideoMode(W, H, (Ini.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 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);
+ 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 SongMenu', 3); Log.BenchmarkStart(3);
+ //ScreenSongMenu := TScreenSongMenu.Create;
+ Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing with Modi support', 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);
+end;
+
+end.
diff --git a/Game/Code/Classes/UGraphicClasses.dcu b/Game/Code/Classes/UGraphicClasses.dcu
new file mode 100644
index 00000000..58d003b0
--- /dev/null
+++ b/Game/Code/Classes/UGraphicClasses.dcu
Binary files differ
diff --git a/Game/Code/Classes/UGraphicClasses.pas b/Game/Code/Classes/UGraphicClasses.pas
new file mode 100644
index 00000000..abb59e4b
--- /dev/null
+++ b/Game/Code/Classes/UGraphicClasses.pas
@@ -0,0 +1,7 @@
+unit UGraphicClasses;
+
+interface
+
+implementation
+
+end.
diff --git a/Game/Code/Classes/UIni.dcu b/Game/Code/Classes/UIni.dcu
new file mode 100644
index 00000000..e891d36c
--- /dev/null
+++ b/Game/Code/Classes/UIni.dcu
Binary files differ
diff --git a/Game/Code/Classes/UIni.pas b/Game/Code/Classes/UIni.pas
new file mode 100644
index 00000000..beadabb6
--- /dev/null
+++ b/Game/Code/Classes/UIni.pas
@@ -0,0 +1,693 @@
+unit UIni;
+
+interface
+uses IniFiles, ULog, SysUtils;
+
+type
+ TIni = class
+ Name: array[0..5] of string;
+
+ // Game
+ Players: integer;
+ Difficulty: integer;
+ Language: integer;
+ Tabs: integer;
+ Tabs_at_startup:integer; //Tabs at Startup fix
+ Sorting: integer;
+ Debug: integer;
+
+ // Graphics
+ Screens: integer;
+ Resolution: integer;
+ Depth: integer;
+ FullScreen: integer;
+ TextureSize: integer;
+ SingWindow: integer;
+ Oscilloscope: integer;
+ Spectrum: integer;
+ Spectrograph: integer;
+ MovieSize: integer;
+ //LineBonus Mod
+ LineBonus: integer;
+ //GMA Fix
+ GMAFix: integer;
+
+
+ // Sound
+ MicBoost: integer;
+ ClickAssist: integer;
+ BeatClick: integer;
+ SavePlayback: integer;
+ Threshold: integer;
+ //TwoPlayerMode: integer;
+
+ // Lyrics
+ LyricsFont: integer;
+ LyricsEffect: integer;
+ Solmization: integer;
+
+ // Themes
+ Theme: integer;
+ SkinNo: integer;
+ Color: integer;
+
+ // Record
+ Card: integer; // not saved in config.ini
+
+ CardList: array of record
+ Name: string;
+ Input: integer;
+ ChannelL: integer;
+ ChannelR: integer;
+ end;
+
+ // Controller
+ Joypad: integer;
+
+ // Soundcards
+ SoundCard: array[0..7, 1..2] of integer;
+
+ // Devices
+ LPT: integer;
+
+ procedure Load;
+ procedure Save;
+ procedure SaveNames;
+ procedure SaveLevel;
+ end;
+
+
+var
+ Ini: TIni;
+ IResolution: array of string;
+ ILanguage: array of string;
+ ITheme: array of string;
+ ISkin: array of string;
+ ICard: array of string;
+ IInput: array of string;
+
+const
+ IPlayers: array[0..4] of string = ('1', '2', '3', '4', '6');
+ IDifficulty: array[0..2] of string = ('Easy', 'Medium', 'Hard');
+ ITabs: array[0..1] of string = ('Off', 'On');
+
+ ISorting: array[0..7] of string = ('Edition', 'Genre', 'Language', 'Folder', 'Title', 'Artist', 'Title2', 'Artist2');
+ sEdition = 0;
+ sGenre = 1;
+ sLanguage = 2;
+ sFolder = 3;
+ sTitle = 4;
+ sArtist = 5;
+ sTitle2 = 6;
+ sArtist2 = 7;
+
+ IDebug: array[0..1] of string = ('Off', 'On');
+
+ IScreens: array[0..1] of string = ('1', '2');
+ IFullScreen: array[0..1] of string = ('Off', 'On');
+ IDepth: array[0..1] of string = ('16 bit', '32 bit');
+ ITextureSize: array[0..2] of string = ('128', '256', '512');
+ ISingWindow: array[0..1] of string = ('Small', 'Big');
+
+ //SingBar Mod
+ IOscilloscope: array[0..2] of string = ('Off', 'Osci', 'Bar');
+ //IOscilloscope: array[0..1] of string = ('Off', 'On');
+
+ //Line Bonus MOd
+ ILineBonus: array[0..2] of string = ('Off', 'At Score', 'At Notes');
+ //GMA Fix
+ IGMAFix: array[0..1] of string = ('Off', 'On');
+
+ ISpectrum: array[0..1] of string = ('Off', 'On');
+ ISpectrograph: array[0..1] of string = ('Off', 'On');
+ IMovieSize: array[0..1] of string = ('Half', 'Full');
+
+ IMicBoost: array[0..3] of string = ('Off', '+6dB', '+12dB', '+18dB');
+ IClickAssist: array[0..1] of string = ('Off', 'On');
+ IBeatClick: array[0..1] of string = ('Off', 'On');
+ ISavePlayback: array[0..1] of string = ('Off', 'On');
+ IThreshold: array[0..3] of string = ('5%', '10%', '15%', '20%');
+ //ITwoPlayerMode: array[0..2] of string = ('Stereo', '2 Cards', 'Advanced');
+
+ ILyricsFont: array[0..2] of string = ('Plain', 'OLine1', 'OLine2');
+ ILyricsEffect: array[0..3] of string = ('Simple', 'Zoom', 'Slide', 'Ball');
+ ISolmization: array[0..3] of string = ('Off', 'Euro', 'Jap', 'American');
+
+ IColor: array[0..8] of string = ('Blue', 'Green', 'Pink', 'Red', 'Violet', 'Orange', 'Yellow', 'Brown', 'Black');
+
+ IJoypad: array[0..1] of string = ('Off', 'On');
+ ILPT: array[0..2] of string = ('Off', 'LCD', 'Lights');
+
+ IChannel: array[0..6] of string = ('0', '1', '2', '3', '4', '5', '6');
+
+implementation
+uses UPliki, SDL, ULanguage, USkins, URecord;
+
+procedure TIni.Load;
+var
+ IniFile: TMemIniFile;
+ ThemeIni: TMemIniFile;
+ Tekst: string;
+ Pet: integer;
+ B: boolean;
+ I, I2, I3: integer;
+ S: string;
+ Modes: PPSDL_Rect;
+ SR: TSearchRec; //Skin List Patch
+
+function GetFileName (S: String):String;
+ begin
+ //Result := copy (S,0,StrRScan (PChar(S),char('.'))+1);
+ Result := copy (S,0,Pos ('.ini',S)-1);
+ end;
+
+begin
+ GamePath := ExtractFilePath(ParamStr(0));
+ IniFile := TMemIniFile.Create(GamePath + 'config.ini');
+
+ // Name
+ for I := 0 to 5 do
+ Ini.Name[I] := IniFile.ReadString('Name', 'P'+IntToStr(I+1), 'Player'+IntToStr(I+1));
+
+ // Players
+ Tekst := IniFile.ReadString('Game', 'Players', IPlayers[0]);
+ for Pet := 0 to High(IPlayers) do
+ if Tekst = IPlayers[Pet] then Ini.Players := Pet;
+
+ // Difficulty
+ Tekst := IniFile.ReadString('Game', 'Difficulty', 'Easy');
+ for Pet := 0 to High(IDifficulty) do
+ if Tekst = IDifficulty[Pet] then Ini.Difficulty := Pet;
+
+ // Language
+ Tekst := IniFile.ReadString('Game', 'Language', 'English');
+ for Pet := 0 to High(ILanguage) do
+ if Tekst = ILanguage[Pet] then Ini.Language := Pet;
+
+// Language.ChangeLanguage(ILanguage[Ini.Language]);
+
+ // Tabs
+ Tekst := IniFile.ReadString('Game', 'Tabs', ITabs[0]);
+ for Pet := 0 to High(ITabs) do
+ if Tekst = ITabs[Pet] then Ini.Tabs := Pet;
+
+ //Tabs at Startup fix
+ Ini.Tabs_at_startup := Ini.Tabs;
+
+ // Sorting
+ Tekst := IniFile.ReadString('Game', 'Sorting', ISorting[0]);
+ for Pet := 0 to High(ISorting) do
+ if Tekst = ISorting[Pet] then Ini.Sorting := Pet;
+
+ // Debug
+ Tekst := IniFile.ReadString('Game', 'Debug', IDebug[0]);
+ for Pet := 0 to High(IDebug) do
+ if Tekst = IDebug[Pet] then Ini.Debug := Pet;
+
+ //if Ini.Debug = 1 then SongPath := 'E:\UltraStar 03\Songs\';
+
+ // Screens
+ Tekst := IniFile.ReadString('Graphics', 'Screens', IScreens[0]);
+ for Pet := 0 to High(IScreens) do
+ if Tekst = IScreens[Pet] then Ini.Screens := Pet;
+
+ // Resolution
+ SetLength(IResolution, 0);
+ Modes := SDL_ListModes(nil, SDL_OPENGL or SDL_FULLSCREEN); // Check if there are any modes available
+ repeat
+// Log.LogError(Format( ' %d x %d', [ modes^.w, modes^.h ] ) );
+ SetLength(IResolution, Length(IResolution) + 1);
+ IResolution[High(IResolution)] := IntToStr(Modes^.w) + 'x' + IntToStr(Modes^.h);
+ Inc(Modes);
+ until Modes^ = nil;
+
+ // reverse order
+ for I := 0 to (Length(IResolution) div 2) - 1 do begin
+ S := IResolution[I];
+ IResolution[I] := IResolution[High(IResolution)-I];
+ IResolution[High(IResolution)-I] := S;
+ end;
+
+ Tekst := IniFile.ReadString('Graphics', 'Resolution', '800x600');
+ for Pet := 0 to High(IResolution) do
+ if Tekst = IResolution[Pet] then Ini.Resolution := Pet;
+
+ // FullScreen
+ Tekst := IniFile.ReadString('Graphics', 'FullScreen', 'On');
+ for Pet := 0 to High(IFullScreen) do
+ if Tekst = IFullScreen[Pet] then Ini.FullScreen := Pet;
+
+ // Resolution
+ Tekst := IniFile.ReadString('Graphics', 'Depth', '32 bit');
+ for Pet := 0 to High(IDepth) do
+ if Tekst = IDepth[Pet] then Ini.Depth := Pet;
+
+ // Texture Size
+ Tekst := IniFile.ReadString('Graphics', 'TextureSize', ITextureSize[1]);
+ for Pet := 0 to High(ITextureSize) do
+ if Tekst = ITextureSize[Pet] then Ini.TextureSize := Pet;
+
+ // SingWindow
+ Tekst := IniFile.ReadString('Graphics', 'SingWindow', 'Big');
+ for Pet := 0 to High(ISingWindow) do
+ if Tekst = ISingWindow[Pet] then Ini.SingWindow := Pet;
+
+ // Oscilloscope
+ Tekst := IniFile.ReadString('Graphics', 'Oscilloscope', 'Off');
+ for Pet := 0 to High(IOscilloscope) do
+ if Tekst = IOscilloscope[Pet] then Ini.Oscilloscope := Pet;
+
+ // Line Bonus
+ Tekst := IniFile.ReadString('Graphics', 'LineBonus', 'At Score');
+ for Pet := 0 to High(ILineBonus) do
+ if Tekst = ILineBonus[Pet] then Ini.LineBonus := Pet;
+
+ //GMA Fix
+ Tekst := IniFile.ReadString('Graphics', 'GMAFix', 'Off');
+ for Pet := 0 to High(IGMAFix) do
+ if Tekst = IGMAFix[Pet] then Ini.GMAFix := Pet;
+
+ // Spectrum
+ Tekst := IniFile.ReadString('Graphics', 'Spectrum', 'Off');
+ for Pet := 0 to High(ISpectrum) do
+ if Tekst = ISpectrum[Pet] then Ini.Spectrum := Pet;
+
+ // Spectrograph
+ Tekst := IniFile.ReadString('Graphics', 'Spectrograph', 'Off');
+ for Pet := 0 to High(ISpectrograph) do
+ if Tekst = ISpectrograph[Pet] then Ini.Spectrograph := Pet;
+
+ // MovieSize
+ Tekst := IniFile.ReadString('Graphics', 'MovieSize', IMovieSize[0]);
+ for Pet := 0 to High(IMovieSize) do
+ if Tekst = IMovieSize[Pet] then Ini.MovieSize := Pet;
+
+ // MicBoost
+ Tekst := IniFile.ReadString('Sound', 'MicBoost', 'Off');
+ for Pet := 0 to High(IMicBoost) do
+ if Tekst = IMicBoost[Pet] then Ini.MicBoost := Pet;
+
+ // ClickAssist
+ Tekst := IniFile.ReadString('Sound', 'ClickAssist', 'Off');
+ for Pet := 0 to High(IClickAssist) do
+ if Tekst = IClickAssist[Pet] then Ini.ClickAssist := Pet;
+
+ // BeatClick
+ Tekst := IniFile.ReadString('Sound', 'BeatClick', IBeatClick[0]);
+ for Pet := 0 to High(IBeatClick) do
+ if Tekst = IBeatClick[Pet] then Ini.BeatClick := Pet;
+
+ // SavePlayback
+ Tekst := IniFile.ReadString('Sound', 'SavePlayback', ISavePlayback[0]);
+ for Pet := 0 to High(ISavePlayback) do
+ if Tekst = ISavePlayback[Pet] then Ini.SavePlayback := Pet;
+
+ // Threshold
+ Tekst := IniFile.ReadString('Sound', 'Threshold', IThreshold[2]);
+ for Pet := 0 to High(IThreshold) do
+ if Tekst = IThreshold[Pet] then Ini.Threshold := Pet;
+
+ {// Two Player Mode
+ for I := 0 to 7 do begin
+ Ini.SoundCard[I, 1] := 2*I + 1;
+ Ini.SoundCard[I, 2] := 2*I + 2;
+ end;
+
+ Tekst := IniFile.ReadString('Sound', 'TwoPlayerMode', ITwoPlayerMode[0]);
+ for Pet := 0 to High(ITwoPlayerMode) do
+ if Tekst = ITwoPlayerMode[Pet] then Ini.TwoPlayerMode := Pet;
+
+ if Ini.TwoPlayerMode = 1 then begin
+ Ini.SoundCard[0, 1] := 1;
+ Ini.SoundCard[0, 2] := 3;
+ Ini.SoundCard[1, 1] := 2;
+ end;}
+
+ // Lyrics Font
+ Tekst := IniFile.ReadString('Lyrics', 'LyricsFont', ILyricsFont[1]);
+ for Pet := 0 to High(ILyricsFont) do
+ if Tekst = ILyricsFont[Pet] then Ini.LyricsFont := Pet;
+
+ // Lyrics Effect
+ Tekst := IniFile.ReadString('Lyrics', 'LyricsEffect', ILyricsEffect[1]);
+ for Pet := 0 to High(ILyricsEffect) do
+ if Tekst = ILyricsEffect[Pet] then Ini.LyricsEffect := Pet;
+
+ // Solmization
+ Tekst := IniFile.ReadString('Lyrics', 'Solmization', ISolmization[0]);
+ for Pet := 0 to High(ISolmization) do
+ if Tekst = ISolmization[Pet] then Ini.Solmization := Pet;
+
+ // Theme
+ {SetLength(ITheme, 0);
+ if FileExists('Themes\Singstar.ini') then begin
+ SetLength(ITheme, Length(ITheme)+1);
+ ITheme[High(ITheme)] := 'Singstar';
+ end; {
+ if FileExists('Themes\Karin.ini') then begin
+ SetLength(ITheme, Length(ITheme)+1);
+ ITheme[High(ITheme)] := 'Karin';
+ end;}
+
+ //Theme List Patch
+ SetLength(ITheme, 0);
+ FindFirst('Themes\*.ini',faAnyFile,SR);
+ Repeat
+ ThemeIni := TMemIniFile.Create(SR.Name);
+ Tekst := UpperCase(ThemeIni.ReadString('Theme','Name',GetFileName(SR.Name)));
+ ThemeIni.Free;
+ for Pet := low(Skin.Skin) to high(Skin.Skin) do
+ begin
+ if UpperCase(Skin.Skin[Pet].Theme) = Tekst then
+ begin
+ SetLength(ITheme, Length(ITheme)+1);
+ ITheme[High(ITheme)] := GetFileName(SR.Name);
+ break;
+ end;
+ end;
+ Until FindNext(SR) <> 0;
+ FindClose(SR);
+ //Theme List Patch End }
+
+ //No Theme Found
+ if (Length(ITheme)=0) then
+ begin
+ Log.LogError('Could not find any valid Themes.');
+ Halt;
+ end;
+
+
+ Tekst := IniFile.ReadString('Themes', 'Theme', ITheme[0]);
+ Ini.Theme := 0;
+ for Pet := 0 to High(ITheme) do
+ if Uppercase(Tekst) = Uppercase(ITheme[Pet]) then Ini.Theme := Pet;
+
+ // Skin
+ Skin.onThemeChange;
+ Ini.SkinNo := 0;
+
+ Tekst := IniFile.ReadString('Themes', 'Skin', ISkin[0]);
+ for Pet := 0 to High(ISkin) do
+ if Tekst = ISkin[Pet] then Ini.SkinNo := Pet;
+
+ // Color
+ Tekst := IniFile.ReadString('Themes', 'Color', IColor[0]);
+ for Pet := 0 to High(IColor) do
+ if Tekst = IColor[Pet] then Ini.Color := Pet;
+
+ // Record - load ini list
+ SetLength(CardList, 0);
+ I := 1;
+ while (IniFile.ValueExists('Record', 'DeviceName' + IntToStr(I)) = true) do begin
+ //Automatically Delete not Existing Sound Cards
+ S := IniFile.ReadString('Record', 'DeviceName' + IntToStr(I), '');
+ //{
+ B := False;
+ //Look for Soundcard
+ for I2 := 0 to High(Recording.SoundCard) do
+ begin
+ if (S = Trim(Recording.SoundCard[I2].Description)) then
+ begin
+ B := True;
+ Break;
+ end;
+ end;
+
+ if B then
+ begin //}
+ I3 := Length(CardList);
+ SetLength(CardList, I3+1);
+ Ini.CardList[I3].Name := S;
+ Ini.CardList[I3].Input := IniFile.ReadInteger('Record', 'Input' + IntToStr(I), 0);
+ Ini.CardList[I3].ChannelL := IniFile.ReadInteger('Record', 'ChannelL' + IntToStr(I), 0);
+ Ini.CardList[I3].ChannelR := IniFile.ReadInteger('Record', 'ChannelR' + IntToStr(I), 0);
+ end;
+ Inc(I);
+ end;
+
+ Log.LogError(InttoStr(Length(CardList)) + ' Cards Loaded');
+
+ // Record - append detected soundcards
+ for I := 0 to High(Recording.SoundCard) do
+ begin
+ B := False;
+ For I2 := 0 to High(CardList) do
+ begin //Search for Card in List
+ if (CardList[I2].Name = Trim(Recording.SoundCard[I].Description)) then
+ begin
+ B := True;
+ Break;
+ end;
+ end;
+
+ //If not in List -> Add
+ If not B then
+ begin
+ I3 := Length(CardList);
+ SetLength(CardList, I3+1);
+ CardList[I3].Name := Trim(Recording.SoundCard[I].Description);
+ CardList[I3].Input := 0;
+ CardList[I3].ChannelL := 0;
+ CardList[I3].ChannelR := 0;
+ // default for new users
+ if (Length(CardList) = 1) then
+ CardList[I].ChannelL := 1;
+ end;
+ end;
+
+ {for I := 0 to High(Recording.SoundCard) do begin
+
+ B := false;
+ I2 := 0;
+ while ((B = false) and (I2 <= High(CardList))) do
+ if CardList[I2].Name = Recording.SoundCard[I].Description then B := true
+ else Inc(I2);
+
+ // if the card wasn't detected in ini file, append it to the ini list
+ if B = false then begin
+ I3 := Length(CardList);
+ SetLength(CardList, I3+1);
+ CardList[I3].Name := Recording.SoundCard[I].Description;
+ CardList[I3].Input := 0;
+ CardList[I3].ChannelL := 0;
+ CardList[I3].ChannelR := 0;
+ if Length(CardList) = 1 then CardList[I].ChannelL := 1; // default for new users
+ //CardList[I].Input := 2;
+ end;
+ end; }
+
+ Log.LogError(InttoStr(Length(CardList)) + ' Cards Detected');
+
+ // Joypad
+ Tekst := IniFile.ReadString('Controller', 'Joypad', IJoypad[0]);
+ for Pet := 0 to High(IJoypad) do
+ if Tekst = IJoypad[Pet] then Ini.Joypad := Pet;
+
+ // SoundCard
+ for I := 0 to 7 do begin
+ Ini.SoundCard[I, 1] := IniFile.ReadInteger('SoundCards', 'SoundCard'+IntToStr(I+1)+'L', Ini.SoundCard[I, 1]);
+ Ini.SoundCard[I, 2] := IniFile.ReadInteger('SoundCards', 'SoundCard'+IntToStr(I+1)+'R', Ini.SoundCard[I, 2]);
+ end;
+
+ // LCD
+ Tekst := IniFile.ReadString('Devices', 'LPT', ILPT[0]);
+ for Pet := 0 to High(ILPT) do
+ if Tekst = ILPT[Pet] then Ini.LPT := Pet;
+
+
+ // SongPath
+ SongPath := IncludeTrailingPathDelimiter(IniFile.ReadString('Path', 'Songs', SongPath));
+
+
+ IniFile.Free;
+end;
+
+procedure TIni.Save;
+var
+ IniFile: TIniFile;
+ Tekst: string;
+ I: Integer;
+ S: String;
+begin
+ if not (FileExists(GamePath + 'config.ini') and FileIsReadOnly(GamePath + 'config.ini')) then begin
+ IniFile := TIniFile.Create(GamePath + 'config.ini');
+
+ // Players
+ Tekst := IPlayers[Ini.Players];
+ IniFile.WriteString('Game', 'Players', Tekst);
+
+ // Difficulty
+ Tekst := IDifficulty[Ini.Difficulty];
+ IniFile.WriteString('Game', 'Difficulty', Tekst);
+
+ // Language
+ Tekst := ILanguage[Ini.Language];
+ IniFile.WriteString('Game', 'Language', Tekst);
+
+ // Tabs
+ Tekst := ITabs[Ini.Tabs];
+ IniFile.WriteString('Game', 'Tabs', Tekst);
+
+ // Sorting
+ Tekst := ISorting[Ini.Sorting];
+ IniFile.WriteString('Game', 'Sorting', Tekst);
+
+ // Debug
+ Tekst := IDebug[Ini.Debug];
+ IniFile.WriteString('Game', 'Debug', Tekst);
+
+ // Screens
+ Tekst := IScreens[Ini.Screens];
+ IniFile.WriteString('Graphics', 'Screens', Tekst);
+
+ // FullScreen
+ Tekst := IFullScreen[Ini.FullScreen];
+ IniFile.WriteString('Graphics', 'FullScreen', Tekst);
+
+ // Resolution
+ Tekst := IResolution[Ini.Resolution];
+ IniFile.WriteString('Graphics', 'Resolution', Tekst);
+
+ // Depth
+ Tekst := IDepth[Ini.Depth];
+ IniFile.WriteString('Graphics', 'Depth', Tekst);
+
+ // Resolution
+ Tekst := ITextureSize[Ini.TextureSize];
+ IniFile.WriteString('Graphics', 'TextureSize', Tekst);
+
+ // Sing Window
+ Tekst := ISingWindow[Ini.SingWindow];
+ IniFile.WriteString('Graphics', 'SingWindow', Tekst);
+
+ // Oscilloscope
+ Tekst := IOscilloscope[Ini.Oscilloscope];
+ IniFile.WriteString('Graphics', 'Oscilloscope', Tekst);
+
+ //Line Bonus
+ Tekst := ILineBonus[Ini.LineBonus];
+ IniFile.WriteString('Graphics', 'LineBonus', Tekst);
+
+ //GMA Fix
+ Tekst := IGMAFix[Ini.GMAFix];
+ IniFile.WriteString('Graphics', 'GMAFix', Tekst);
+
+ // Spectrum
+ Tekst := ISpectrum[Ini.Spectrum];
+ IniFile.WriteString('Graphics', 'Spectrum', Tekst);
+
+ // Spectrograph
+ Tekst := ISpectrograph[Ini.Spectrograph];
+ IniFile.WriteString('Graphics', 'Spectrograph', Tekst);
+
+ // Movie Size
+ Tekst := IMovieSize[Ini.MovieSize];
+ IniFile.WriteString('Graphics', 'MovieSize', Tekst);
+
+ // MicBoost
+ Tekst := IMicBoost[Ini.MicBoost];
+ IniFile.WriteString('Sound', 'MicBoost', Tekst);
+
+ // ClickAssist
+ Tekst := IClickAssist[Ini.ClickAssist];
+ IniFile.WriteString('Sound', 'ClickAssist', Tekst);
+
+ // BeatClick
+ Tekst := IBeatClick[Ini.BeatClick];
+ IniFile.WriteString('Sound', 'BeatClick', Tekst);
+
+ // Threshold
+ Tekst := IThreshold[Ini.Threshold];
+ IniFile.WriteString('Sound', 'Threshold', Tekst);
+
+ // SavePlayback
+ Tekst := ISavePlayback[Ini.SavePlayback];
+ IniFile.WriteString('Sound', 'SavePlayback', Tekst);
+
+ {// Two Player Mode
+ Tekst := ITwoPlayerMode[Ini.TwoPlayerMode];
+ IniFile.WriteString('Sound', 'TwoPlayerMode', Tekst); }
+
+ // Lyrics Font
+ Tekst := ILyricsFont[Ini.LyricsFont];
+ IniFile.WriteString('Lyrics', 'LyricsFont', Tekst);
+
+ // Lyrics Effect
+ Tekst := ILyricsEffect[Ini.LyricsEffect];
+ IniFile.WriteString('Lyrics', 'LyricsEffect', Tekst);
+
+ // Solmization
+ Tekst := ISolmization[Ini.Solmization];
+ IniFile.WriteString('Lyrics', 'Solmization', Tekst);
+
+ // Theme
+ Tekst := ITheme[Ini.Theme];
+ IniFile.WriteString('Themes', 'Theme', Tekst);
+
+ // Skin
+ Tekst := ISkin[Ini.SkinNo];
+ IniFile.WriteString('Themes', 'Skin', Tekst);
+
+ // Color
+ Tekst := IColor[Ini.Color];
+ IniFile.WriteString('Themes', 'Color', Tekst);
+
+ // Record
+ for I := 0 to High(CardList) do begin
+ S := IntToStr(I+1);
+
+ Tekst := CardList[I].Name;
+ IniFile.WriteString('Record', 'DeviceName' + S, Tekst);
+
+ Tekst := IntToStr(CardList[I].Input);
+ IniFile.WriteString('Record', 'Input' + S, Tekst);
+
+ Tekst := IntToStr(CardList[I].ChannelL);
+ IniFile.WriteString('Record', 'ChannelL' + S, Tekst);
+
+ Tekst := IntToStr(CardList[I].ChannelR);
+ IniFile.WriteString('Record', 'ChannelR' + S, Tekst);
+ end;
+
+ Log.LogError(InttoStr(Length(CardList)) + ' Cards Saved');
+
+ // Joypad
+ Tekst := IJoypad[Ini.Joypad];
+ IniFile.WriteString('Controller', 'Joypad', Tekst);
+
+ IniFile.Free;
+ end;
+end;
+
+procedure TIni.SaveNames;
+var
+ IniFile: TIniFile;
+ I: integer;
+begin
+ if not FileIsReadOnly(GamePath + 'config.ini') then begin
+ IniFile := TIniFile.Create(GamePath + 'config.ini');
+
+ //Name
+ for I := 1 to 6 do
+ IniFile.WriteString('Name', 'P' + IntToStr(I), Ini.Name[I-1]);
+
+ IniFile.Free;
+ end;
+end;
+
+procedure TIni.SaveLevel;
+var
+ IniFile: TIniFile;
+ I: integer;
+begin
+ if not FileIsReadOnly(GamePath + 'config.ini') then begin
+ IniFile := TIniFile.Create(GamePath + 'config.ini');
+
+ // Difficulty
+ IniFile.WriteString('Game', 'Difficulty', IDifficulty[Ini.Difficulty]);
+
+ IniFile.Free;
+ end;
+end;
+
+end. \ No newline at end of file
diff --git a/Game/Code/Classes/UJoystick.dcu b/Game/Code/Classes/UJoystick.dcu
new file mode 100644
index 00000000..62cde484
--- /dev/null
+++ b/Game/Code/Classes/UJoystick.dcu
Binary files differ
diff --git a/Game/Code/Classes/UJoystick.pas b/Game/Code/Classes/UJoystick.pas
new file mode 100644
index 00000000..a2a06307
--- /dev/null
+++ b/Game/Code/Classes/UJoystick.pas
@@ -0,0 +1,124 @@
+unit UJoystick;
+
+interface
+
+uses SDL;
+
+type
+ TJoyButton = record
+ State: integer;
+ Enabled: boolean;
+ Type_: byte;
+ Sym: cardinal;
+ end;
+
+ TJoyUnit = record
+ Button: array[0..15] of TJoyButton;
+ end;
+
+ TJoy = class
+ constructor Create;
+ procedure Update;
+ end;
+
+var
+ Joy: TJoy;
+ JoyUnit: TJoyUnit;
+ SDL_Joy: PSDL_Joystick;
+ JoyEvent: TSDL_Event;
+
+implementation
+
+uses SysUtils;
+
+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 beep;
+
+ SDL_Joy := SDL_JoystickOpen(0);
+ if SDL_Joy = nil then beep;
+
+ 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_UP;
+ JoyUnit.Button[1].Sym := SDLK_RIGHT;
+ JoyUnit.Button[2].Sym := SDLK_DOWN;
+ JoyUnit.Button[3].Sym := SDLK_LEFT;
+
+ JoyUnit.Button[4].Sym := SDLK_RETURN;
+ JoyUnit.Button[5].Sym := SDLK_ESCAPE;
+end;
+
+procedure TJoy.Update;
+var
+ B: integer;
+begin
+ SDL_JoystickUpdate;
+
+ 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;
+
+end;
+
+end.
diff --git a/Game/Code/Classes/ULCD.dcu b/Game/Code/Classes/ULCD.dcu
new file mode 100644
index 00000000..8098a187
--- /dev/null
+++ b/Game/Code/Classes/ULCD.dcu
Binary files differ
diff --git a/Game/Code/Classes/ULCD.pas b/Game/Code/Classes/ULCD.pas
new file mode 100644
index 00000000..a127c689
--- /dev/null
+++ b/Game/Code/Classes/ULCD.pas
@@ -0,0 +1,287 @@
+unit ULCD;
+
+interface
+
+type
+ TLCD = class
+ private
+ Enabled: boolean;
+ Text: array[1..6] of string;
+ StartPos: integer;
+ LineBR: integer;
+ Position: integer;
+ procedure WriteCommand(B: byte);
+ procedure WriteData(B: byte);
+ procedure WriteString(S: string);
+ public
+ HalfInterface: boolean;
+ constructor Create;
+ procedure Enable;
+ procedure Clear;
+ procedure WriteText(Line: integer; S: string);
+ procedure MoveCursor(Line, Pos: integer);
+ procedure ShowCursor;
+ procedure HideCursor;
+
+ // for 2x16
+ procedure AddTextBR(S: string);
+ procedure MoveCursorBR(Pos: integer);
+ procedure ScrollUpBR;
+ procedure AddTextArray(Line:integer; S: string);
+ end;
+
+var
+ LCD: TLCD;
+
+const
+ Data = $378; // domyœlny adres portu
+ Status = Data + 1;
+ Control = Data + 2;
+
+implementation
+
+uses
+ SysUtils, zlportio, UTime;
+
+procedure TLCD.WriteCommand(B: Byte);
+// Wysylanie komend sterujacych
+begin
+ if not HalfInterface then begin
+ zlioportwrite(Control, 0, $02);
+ zlioportwrite(Data, 0, B);
+ zlioportwrite(Control, 0, $03);
+ end else begin
+ zlioportwrite(Control, 0, $02);
+ zlioportwrite(Data, 0, B and $F0);
+ zlioportwrite(Control, 0, $03);
+
+ TimeSleep(0.1);
+
+ zlioportwrite(Control, 0, $02);
+ zlioportwrite(Data, 0, (B * 16) and $F0);
+ zlioportwrite(Control, 0, $03);
+ end;
+
+ if (B=1) or (B=2) then
+ Sleep(2)
+ else
+ TimeSleep(0.1);
+end;
+
+procedure TLCD.WriteData(B: Byte);
+// Wysylanie danych
+begin
+ if not HalfInterface then begin
+ zlioportwrite(Control, 0, $06);
+ zlioportwrite(Data, 0, B);
+ zlioportwrite(Control, 0, $07);
+ end else begin
+ zlioportwrite(Control, 0, $06);
+ zlioportwrite(Data, 0, B and $F0);
+ zlioportwrite(Control, 0, $07);
+
+ TimeSleep(0.1);
+
+ zlioportwrite(Control, 0, $06);
+ zlioportwrite(Data, 0, (B * 16) and $F0);
+ zlioportwrite(Control, 0, $07);
+ end;
+
+ TimeSleep(0.1);
+ Inc(Position);
+end;
+
+procedure TLCD.WriteString(S: string);
+// Wysylanie slow
+var
+ I: integer;
+begin
+ for I := 1 to Length(S) do
+ WriteData(Ord(S[I]));
+end;
+
+constructor TLCD.Create;
+begin
+//
+end;
+
+procedure TLCD.Enable;
+var
+ A: byte;
+ B: byte;
+begin
+ Enabled := true;
+ if not HalfInterface then
+ WriteCommand($38)
+ else begin
+ WriteCommand($33);
+ WriteCommand($32);
+ WriteCommand($28);
+ end;
+
+// WriteCommand($06);
+// WriteCommand($0C);
+// sleep(10);
+end;
+
+procedure TLCD.Clear;
+begin
+ if Enabled then begin
+ WriteCommand(1);
+ WriteCommand(2);
+ Text[1] := '';
+ Text[2] := '';
+ Text[3] := '';
+ Text[4] := '';
+ Text[5] := '';
+ Text[6] := '';
+ StartPos := 1;
+ LineBR := 1;
+ end;
+end;
+
+procedure TLCD.WriteText(Line: integer; S: string);
+begin
+ if Enabled then begin
+ if Line <= 2 then begin
+ MoveCursor(Line, 1);
+ WriteString(S);
+ end;
+
+ Text[Line] := '';
+ AddTextArray(Line, S);
+ end;
+end;
+
+procedure TLCD.MoveCursor(Line, Pos: integer);
+var
+ I: integer;
+begin
+ if Enabled then begin
+ Pos := Pos + (Line-1) * 40;
+
+ if Position > Pos then begin
+ WriteCommand(2);
+ for I := 1 to Pos-1 do
+ WriteCommand(20);
+ end;
+
+ if Position < Pos then
+ for I := 1 to Pos - Position do
+ WriteCommand(20);
+
+ Position := Pos;
+ end;
+end;
+
+procedure TLCD.ShowCursor;
+begin
+ if Enabled then begin
+ WriteCommand(14);
+ end;
+end;
+
+procedure TLCD.HideCursor;
+begin
+ if Enabled then begin
+ WriteCommand(12);
+ end;
+end;
+
+procedure TLCD.AddTextBR(S: string);
+var
+ Word: string;
+ W: integer;
+ P: integer;
+ L: integer;
+begin
+ if Enabled then begin
+ if LineBR <= 6 then begin
+ L := LineBR;
+ P := Pos(' ', S);
+
+ if L <= 2 then
+ MoveCursor(L, 1);
+
+ while (L <= 6) and (P > 0) do begin
+ Word := Copy(S, 1, P);
+ if (Length(Text[L]) + Length(Word)-1) > 16 then begin
+ L := L + 1;
+ if L <= 2 then
+ MoveCursor(L, 1);
+ end;
+
+ if L <= 6 then begin
+ if L <= 2 then
+ WriteString(Word);
+ AddTextArray(L, Word);
+ end;
+
+ Delete(S, 1, P);
+ P := Pos(' ', S)
+ end;
+
+ LineBR := L + 1;
+ end;
+ end;
+end;
+
+procedure TLCD.MoveCursorBR(Pos: integer);
+var
+ I: integer;
+ L: integer;
+begin
+ if Enabled then begin
+ Pos := Pos - (StartPos-1);
+ if Pos <= Length(Text[1]) then
+ MoveCursor(1, Pos);
+
+ if Pos > Length(Text[1]) then begin
+ // bez zawijania
+// Pos := Pos - Length(Text[1]);
+// MoveCursor(2, Pos);
+
+ // z zawijaniem
+ Pos := Pos - Length(Text[1]);
+ ScrollUpBR;
+ MoveCursor(1, Pos);
+ end;
+ end;
+end;
+
+procedure TLCD.ScrollUpBR;
+var
+ T: array[1..5] of string;
+ SP: integer;
+ LBR: integer;
+begin
+ if Enabled then begin
+ T[1] := Text[2];
+ T[2] := Text[3];
+ T[3] := Text[4];
+ T[4] := Text[5];
+ T[5] := Text[6];
+ SP := StartPos + Length(Text[1]);
+ LBR := LineBR;
+
+ Clear;
+
+ StartPos := SP;
+ WriteText(1, T[1]);
+ WriteText(2, T[2]);
+ WriteText(3, T[3]);
+ WriteText(4, T[4]);
+ WriteText(5, T[5]);
+ LineBR := LBR-1;
+ end;
+end;
+
+procedure TLCD.AddTextArray(Line: integer; S: string);
+begin
+ if Enabled then begin
+ Text[Line] := Text[Line] + S;
+ end;
+end;
+
+end.
+
diff --git a/Game/Code/Classes/ULCD.~pas b/Game/Code/Classes/ULCD.~pas
new file mode 100644
index 00000000..a127c689
--- /dev/null
+++ b/Game/Code/Classes/ULCD.~pas
@@ -0,0 +1,287 @@
+unit ULCD;
+
+interface
+
+type
+ TLCD = class
+ private
+ Enabled: boolean;
+ Text: array[1..6] of string;
+ StartPos: integer;
+ LineBR: integer;
+ Position: integer;
+ procedure WriteCommand(B: byte);
+ procedure WriteData(B: byte);
+ procedure WriteString(S: string);
+ public
+ HalfInterface: boolean;
+ constructor Create;
+ procedure Enable;
+ procedure Clear;
+ procedure WriteText(Line: integer; S: string);
+ procedure MoveCursor(Line, Pos: integer);
+ procedure ShowCursor;
+ procedure HideCursor;
+
+ // for 2x16
+ procedure AddTextBR(S: string);
+ procedure MoveCursorBR(Pos: integer);
+ procedure ScrollUpBR;
+ procedure AddTextArray(Line:integer; S: string);
+ end;
+
+var
+ LCD: TLCD;
+
+const
+ Data = $378; // domyœlny adres portu
+ Status = Data + 1;
+ Control = Data + 2;
+
+implementation
+
+uses
+ SysUtils, zlportio, UTime;
+
+procedure TLCD.WriteCommand(B: Byte);
+// Wysylanie komend sterujacych
+begin
+ if not HalfInterface then begin
+ zlioportwrite(Control, 0, $02);
+ zlioportwrite(Data, 0, B);
+ zlioportwrite(Control, 0, $03);
+ end else begin
+ zlioportwrite(Control, 0, $02);
+ zlioportwrite(Data, 0, B and $F0);
+ zlioportwrite(Control, 0, $03);
+
+ TimeSleep(0.1);
+
+ zlioportwrite(Control, 0, $02);
+ zlioportwrite(Data, 0, (B * 16) and $F0);
+ zlioportwrite(Control, 0, $03);
+ end;
+
+ if (B=1) or (B=2) then
+ Sleep(2)
+ else
+ TimeSleep(0.1);
+end;
+
+procedure TLCD.WriteData(B: Byte);
+// Wysylanie danych
+begin
+ if not HalfInterface then begin
+ zlioportwrite(Control, 0, $06);
+ zlioportwrite(Data, 0, B);
+ zlioportwrite(Control, 0, $07);
+ end else begin
+ zlioportwrite(Control, 0, $06);
+ zlioportwrite(Data, 0, B and $F0);
+ zlioportwrite(Control, 0, $07);
+
+ TimeSleep(0.1);
+
+ zlioportwrite(Control, 0, $06);
+ zlioportwrite(Data, 0, (B * 16) and $F0);
+ zlioportwrite(Control, 0, $07);
+ end;
+
+ TimeSleep(0.1);
+ Inc(Position);
+end;
+
+procedure TLCD.WriteString(S: string);
+// Wysylanie slow
+var
+ I: integer;
+begin
+ for I := 1 to Length(S) do
+ WriteData(Ord(S[I]));
+end;
+
+constructor TLCD.Create;
+begin
+//
+end;
+
+procedure TLCD.Enable;
+var
+ A: byte;
+ B: byte;
+begin
+ Enabled := true;
+ if not HalfInterface then
+ WriteCommand($38)
+ else begin
+ WriteCommand($33);
+ WriteCommand($32);
+ WriteCommand($28);
+ end;
+
+// WriteCommand($06);
+// WriteCommand($0C);
+// sleep(10);
+end;
+
+procedure TLCD.Clear;
+begin
+ if Enabled then begin
+ WriteCommand(1);
+ WriteCommand(2);
+ Text[1] := '';
+ Text[2] := '';
+ Text[3] := '';
+ Text[4] := '';
+ Text[5] := '';
+ Text[6] := '';
+ StartPos := 1;
+ LineBR := 1;
+ end;
+end;
+
+procedure TLCD.WriteText(Line: integer; S: string);
+begin
+ if Enabled then begin
+ if Line <= 2 then begin
+ MoveCursor(Line, 1);
+ WriteString(S);
+ end;
+
+ Text[Line] := '';
+ AddTextArray(Line, S);
+ end;
+end;
+
+procedure TLCD.MoveCursor(Line, Pos: integer);
+var
+ I: integer;
+begin
+ if Enabled then begin
+ Pos := Pos + (Line-1) * 40;
+
+ if Position > Pos then begin
+ WriteCommand(2);
+ for I := 1 to Pos-1 do
+ WriteCommand(20);
+ end;
+
+ if Position < Pos then
+ for I := 1 to Pos - Position do
+ WriteCommand(20);
+
+ Position := Pos;
+ end;
+end;
+
+procedure TLCD.ShowCursor;
+begin
+ if Enabled then begin
+ WriteCommand(14);
+ end;
+end;
+
+procedure TLCD.HideCursor;
+begin
+ if Enabled then begin
+ WriteCommand(12);
+ end;
+end;
+
+procedure TLCD.AddTextBR(S: string);
+var
+ Word: string;
+ W: integer;
+ P: integer;
+ L: integer;
+begin
+ if Enabled then begin
+ if LineBR <= 6 then begin
+ L := LineBR;
+ P := Pos(' ', S);
+
+ if L <= 2 then
+ MoveCursor(L, 1);
+
+ while (L <= 6) and (P > 0) do begin
+ Word := Copy(S, 1, P);
+ if (Length(Text[L]) + Length(Word)-1) > 16 then begin
+ L := L + 1;
+ if L <= 2 then
+ MoveCursor(L, 1);
+ end;
+
+ if L <= 6 then begin
+ if L <= 2 then
+ WriteString(Word);
+ AddTextArray(L, Word);
+ end;
+
+ Delete(S, 1, P);
+ P := Pos(' ', S)
+ end;
+
+ LineBR := L + 1;
+ end;
+ end;
+end;
+
+procedure TLCD.MoveCursorBR(Pos: integer);
+var
+ I: integer;
+ L: integer;
+begin
+ if Enabled then begin
+ Pos := Pos - (StartPos-1);
+ if Pos <= Length(Text[1]) then
+ MoveCursor(1, Pos);
+
+ if Pos > Length(Text[1]) then begin
+ // bez zawijania
+// Pos := Pos - Length(Text[1]);
+// MoveCursor(2, Pos);
+
+ // z zawijaniem
+ Pos := Pos - Length(Text[1]);
+ ScrollUpBR;
+ MoveCursor(1, Pos);
+ end;
+ end;
+end;
+
+procedure TLCD.ScrollUpBR;
+var
+ T: array[1..5] of string;
+ SP: integer;
+ LBR: integer;
+begin
+ if Enabled then begin
+ T[1] := Text[2];
+ T[2] := Text[3];
+ T[3] := Text[4];
+ T[4] := Text[5];
+ T[5] := Text[6];
+ SP := StartPos + Length(Text[1]);
+ LBR := LineBR;
+
+ Clear;
+
+ StartPos := SP;
+ WriteText(1, T[1]);
+ WriteText(2, T[2]);
+ WriteText(3, T[3]);
+ WriteText(4, T[4]);
+ WriteText(5, T[5]);
+ LineBR := LBR-1;
+ end;
+end;
+
+procedure TLCD.AddTextArray(Line: integer; S: string);
+begin
+ if Enabled then begin
+ Text[Line] := Text[Line] + S;
+ end;
+end;
+
+end.
+
diff --git a/Game/Code/Classes/ULanguage.dcu b/Game/Code/Classes/ULanguage.dcu
new file mode 100644
index 00000000..2d5c3596
--- /dev/null
+++ b/Game/Code/Classes/ULanguage.dcu
Binary files differ
diff --git a/Game/Code/Classes/ULanguage.pas b/Game/Code/Classes/ULanguage.pas
new file mode 100644
index 00000000..bc3793e3
--- /dev/null
+++ b/Game/Code/Classes/ULanguage.pas
@@ -0,0 +1,222 @@
+unit ULanguage;
+
+interface
+
+type
+ TLanguageEntry = record
+ ID: string;
+ Text: string;
+ end;
+
+ TLanguageList = record
+ Name: string;
+ {FileName: string; }
+ end;
+
+ TLanguage = class
+ private
+ 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 UPliki, 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 Files');
+
+ //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);
+ 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;
+
+ //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
+ if Text = Result then
+ begin
+ for E := low(SEntry) to high(SEntry) do
+ if Text = SEntry[E].ID then
+ begin
+ Result := SEntry[E].Text;
+ exit;
+ end;
+ 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.dcu b/Game/Code/Classes/ULight.dcu
new file mode 100644
index 00000000..10ba61bc
--- /dev/null
+++ b/Game/Code/Classes/ULight.dcu
Binary files differ
diff --git a/Game/Code/Classes/ULight.pas b/Game/Code/Classes/ULight.pas
new file mode 100644
index 00000000..967d2ea1
--- /dev/null
+++ b/Game/Code/Classes/ULight.pas
@@ -0,0 +1,116 @@
+unit ULight;
+interface
+
+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, zlportio, UTime;
+
+constructor TLight.Create;
+begin
+ Enabled := false;
+end;
+
+procedure TLight.Enable;
+begin
+ Enabled := true;
+ LastTime := GetTime;
+end;
+
+procedure TLight.SetState(State: integer);
+begin
+ if Enabled then
+ PortWriteB($378, State);
+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.dcu b/Game/Code/Classes/ULog.dcu
new file mode 100644
index 00000000..1794325d
--- /dev/null
+++ b/Game/Code/Classes/ULog.dcu
Binary files differ
diff --git a/Game/Code/Classes/ULog.pas b/Game/Code/Classes/ULog.pas
new file mode 100644
index 00000000..6bffa04e
--- /dev/null
+++ b/Game/Code/Classes/ULog.pas
@@ -0,0 +1,227 @@
+unit ULog;
+
+interface
+
+uses Classes;
+
+type
+ TLog = class
+ BenchmarkTimeStart: array[0..7] of real;
+ BenchmarkTimeLength: array[0..7] of real;//TDateTime;
+
+ FileBenchmark: TextFile;
+ FileBenchmarkO: boolean; // opened
+ FileAnalyze: TextFile;
+ FileAnalyzeO: boolean; // opened
+ FileError: TextFile;
+ FileErrorO: boolean; // opened
+
+ Title: String; //Application Title
+
+ // destuctor
+ destructor Free;
+
+ // benchmark
+ procedure BenchmarkStart(Number: integer);
+ procedure BenchmarkEnd(Number: integer);
+ procedure LogBenchmark(Text: string; Number: integer);
+
+ // analyze
+ procedure LogAnalyze(Text: string);
+
+ // 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 UPliki, SysUtils, DateUtils, URecord, UTime, UIni, Windows;
+
+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 (ParamStr(1) = '-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+}
+ 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.LogAnalyze(Text: string);
+var
+ Seconds: integer;
+ Miliseconds: integer;
+ ValueText: string;
+begin
+ if Ini.Debug = 1 then begin
+
+ if not FileAnalyzeO then begin
+ AssignFile(FileAnalyze, LogPath + 'Analyze.log');
+ {$I-}
+ Rewrite(FileAnalyze);
+ if IOResult = 0 then FileAnalyzeO := true;
+ {$I+}
+ end;
+
+ if FileAnalyzeO then begin
+ WriteLn(FileAnalyze, Text);
+ Flush(FileAnalyze); // try to speed up
+ end;
+
+ end;
+end;
+
+procedure TLog.LogError(Text: string);
+begin
+ if not FileErrorO then begin
+ FileErrorO := true;
+ AssignFile(FileError, LogPath + 'Error.log');
+ {$I-}
+ Rewrite(FileError);
+ if IOResult = 0 then FileErrorO := true;
+ {$I+}
+ end;
+
+ if FileErrorO then begin
+ WriteLn(FileError, Text);
+ Flush(FileError);
+ 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
+//asd
+ 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.
+ \ No newline at end of file
diff --git a/Game/Code/Classes/ULyrics.dcu b/Game/Code/Classes/ULyrics.dcu
new file mode 100644
index 00000000..3867c263
--- /dev/null
+++ b/Game/Code/Classes/ULyrics.dcu
Binary files differ
diff --git a/Game/Code/Classes/ULyrics.pas b/Game/Code/Classes/ULyrics.pas
new file mode 100644
index 00000000..c3b440bc
--- /dev/null
+++ b/Game/Code/Classes/ULyrics.pas
@@ -0,0 +1,383 @@
+unit ULyrics;
+
+interface
+uses SysUtils, OpenGL12, UMusic;
+
+type
+ TWord = record
+ X: real;
+ Y: real;
+ Size: real;
+ Width: real;
+ Text: string;
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ Scale: real;
+ Done: real;
+ FontStyle: integer;
+ Italic: boolean;
+ Selected: boolean;
+ end;
+
+ TLyric = class
+ private
+ AlignI: integer;
+ XR: real;
+ YR: real;
+ SizeR: real;
+ SelectedI: integer;
+ ScaleR: real;
+ StyleI: integer; // 0 - one selection, 1 - long selection, 2 - one selection with fade to normal text, 3 - long selection with fade with color from left
+ FontStyleI: integer; // font number
+ Word: array of TWord;
+ procedure SetX(Value: real);
+ procedure SetY(Value: real);
+ function GetClientX: real;
+ procedure SetAlign(Value: integer);
+ function GetSize: real;
+ procedure SetSize(Value: real);
+ procedure SetSelected(Value: integer);
+ procedure SetDone(Value: real);
+ procedure SetScale(Value: real);
+ procedure SetStyle(Value: integer);
+ procedure SetFStyle(Value: integer);
+ procedure Refresh;
+ procedure DrawNormal(W: integer);
+ procedure DrawPlain(W: integer);
+ procedure DrawScaled(W: integer);
+ procedure DrawSlide(W: integer);
+ public
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ ColSR: real;
+ ColSG: real;
+ ColSB: real;
+ Italic: boolean;
+ Text: string; // LCD
+
+ published
+ property X: real write SetX;
+ property Y: real write SetY;
+ property ClientX: real read GetClientX;
+ property Align: integer write SetAlign;
+ property Size: real read GetSize write SetSize;
+ property Selected: integer read SelectedI write SetSelected;
+ property Done: real write SetDone;
+ property Scale: real write SetScale;
+ property Style: integer write SetStyle;
+ property FontStyle: integer write SetFStyle;
+ procedure AddWord(Text: string);
+ procedure AddCzesc(NrCzesci: integer);
+
+ function SelectedLetter: integer; // LCD
+ function SelectedLength: integer; // LCD
+
+ procedure Clear;
+ procedure Draw;
+
+ end;
+
+var
+ Lyric: TLyric;
+
+implementation
+uses TextGL, UGraphic, UDrawTexture;
+
+procedure TLyric.SetX(Value: real);
+begin
+ XR := Value;
+end;
+
+procedure TLyric.SetY(Value: real);
+begin
+ YR := Value;
+end;
+
+function TLyric.GetClientX: real;
+begin
+ Result := Word[0].X;
+end;
+
+procedure TLyric.SetAlign(Value: integer);
+begin
+ AlignI := Value;
+// if AlignInt = 0 then beep;
+end;
+
+function TLyric.GetSize: real;
+begin
+ Result := SizeR;
+end;
+
+procedure TLyric.SetSize(Value: real);
+begin
+ SizeR := Value;
+end;
+
+procedure TLyric.SetSelected(Value: integer);
+var
+ W: integer;
+begin
+ if (StyleI = 0) or (StyleI = 2) or (StyleI = 4) then begin
+ if (SelectedI > -1) and (SelectedI <= High(Word)) then begin
+ Word[SelectedI].Selected := false;
+ Word[SelectedI].ColR := ColR;
+ Word[SelectedI].ColG := ColG;
+ Word[SelectedI].ColB := ColB;
+ Word[SelectedI].Done := 0;
+ end;
+
+ SelectedI := Value;
+ if (Value > -1) and (Value <= High(Word)) then begin
+ Word[Value].Selected := true;
+ Word[Value].ColR := ColSR;
+ Word[Value].ColG := ColSG;
+ Word[Value].ColB := ColSB;
+ Word[Value].Scale := ScaleR;
+ end;
+ end;
+
+ if (StyleI = 1) or (StyleI = 3) then begin
+ if (SelectedI > -1) and (SelectedI <= High(Word)) then begin
+ for W := SelectedI to High(Word) do begin
+ Word[W].Selected := false;
+ Word[W].ColR := ColR;
+ Word[W].ColG := ColG;
+ Word[W].ColB := ColB;
+ Word[W].Done := 0;
+ end;
+ end;
+
+ SelectedI := Value;
+ if (Value > -1) and (Value <= High(Word)) then begin
+ for W := 0 to Value do begin
+ Word[W].Selected := true;
+ Word[W].ColR := ColSR;
+ Word[W].ColG := ColSG;
+ Word[W].ColB := ColSB;
+ Word[W].Scale := ScaleR;
+ Word[W].Done := 1;
+ end;
+ end;
+ end;
+
+ Refresh;
+end;
+
+procedure TLyric.SetDone(Value: real);
+var
+ W: integer;
+begin
+ W := SelectedI;
+ if W > -1 then
+ Word[W].Done := Value;
+end;
+
+procedure TLyric.SetScale(Value: real);
+begin
+ ScaleR := Value;
+end;
+
+procedure TLyric.SetStyle(Value: integer);
+begin
+ StyleI := Value;
+end;
+
+procedure TLyric.SetFStyle(Value: integer);
+begin
+ FontStyleI := Value;
+end;
+
+procedure TLyric.AddWord(Text: string);
+var
+ WordNum: integer;
+begin
+ WordNum := Length(Word);
+ SetLength(Word, WordNum + 1);
+ if WordNum = 0 then begin
+ Word[WordNum].X := XR;
+ end else begin
+ Word[WordNum].X := Word[WordNum - 1].X + Word[WordNum - 1].Width;
+ end;
+
+ Word[WordNum].Y := YR;
+ Word[WordNum].Size := SizeR;
+ Word[WordNum].FontStyle := FontStyleI; // new
+ SetFontStyle(FontStyleI);
+ SetFontSize(SizeR);
+ Word[WordNum].Width := glTextWidth(pchar(Text));
+ Word[WordNum].Text := Text;
+ Word[WordNum].ColR := ColR;
+ Word[WordNum].ColG := ColG;
+ Word[WordNum].ColB := ColB;
+ Word[WordNum].Scale := 1;
+ Word[WordNum].Done := 0;
+ Word[WordNum].Italic := Italic;
+
+ Refresh;
+end;
+
+procedure TLyric.AddCzesc(NrCzesci: integer);
+var
+ N: integer;
+begin
+ Clear;
+ for N := 0 to Czesci[0].Czesc[NrCzesci].HighNut do begin
+ Italic := Czesci[0].Czesc[NrCzesci].Nuta[N].FreeStyle;
+ AddWord(Czesci[0].Czesc[NrCzesci].Nuta[N].Tekst);
+ Text := Text + Czesci[0].Czesc[NrCzesci].Nuta[N].Tekst;
+ end;
+ Selected := -1;
+end;
+
+procedure TLyric.Clear;
+begin
+{ ColR := Skin_FontR;
+ ColG := Skin_FontG;
+ ColB := Skin_FontB;}
+ SetLength(Word, 0);
+ Text := '';
+ SelectedI := -1;
+end;
+
+procedure TLyric.Refresh;
+var
+ W: integer;
+ TotWidth: real;
+begin
+ if AlignI = 1 then begin
+ TotWidth := 0;
+ for W := 0 to High(Word) do
+ TotWidth := TotWidth + Word[W].Width;
+
+ Word[0].X := XR - TotWidth / 2;
+ for W := 1 to High(Word) do
+ Word[W].X := Word[W - 1].X + Word[W - 1].Width;
+ end;
+end;
+
+procedure TLyric.Draw;
+var
+ W: integer;
+begin
+ case StyleI of
+ 0:
+ begin
+ for W := 0 to High(Word) do
+ DrawNormal(W);
+ end;
+ 1:
+ begin
+ for W := 0 to High(Word) do
+ DrawPlain(W);
+ end;
+ 2: // zoom
+ begin
+ for W := 0 to High(Word) do
+ if not Word[W].Selected then
+ DrawNormal(W);
+
+ for W := 0 to High(Word) do
+ if Word[W].Selected then
+ DrawScaled(W);
+ end;
+ 3: // slide
+ begin
+ for W := 0 to High(Word) do begin
+ if not Word[W].Selected then
+ DrawNormal(W)
+ else
+ DrawSlide(W);
+ end;
+ end;
+ 4: // ball
+ begin
+ for W := 0 to High(Word) do
+ DrawNormal(W);
+
+ for W := 0 to High(Word) do
+ if Word[W].Selected then begin
+ Tex_Ball.X := (Word[W].X - 10) + Word[W].Done * Word[W].Width;
+ Tex_Ball.Y := 480 - 10*sin(Word[W].Done * pi);
+ Tex_Ball.W := 20;
+ Tex_Ball.H := 20;
+ DrawTexture(Tex_Ball);
+ end;
+ end;
+ end; // case
+end;
+
+procedure TLyric.DrawNormal(W: integer);
+begin
+ SetFontStyle(Word[W].FontStyle);
+ SetFontPos(Word[W].X+ 10*ScreenX, Word[W].Y);
+ SetFontSize(Word[W].Size);
+ SetFontItalic(Word[W].Italic);
+ glColor3f(Word[W].ColR, Word[W].ColG, Word[W].ColB);
+ glPrint(pchar(Word[W].Text));
+end;
+
+procedure TLyric.DrawPlain(W: integer);
+var
+ D: real;
+begin
+ D := Word[W].Done; // przyrost
+
+ SetFontStyle(Word[W].FontStyle);
+ SetFontPos(Word[W].X, Word[W].Y);
+ SetFontSize(Word[W].Size);
+ SetFontItalic(Word[W].Italic);
+
+ if D = 0 then
+ glColor3f(ColR, ColG, ColB)
+ else
+ glColor3f(ColSR, ColSG, ColSB);
+
+ glPrint(pchar(Word[W].Text));
+end;
+
+procedure TLyric.DrawScaled(W: integer);
+var
+ D: real;
+begin
+ // previous plus dynamic scaling effect
+ D := 1-Word[W].Done; // przyrost
+ SetFontStyle(Word[W].FontStyle);
+ SetFontPos(Word[W].X - D * Word[W].Width * (Word[W].Scale - 1) / 2 + (D+1)*10*ScreenX, Word[W].Y - D * 1.5 * Word[W].Size *(Word[W].Scale - 1));
+ SetFontSize(Word[W].Size + D * (Word[W].Size * Word[W].Scale - Word[W].Size));
+ SetFontItalic(Word[W].Italic);
+ glColor3f(Word[W].ColR, Word[W].ColG, Word[W].ColB);
+ glPrint(pchar(Word[W].Text))
+end;
+
+procedure TLyric.DrawSlide(W: integer);
+var
+ D: real;
+begin
+ D := Word[W].Done; // przyrost
+ SetFontStyle(Word[W].FontStyle);
+ SetFontPos(Word[W].X, Word[W].Y);
+ SetFontSize(Word[W].Size);
+ SetFontItalic(Word[W].Italic);
+ glColor3f(Word[W].ColR, Word[W].ColG, Word[W].ColB);
+ glPrintDone(pchar(Word[W].Text), D, ColR, ColG, ColB);
+end;
+
+function TLyric.SelectedLetter; // LCD
+var
+ W: integer;
+begin
+ Result := 1;
+
+ for W := 0 to SelectedI-1 do
+ Result := Result + Length(Word[W].Text);
+end;
+
+function TLyric.SelectedLength: integer; // LCD
+begin
+ Result := Length(Word[SelectedI].Text);
+end;
+
+end.
diff --git a/Game/Code/Classes/UMain.dcu b/Game/Code/Classes/UMain.dcu
new file mode 100644
index 00000000..3a2edf09
--- /dev/null
+++ b/Game/Code/Classes/UMain.dcu
Binary files differ
diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas
new file mode 100644
index 00000000..3ef65e1d
--- /dev/null
+++ b/Game/Code/Classes/UMain.pas
@@ -0,0 +1,673 @@
+unit UMain;
+
+interface
+uses SDL, UGraphic, UMusic, URecord, UTime, SysUtils, UDisplay, UIni, ULog, ULyrics, UScreenSing,
+ OpenGL12, zlportio {you can disable it and all PortWriteB calls}, 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: integer;
+ LineBonus_PosY: integer;
+ LineBonus_Alpha: Single;
+ LineBonus_Visible: boolean;
+ LineBonus_Text: string;
+ LineBonus_Color: TRGB;
+
+ //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
+
+
+
+
+// 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
+ OGL: Boolean;
+ Done: Boolean;
+ Event: TSDL_event;
+ FileName: string;
+ Restart: boolean;
+
+ // gracz i jego nuty
+ Player: array of TPlayer;
+ PlayersPlay: integer;
+
+
+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;
+
+procedure MainLoop;
+var
+ Delay: integer;
+begin
+ SDL_EnableKeyRepeat(125, 125);
+ While not Done do
+ Begin
+ // joypad
+ if Ini.Joypad = 1 then
+ Joy.Update;
+
+ // keyboard events
+ CheckEvents;
+
+ // display
+ 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: done := true;
+{ SDL_MOUSEBUTTONDOWN:
+ With Event.button Do
+ Begin
+ If State = SDL_BUTTON_LEFT Then
+ Begin
+ //
+ End;
+ End; // With}
+ SDL_KEYDOWN:
+ begin
+ if (Not Display.ActualScreen^.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True)) then
+// if (Not Display.ActualScreen^.ParseInput(Event.key.keysym.scancode, True)) then
+ done := true; // exit game
+ 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;
+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;
+
+ //PortWriteB($378, LPT_1 + LPT_2 * 2); // 0 zapala
+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;
+ 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;
+
+end.
+
diff --git a/Game/Code/Classes/UMusic.dcu b/Game/Code/Classes/UMusic.dcu
new file mode 100644
index 00000000..f3116f8b
--- /dev/null
+++ b/Game/Code/Classes/UMusic.dcu
Binary files differ
diff --git a/Game/Code/Classes/UMusic.pas b/Game/Code/Classes/UMusic.pas
new file mode 100644
index 00000000..db1675c5
--- /dev/null
+++ b/Game/Code/Classes/UMusic.pas
@@ -0,0 +1,783 @@
+unit UMusic;
+
+interface
+
+uses Classes, MPlayer, Windows, Messages, SysUtils, Forms, ULog, USongs, Bass;//, DXSounds;
+
+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
+// MediaPlayer: TMediaPlayer; // It will be replaced by another component;
+{ MediaPlayerStart: TMediaPlayer; // or maybe not if done this way ;)
+ MediaPlayerBack: TMediaPlayer;
+ MediaPlayerSwoosh: TMediaPlayer;
+ MediaPlayerChange: TMediaPlayer;
+ MediaPlayerOption: TMediaPlayer;
+ MediaPlayerClick: TMediaPlayer;
+ MediaPlayerDrum: TMediaPlayer;
+ MediaPlayerHihat: TMediaPlayer;
+ MediaPlayerClap: TMediaPlayer;
+ MediaPlayerShuffle: TMediaPlayer;}
+ 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;
+// DXSound: TDXSound;
+// Player: TcmxMp3;
+ public
+ Bass: hStream;
+
+// SoundCard: array of TSoundCard;
+ procedure InitializePlayback;
+ procedure InitializeRecord;
+ procedure SetVolume(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 LoadPlayerFromFile(var MediaPlayer: TMediaPlayer; Name: string): boolean;
+ 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
+// BPM: array of TBPM;
+// Gap: real;
+ IlNut: integer;
+ DlugoscNut: integer;
+// WartoscNut: 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
+// BajtowTotal: integer;
+// BajtowTeraz: integer;
+// BajtowNaSek: integer;
+ OldBeat: integer; // poprzednio wykryty beat w utworze
+ AktBeat: integer; // aktualny beat w utworze
+ MidBeat: real; // dokladny AktBeat
+
+ // should not be used
+// OldHalf: integer; // poprzednio wykryta polowka
+// AktHalf: integer; // aktualna polowka w utworze
+// MidHalf: real; // dokladny AktHalf
+
+ // 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
+// TerazSek: integer;
+ end;
+
+var
+ Form: TForm;
+ Music: TMusic;
+
+ // muzyka
+ Muzyka: TMuzyka;
+
+ // czesci z nutami;
+ Czesci: array of TCzesci;
+
+ // czas
+ Czas: TCzas;
+
+ fHWND: Thandle;
+
+const
+ ModeStr: array[TMPModes] of string = ('Not ready', 'Stopped', 'Playing', 'Recording', 'Seeking', 'Paused', 'Open');
+
+implementation
+uses UGraphic, URecord, UPliki, 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);
+
+ if not BASS_Init(1, 44100, 0, fHWND, nil) then begin
+ Application.MessageBox ('Could not initialize BASS', 'Error');
+ 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);
+
+{ MediaPlayer := TMediaPlayer.Create( nil );
+ MediaPlayer.ParentWindow := fHWND;
+ MediaPlayer.Wait := true;}
+
+ Log.LogStatus('Loading Sounds', 'Music Initialize');
+
+{ LoadPlayerFromFile(MediaPlayerStart, SoundPath + 'Common Start.mp3');
+ LoadPlayerFromFile(MediaPlayerBack, SoundPath + 'Common Back.mp3');
+ LoadPlayerFromFile(MediaPlayerSwoosh, SoundPath + 'menu swoosh.mp3');
+ LoadPlayerFromFile(MediaPlayerChange, SoundPath + 'select music change music.mp3');
+ LoadPlayerFromFile(MediaPlayerOption, SoundPath + 'option change col.mp3');
+ LoadPlayerFromFile(MediaPlayerClick, SoundPath + 'rimshot022b.mp3');
+
+ LoadPlayerFromFile(MediaPlayerDrum, SoundPath + 'bassdrumhard076b.mp3');
+ LoadPlayerFromFile(MediaPlayerHihat, SoundPath + 'hihatclosed068b.mp3');
+ LoadPlayerFromFile(MediaPlayerClap, SoundPath + 'claps050b.mp3');
+
+ LoadPlayerFromFile(MediaPlayerShuffle, SoundPath + 'Shuffle.mp3');}
+
+ 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
+ BASS_SetVolume(Volume);
+end;
+
+procedure TMusic.SetLoop(Enabled: boolean);
+begin
+ Loop := Enabled;
+end;
+
+function TMusic.Open(Name: string): boolean;
+begin
+ Loaded := false;
+ if FileExists(Name) then begin
+{ MediaPlayer.FileName := Name;
+ MediaPlayer.Open;}
+
+ Bass := Bass_StreamCreateFile(false, pchar(Name), 0, 0, 0);
+ Loaded := true;
+ end;
+
+ Result := Loaded;
+
+// Player := TcmxMp3.Create(Name);
+end;
+
+procedure TMusic.Rewind;
+begin
+ if Loaded then begin
+// MediaPlayer.Position := 0;
+
+ end;
+end;
+
+procedure TMusic.MoveTo(Time: real);
+var
+ bytes: integer;
+begin
+// if Loaded then begin
+// MediaPlayer.StartPos := Round(Time);
+ bytes := BASS_ChannelSeconds2Bytes(Bass, Time);
+ BASS_ChannelSetPosition(Bass, bytes);
+// end;
+end;
+
+procedure TMusic.Play;
+begin
+ if Loaded then begin
+// MediaPlayer.Play;
+ 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);
+// Bass_StreamFree(Bass);
+// if ModeStr[MediaPlayer.Mode] = 'Playing' then begin
+// MediaPlayer.Stop;
+// end;
+end;
+
+procedure TMusic.Close;
+begin
+ Bass_StreamFree(Bass);
+// Player.Free;
+// MediaPlayer.Close;
+end;
+
+function TMusic.Length: real;
+var
+ bytes: integer;
+begin
+ Result := 60;
+
+ bytes := BASS_StreamGetLength(Bass);
+ Result := BASS_ChannelBytes2Seconds(Bass, bytes);
+
+{ if Assigned(MediaPlayer) then begin
+ if Loaded then Result := MediaPlayer.Length / 1000;
+ end;}
+// if Assigned(Player) then
+// Result := Player.LengthInSeconds;
+end;
+
+function TMusic.Position: real;
+var
+ bytes: integer;
+begin
+ Result := 0;//MediaPlayer.Position / 1000;
+ bytes := BASS_ChannelGetPosition(BASS);
+ Result := BASS_ChannelBytes2Seconds(BASS, bytes);
+end;
+
+function TMusic.Finished: boolean;
+begin
+ Result := false;
+// if ModeStr[MediaPlayer.Mode] = 'Stopped' then Result := true;
+ if BASS_ChannelIsActive(BASS) = BASS_ACTIVE_STOPPED then begin
+// beep;
+ Result := true;
+ end;
+end;
+
+{function myeffect( chan : integer; stream : Pointer; len : integer; udata : Pointer ): Pointer; cdecl;
+var
+ dane: pwordarray;
+ pet: integer;
+ Prev: smallint;
+ PrevNew: smallint;
+begin
+ dane := stream;
+ Prev := 0;
+ for pet := 0 to len div 2 -1 do begin
+ PrevNew := Dane[Pet];
+
+// Dane[pet] := Round(PrevNew*1/8 + Prev*7/8);
+
+ Prev := Dane[Pet];
+ end;
+end;}
+
+procedure TMusic.PlayStart;
+{var
+ Music: PMix_Chunk;}
+begin
+{ Mix_OpenAudio(44100, 16, 1, 16*1024);
+ Music := Mix_LoadWAV('D:\Rozne\UltraStar\Old\Boys - Hej Sokoly 30s.wav');
+ Mix_RegisterEffect(0, myeffect, nil, 0);
+ Mix_PlayChannel(0, Music, 0);}
+
+// MediaPlayerStart.Rewind;
+// MediaPlayerStart.Play;
+ BASS_ChannelPlay(BassStart, True);
+end;
+
+procedure TMusic.PlayBack;
+begin
+// MediaPlayerBack.Rewind;
+// MediaPlayerBack.Play;
+// if not
+ BASS_ChannelPlay(BassBack, True);// then
+// Application.MessageBox ('Error playing stream!', 'Error');
+end;
+
+procedure TMusic.PlaySwoosh;
+begin
+// MediaPlayerSwoosh.Rewind;
+// MediaPlayerSwoosh.Play;
+ BASS_ChannelPlay(BassSwoosh, True);
+end;
+
+procedure TMusic.PlayChange;
+begin
+// MediaPlayerChange.Rewind;
+// MediaPlayerChange.Play;
+ BASS_ChannelPlay(BassChange, True);
+end;
+
+procedure TMusic.PlayOption;
+begin
+// MediaPlayerOption.Rewind;
+// MediaPlayerOption.Play;
+ BASS_ChannelPlay(BassOption, True);
+end;
+
+procedure TMusic.PlayClick;
+begin
+// MediaPlayerClick.Rewind;
+// MediaPlayerClick.Play;
+ BASS_ChannelPlay(BassClick, True);
+end;
+
+procedure TMusic.PlayDrum;
+begin
+// MediaPlayerDrum.Rewind;
+// MediaPlayerDrum.Play;
+ BASS_ChannelPlay(BassDrum, True);
+end;
+
+procedure TMusic.PlayHihat;
+begin
+// MediaPlayerHihat.Rewind;
+// MediaPlayerHihat.Play;
+ BASS_ChannelPlay(BassHihat, True);
+end;
+
+procedure TMusic.PlayClap;
+begin
+// MediaPlayerClap.Rewind;
+// MediaPlayerClap.Play;
+ BASS_ChannelPlay(BassClap, True);
+end;
+
+procedure TMusic.PlayShuffle;
+begin
+// MediaPlayerShuffle.Rewind;
+// MediaPlayerShuffle.Play;
+ 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;
+
+{ case PlayersPlay of
+ 1: begin
+ CaptureCard(0, 0, 1, 0);
+ end;
+ 2: begin
+ if Ini.TwoPlayerMode = 0 then begin
+ CaptureCard(0, 0, 1, 2);
+ end else begin
+ CaptureCard(0, 0, 1, 0);
+ CaptureCard(1, 1, 2, 0);
+ end;
+ end;
+ 3: begin
+ CaptureCard(0, 0, 1, 2);
+ CaptureCard(1, 1, 3, 0);
+ end;
+ end; // case}
+
+// CaptureCard(0, 0, 0, 0);
+// end;
+
+ {for SC := 0 to High(SoundCard) do begin
+ P1 := Ini.SoundCard[SC, 1];
+ P2 := Ini.SoundCard[SC, 2];
+ if P1 > PlayersPlay then P1 := 0;
+ if P2 > PlayersPlay then P2 := 0;
+ CaptureCard(SC, P1, P2);
+ end; }
+ // 0.5.2: new
+ 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
+{ if RecordSystem = 1 then begin
+ case PlayersPlay of
+ 1: begin
+ StopCard(0);
+ end;
+ 2: begin
+ if Ini.TwoPlayerMode = 0 then begin
+ StopCard(0);
+ end else begin
+ StopCard(0);
+ StopCard(1);
+ end;
+ end;
+ 3: begin
+ StopCard(0);
+ StopCard(1);
+ end;
+ end;
+ end;}
+
+ {for SC := 0 to High(SoundCard) do begin
+ StopCard(SC);
+ end; }
+
+ // 0.5.2
+ 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
+
+ //SoundCard[RecordI].BassRecordStream := BASS_RecordStart(44100, 2, MakeLong(0, 20) , @GetMicrophone, PlayerLeft + PlayerRight*256);
+ Recording.SoundCard[RecordI].BassRecordStream := BASS_RecordStart(44100, 2, MakeLong(0, 20) , @GetMicrophone, PlayerLeft + PlayerRight*256);
+
+ {if SoundCard[RecordI].BassRecordStream = 0 then begin
+ Error := BASS_ErrorGetCode;
+
+ ErrorMsg := IntToStr(Error);
+ if Error = BASS_ERROR_INIT then ErrorMsg := 'Not successfully called';
+ if Error = BASS_ERROR_ALREADY then ErrorMsg := 'Recording is already in progress';
+ if Error = BASS_ERROR_NOTAVAIL then ErrorMsg := 'The recording device is not available';
+ if Error = BASS_ERROR_FORMAT then ErrorMsg := 'The specified format is not supported';
+ if Error = BASS_ERROR_MEM then ErrorMsg := 'There is insufficent memory';
+ if Error = BASS_ERROR_UNKNOWN then ErrorMsg := 'Unknown';
+
+ Log.LogError('Error creating record stream [' + IntToStr(RecordI) + ', '
+ + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: '
+ + ErrorMsg);
+ end; }
+ end;
+end;
+
+procedure TMusic.StopCard(Card: byte);
+begin
+ BASS_RecordSetDevice(Card);
+ BASS_RecordFree;
+end;
+
+function TMusic.LoadPlayerFromFile(var MediaPlayer: TMediaPlayer; Name: string): boolean;
+begin
+ Log.LogStatus('Loading Sound: "' + Name + '"', 'LoadPlayerFromFile');
+ if FileExists(Name) then begin
+ try
+ MediaPlayer := TMediaPlayer.Create( nil );
+ except
+ Log.LogError('Failed to create MediaPlayer', 'LoadPlayerFromFile');
+ end;
+ try
+ MediaPlayer.ParentWindow := fHWND;
+ MediaPlayer.Wait := true;
+ MediaPlayer.FileName := Name;
+ MediaPlayer.DeviceType := dtAutoSelect;
+ MediaPlayer.Display := nil;
+ except
+ Log.LogError('Failed setting MediaPlayer: ' + MediaPlayer.ErrorMessage, 'LoadPlayerFromFile');
+ end;
+ try
+ MediaPlayer.Open;
+ except
+ Log.LogError('Failed to open using MediaPlayer', 'LoadPlayerFromFile');
+ end;
+ end else begin
+ Log.LogError('Sound not found: "' + Name + '"', 'LoadPlayerFromFile');
+ exit;
+ end;
+end;
+
+function TMusic.LoadSoundFromFile(var hStream: hStream; Name: string): boolean;
+begin
+ if FileExists(Name) then begin
+ Log.LogStatus('Loading Sound: "' + Name + '"', 'LoadPlayerFromFile');
+ try
+ hStream := BASS_StreamCreateFile(False, pchar(Name), 0, 0, 0);
+ except
+ Log.LogError('Failed to open using BASS', 'LoadPlayerFromFile');
+ end;
+ end else begin
+ Log.LogError('Sound not found: "' + Name + '"', 'LoadPlayerFromFile');
+ 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(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, 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.
diff --git a/Game/Code/Classes/UParty.dcu b/Game/Code/Classes/UParty.dcu
new file mode 100644
index 00000000..e3e1a901
--- /dev/null
+++ b/Game/Code/Classes/UParty.dcu
Binary files differ
diff --git a/Game/Code/Classes/UParty.pas b/Game/Code/Classes/UParty.pas
new file mode 100644
index 00000000..da89ca8a
--- /dev/null
+++ b/Game/Code/Classes/UParty.pas
@@ -0,0 +1,204 @@
+unit UParty;
+
+interface
+
+uses ModiSDK;
+
+type
+ TRoundInfo = record
+ Plugin: Word;
+ Winner: Byte;
+ end;
+
+ TParty_Session = class
+ private
+ function GetRandomPlayer(Team: Byte): Byte;
+ function IsWinner(Player, Winner: Byte): boolean;
+ procedure GenScores;
+ public
+ Teams: TTeamInfo;
+ Rounds: array of TRoundInfo;
+ CurRound: Byte;
+
+ constructor Create;
+
+ procedure StartNewParty;
+ procedure StartRound;
+ procedure EndRound;
+ function GetWinner: Byte;
+ function GetWinnerString(Round: Byte): String;
+ end;
+
+var
+ PartySession: TParty_Session;
+
+implementation
+
+uses UDLLManager, UGraphic, UMain, ULanguage, ULog;
+
+//----------
+//Constructor - Prepares the Class
+//----------
+constructor TParty_Session.Create;
+begin
+// - Nothing in here atm
+end;
+
+//----------
+//StartNewParty - Clears the Class and Prepares for new Party
+//----------
+procedure TParty_Session.StartNewParty;
+begin
+//Set cur Round to Round 1
+CurRound := 255;
+
+PlayersPlay := Teams.NumTeams;
+if isWinner(0,9) then
+ Log.LogError('Test');
+end;
+
+//----------
+//GetRandomPlayer - Gives back a Random Player to Play next Round
+//----------
+function TParty_Session.GetRandomPlayer(Team: Byte): Byte;
+var
+ I, J: Integer;
+ lowestTP: Byte;
+begin
+ //Get lowest TP
+ lowestTP := high(Byte);
+ J := -1;
+ for I := 0 to Teams.Teaminfo[Team].NumPlayers do
+ begin
+ if (Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed < lowestTP) then
+ begin
+ lowestTP := Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed;
+ J := I;
+ end
+ else if (Teams.Teaminfo[Team].Playerinfo[I].TimesPlayed = lowestTP) then
+ begin
+ J := -1;
+ end;
+ end;
+
+ //If more than one Person has lowestTP then Select Random Player
+ if (J < 0) then
+ repeat
+ Result := Random(Teams.Teaminfo[Team].NumPlayers);
+ until (Teams.Teaminfo[Team].Playerinfo[Result].TimesPlayed = lowestTP)
+ else //Else Select the one wth lowest TP
+ Result:= J;
+end;
+
+//----------
+//StartNextRound - Prepares ScreenSingModi for Next Round And Load Plugin
+//----------
+procedure TParty_Session.StartRound;
+var
+ I: Integer;
+begin
+ if ((CurRound < high(Rounds)) OR (CurRound = high(CurRound))) then
+ begin
+ //Increase Current Round
+ Inc (CurRound);
+
+ Rounds[CurRound].Winner := 0;
+ DllMan.LoadPlugin(Rounds[CurRound].Plugin);
+
+ //Select Players
+ for I := 0 to Teams.NumTeams do
+ Teams.Teaminfo[I].CurPlayer := GetRandomPlayer(I);
+
+ //Set ScreenSingModie Variables
+ ScreenSingModi.TeamInfo := Teams;
+
+ //Set
+ end;
+end;
+
+//----------
+//IsWinner - Returns True if the Players Bit is set in the Winner Byte
+//----------
+function TParty_Session.IsWinner(Player, Winner: Byte): boolean;
+var
+ Bit: Byte;
+begin
+ Case Player of
+ 0: Bit := 1;
+ 1: Bit := 2;
+ 2: Bit := 4;
+ 3: Bit := 8;
+ 4: Bit := 16;
+ 5: Bit := 32;
+ end;
+
+ Result := ((Winner AND Bit) = Bit);
+end;
+
+//----------
+//GenScores - Inc Scores for Cur. Round
+//----------
+procedure TParty_Session.GenScores;
+var
+ I: Byte;
+begin
+ for I := 0 to Teams.NumTeams do
+ begin
+ if isWinner(I, Rounds[CurRound].Winner) then
+ Inc(Teams.Teaminfo[I].Score);
+ end;
+end;
+
+//----------
+//GetWinnerString - Get String with WinnerTeam Name, when there is more than one Winner than Connect with and or ,
+//----------
+function TParty_Session.GetWinnerString(Round: Byte): String;
+var
+ Winners: Array of String;
+ I: Integer;
+begin
+ if (Rounds[Round].Winner = 0) then
+ begin
+ Result := 'Nobody';
+ exit;
+ end;
+
+ SetLength(Winners, 0);
+ for I := 0 to Teams.NumTeams do
+ begin
+ if isWinner(I, Rounds[Round].Winner) then
+ begin
+ SetLength(Winners, Length(Winners) + 1);
+ Winners[high(Winners)] := Teams.TeamInfo[I].Name;
+ end;
+ end;
+ Result := Language.Implode(Winners);
+end;
+
+//----------
+//EndRound - Get Winner from ScreenSingModi and Save Data to RoundArray
+//----------
+procedure TParty_Session.EndRound;
+var
+ I: Integer;
+begin
+ //Copy Winner
+ Rounds[CurRound].Winner := ScreenSingModi.Winner;
+ //Set Scores
+ GenScores;
+
+ //Increase TimesPlayed 4 all Players
+ For I := 0 to Teams.NumTeams do
+ Inc(Teams.Teaminfo[I].Playerinfo[Teams.Teaminfo[0].CurPlayer].TimesPlayed);
+
+end;
+
+//----------
+//Get Winner - Gives back the Number of the total Winner
+//----------
+function TParty_Session.GetWinner: Byte;
+begin
+
+end;
+
+end.
diff --git a/Game/Code/Classes/UPliki.dcu b/Game/Code/Classes/UPliki.dcu
new file mode 100644
index 00000000..1798b6f8
--- /dev/null
+++ b/Game/Code/Classes/UPliki.dcu
Binary files differ
diff --git a/Game/Code/Classes/UPliki.pas b/Game/Code/Classes/UPliki.pas
new file mode 100644
index 00000000..475a3752
--- /dev/null
+++ b/Game/Code/Classes/UPliki.pas
@@ -0,0 +1,830 @@
+unit UPliki;
+
+interface
+
+uses USongs, SysUtils, ULog, UMusic;
+
+procedure InitializePaths;
+function ReadHeader(var Song: TSong): boolean;
+function SkanujPlik(var Song: TSong): boolean;
+procedure CzyscNuty;
+function WczytajCzesci(Name: string): boolean;
+function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean;
+function SaveSongDebug(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean;
+
+var
+ GamePath: string;
+ SoundPath: string;
+ SongPath: string;
+ LogPath: string;
+ ThemePath: string;
+ ScreenshotsPath: string;
+ CoversPath: string;
+ LanguagesPath: string;
+ PluginPath: string;
+
+ Plik: TextFile; // all procedures in this unit operates on this file
+ PlikC: char;
+ Lineno: integer;
+
+ // variables available for all procedures
+ Base: array[0..1] of integer;
+ Rel: array[0..1] of integer;
+ Mult: integer;
+ MultBPM: integer;
+
+implementation
+uses TextGL, UIni, UMain, math;
+
+procedure InitializePaths;
+begin
+ GamePath := ExtractFilePath(ParamStr(0));
+ SoundPath := GamePath + 'Sounds\';
+ SongPath := GamePath + 'Songs\';
+ LogPath := GamePath;
+ ThemePath := GamePath + 'Themes\';
+ ScreenshotsPath := GamePath + 'Screenshots\';
+ CoversPath := GamePath + 'Covers\';
+ LanguagesPath := GamePath + 'Languages\';
+ //Modi Loader
+ PluginPath := GamePath + 'Plugins\';
+
+ DecimalSeparator := ',';
+end;
+
+function ReadHeader(var Song: TSong): boolean;
+var
+ TempC: char;
+ Tekst: string;
+ Done: integer;
+begin
+ // clear
+ Song.Title := '';
+ Song.Artist := '';
+ Song.Genre := 'Unknown';
+ Song.Edition := 'Unknown';
+ Song.Language := 'Unknown'; //Language Patch
+ Song.Mp3 := '';
+ Song.BPM := 0;
+ Song.GAP := 0;
+ Song.Start := 0;
+ Song.Finish := 0;
+ Song.Background := '';
+ Song.Video := '';
+ Song.VideoGAP := 0;
+ Song.NotesGAP := 0;
+ Song.Resolution := 4;
+
+ //Creator Patch
+ Song.Creator := '';
+
+ Done := 0;
+
+ //Editor Error Reporting Hack
+ LineNo := 0;
+ try
+
+ // read
+ Read(Plik, PlikC);
+ while (PlikC = '#') do begin
+ ReadLn(Plik, Tekst);
+
+ //Editor Error Reporting Hack
+ Inc (LineNo);
+
+ //Header Improvements Patch
+
+ if UpperCase(Copy(Tekst, 1, 6)) = 'TITLE:' then begin
+ Delete(Tekst, 1, 6);
+ Song.Title := Trim(Tekst);
+ Tekst := '';
+ Done := Done or 1;
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 7)) = 'ARTIST:' then begin
+ Delete(Tekst, 1, 7);
+ Song.Artist := Trim(Tekst);
+ Tekst := '';
+ Done := Done or 2;
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 4)) = 'MP3:' then begin
+ Delete(Tekst, 1, 4);
+ Song.Mp3 := Trim(Tekst);
+ Tekst := '';
+ Done := Done or 4;
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 8)) = 'CREATOR:' then begin // this goes for edit
+ Delete(Tekst, 1, 8);
+ Song.Creator := Trim(Tekst);
+ Tekst := '';
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 6)) = 'GENRE:' then begin // this goes for edit
+ Delete(Tekst, 1, 6);
+ Song.Genre := Trim(Tekst);
+ Tekst := '';
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 8)) = 'EDITION:' then begin // this goes for edit
+ Delete(Tekst, 1, 8);
+ Song.Edition := Trim(Tekst);
+ Tekst := '';
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 9)) = 'LANGUAGE:' then begin // this goes for edit
+ Delete(Tekst, 1, 9);
+ Song.Language := Trim(Tekst);
+ Tekst := '';
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 6)) = 'COVER:' then begin
+ Delete(Tekst, 1, 6);
+ Song.Cover := Trim(Tekst);
+ Tekst := '';
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 11)) = 'BACKGROUND:' then begin
+ Delete(Tekst, 1, 11);
+ Song.Background := Trim(Tekst);
+ Tekst := '';
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 6)) = 'VIDEO:' then begin
+ Delete(Tekst, 1, 6);
+ Song.Video := Trim(Tekst);
+ Tekst := '';
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 9)) = 'VIDEOGAP:' then begin
+ Delete(Tekst, 1, 9);
+
+ //Change . to , Mod by Whiteshark :P
+ if (Pos('.',Tekst) <> 0) then
+ begin
+ Tekst[Pos('.',Tekst)] := ',';
+ //Little Annonce for the User
+ Log.LogError('VideoGap Seperator wrong in SongHeader: ' + Song.FileName + ' [Corrected for this Session]');
+ end;
+
+ Song.VideoGAP := StrToFloat(Tekst);
+ Tekst := ''
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 9)) = 'NOTESGAP:' then begin
+ Delete(Tekst, 1, 9);
+ Song.NotesGAP := StrToInt(Tekst);
+ Tekst := ''
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 9)) = 'RELATIVE:' then begin
+ Delete(Tekst, 1, 9);
+ if LowerCase(Tekst) = 'yes' then Song.Relative := true;
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 6)) = 'START:' then begin
+ Delete(Tekst, 1, 6);
+ Song.Start := StrToFloat(Tekst);
+// Muzyka.Start := StrToInt(Tekst);
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 4)) = 'END:' then begin
+ Delete(Tekst, 1, 4);
+ Song.Finish := StrToInt(Tekst);
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 11)) = 'RESOLUTION:' then begin
+ Delete(Tekst, 1, 11);
+ Song.Resolution := StrToInt(Tekst);
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 4)) = 'BPM:' then begin
+ Delete(Tekst, 1, 4);
+
+// Muzyka.BPMOld := StrToFloat(Tekst) * Mult * MultBPM; // old system
+
+ (* new system with variable BPM *)
+// Muzyka.BPMOld := 50;
+
+ //Change . to , Mod by Whiteshark :P
+ if (Pos('.',Tekst) <> 0) then
+ begin
+ Tekst[Pos('.',Tekst)] := ',';
+ //Little Annonce for the User
+ Log.LogError('BPM Seperator wrong in SongHeader: ' + Song.FileName + ' [Corrected for this Session]');
+ end;
+
+ SetLength(Song.BPM, 1);
+ Song.BPM[0].StartBeat := 0;
+ Song.BPM[0].BPM := StrToFloat(Tekst) * Mult * MultBPM;
+ Tekst := '';
+ Done := Done or 8;
+ end
+
+ else if UpperCase(Copy(Tekst, 1, 4)) = 'GAP:' then begin
+ Delete(Tekst, 1, 4);
+ Song.GAP := StrToFloat(Tekst);
+ Tekst := '';
+// Muzyka.GAP := StrToFloat(Tekst);
+// Done := Done or 16;
+ end;
+
+ //Header Improvements Patch Ende
+
+ Read(Plik, PlikC);
+ end;
+
+ //Editor Error Reporting Hack
+ except //An Error happened<- bad english :P
+ Log.LogError('An Error occured reading Line ' + inttostr(LineNo) + ' from SongHeader: ' + Song.FileName);
+ Halt;
+ end;
+ //Editor Error Reporting Hack End
+
+ if Song.Background = '' then begin
+ Song.Background := Songs.FindSongFile(Song.Path, '*[BG].jpg');
+ end;
+
+ if (Done and 15) = 15 then Result := true
+ else Result := false;
+end;
+
+function SkanujPlik(var Song: TSong): boolean;
+var
+ Done: integer;
+ Tekst: string;
+ C: integer; // category
+ P: integer; // position
+begin
+// try
+ AssignFile(Plik, Song.Path + Song.FileName);
+ Reset(Plik);
+
+ Result := ReadHeader(Song);
+
+{ ReadLn(Plik, Tekst);
+ while (Copy(Tekst, 1, 1) = '#') do begin
+ if Copy(Tekst, 1, 10) = '#CATEGORY:' then begin
+ Delete(Tekst, 1, 10);
+
+ Trim(Tekst);
+ while (Length(Tekst) > 0) do begin
+ C := Length(Song.Category);
+ SetLength(Song.Category, C+1);
+
+ P := Pos(',', Tekst);
+ if P = 0 then P := Length(Tekst);
+ Song.Category[C] := Copy(Tekst, 1, P);
+
+ Delete(Tekst, 1, P);
+ Trim(Tekst);
+ end;
+
+ end;}
+
+
+end;
+
+procedure CzyscNuty;
+var
+ Pet: integer;
+begin
+ SetLength(Czesci, Length(Player));
+ SetLength(AktSong.BPM, 0);
+ for Pet := 0 to High(Player) do begin
+ SetLength(Czesci[Pet].Czesc, 1);
+ SetLength(Czesci[Pet].Czesc[0].Nuta, 0);
+ Czesci[Pet].Czesc[0].Lyric := '';
+ Czesci[Pet].Czesc[0].LyricWidth := 0;
+ Player[pet].Score := 0;
+ Player[pet].IlNut := 0;
+ Player[pet].HighNut := -1;
+ end;
+end;
+
+procedure DodajNute(NrCzesci: integer; TypeP: char; StartP, DurationP, NoteP: integer; LyricS: string);
+var
+ Space: boolean;
+begin
+ case Ini.Solmization of
+ 1: // european
+ begin
+ case (NoteP mod 12) of
+ 0..1: LyricS := ' do ';
+ 2..3: LyricS := ' re ';
+ 4: LyricS := ' mi ';
+ 5..6: LyricS := ' fa ';
+ 7..8: LyricS := ' sol ';
+ 9..10: LyricS := ' la ';
+ 11: LyricS := ' si ';
+ end;
+ end;
+ 2: // japanese
+ begin
+ case (NoteP mod 12) of
+ 0..1: LyricS := ' do ';
+ 2..3: LyricS := ' re ';
+ 4: LyricS := ' mi ';
+ 5..6: LyricS := ' fa ';
+ 7..8: LyricS := ' so ';
+ 9..10: LyricS := ' la ';
+ 11: LyricS := ' shi ';
+ end;
+ end;
+ 3: // american
+ begin
+ case (NoteP mod 12) of
+ 0..1: LyricS := ' do ';
+ 2..3: LyricS := ' re ';
+ 4: LyricS := ' mi ';
+ 5..6: LyricS := ' fa ';
+ 7..8: LyricS := ' sol ';
+ 9..10: LyricS := ' la ';
+ 11: LyricS := ' ti ';
+ end;
+ end;
+ end; // case
+
+// Log.LogStatus('Czesc: ' + IntToStr(Czesci[NrCzesci].High), 'DodajNute');
+// Log.LogStatus('Dodano: [' + IntToStr(NrCzesci) + '] ' + IntToStr(StartP) + ' '
+// + IntToStr(DurationP) + ' '+ IntToStr(NoteP) + ' ' + LyricS, 'DodajNute');
+
+{ Delete(LyricS, 1, 1);
+ Space := false;
+ if Copy(LyricS, Length(LyricS), 1) = ' ' then begin
+ Space := true;
+ Delete(LyricS, Length(LyricS), 1);
+ end;
+ if LyricS = 'a' then LyricS := chr($B1);
+ if LyricS = 'i' then LyricS := chr($B2);
+ if LyricS = 'u' then LyricS := chr($B3);
+ if LyricS = 'e' then LyricS := chr($B4);
+ if LyricS = 'o' then LyricS := chr($B5);
+
+ if LyricS = 'ka' then LyricS := chr($B6);
+ if LyricS = 'ki' then LyricS := chr($B7);
+ if LyricS = 'ku' then LyricS := chr($B8);
+ if LyricS = 'ke' then LyricS := chr($B9);
+ if LyricS = 'ko' then LyricS := chr($BA);
+
+ if LyricS = 'ga' then LyricS := chr($B6) + chr($DE);
+ if LyricS = 'gi' then LyricS := chr($B7) + chr($DE);
+ if LyricS = 'gu' then LyricS := chr($B8) + chr($DE);
+ if LyricS = 'ge' then LyricS := chr($B9) + chr($DE);
+ if LyricS = 'go' then LyricS := chr($BA) + chr($DE);
+
+ if LyricS = 'sa' then LyricS := chr($BB);
+ if LyricS = 'shi' then LyricS := chr($BC);
+ if LyricS = 'su' then LyricS := chr($BD);
+ if LyricS = 'se' then LyricS := chr($BE);
+ if LyricS = 'so' then LyricS := chr($BF);
+
+ if LyricS = 'za' then LyricS := chr($BB) + chr($DE);
+ if LyricS = 'ji' then LyricS := chr($BC) + chr($DE);
+ if LyricS = 'zu' then LyricS := chr($BD) + chr($DE);
+ if LyricS = 'ze' then LyricS := chr($BE) + chr($DE);
+ if LyricS = 'zo' then LyricS := chr($BF) + chr($DE);
+
+ if LyricS = 'ta' then LyricS := chr($C0);
+ if LyricS = 'chi' then LyricS := chr($C1);
+ if LyricS = 'tsu' then LyricS := chr($C2);
+ if LyricS = 'te' then LyricS := chr($C3);
+ if LyricS = 'to' then LyricS := chr($C4);
+
+ if LyricS = 'da' then LyricS := chr($C0) + chr($DE);
+// if LyricS = 'ji' then LyricS := chr($C1) + chr($DE);
+// if LyricS = 'zu' then LyricS := chr($C2) + chr($DE);
+ if LyricS = 'de' then LyricS := chr($C3) + chr($DE);
+ if LyricS = 'do' then LyricS := chr($C4) + chr($DE);
+
+ if LyricS = 'na' then LyricS := chr($C5);
+ if LyricS = 'ni' then LyricS := chr($C6);
+ if LyricS = 'nu' then LyricS := chr($C7);
+ if LyricS = 'ne' then LyricS := chr($C8);
+ if LyricS = 'no' then LyricS := chr($C9);
+
+ if LyricS = 'ha' then LyricS := chr($CA);
+ if LyricS = 'hi' then LyricS := chr($CB);
+ if LyricS = 'hu' then LyricS := chr($CC);
+ if LyricS = 'he' then LyricS := chr($CD);
+ if LyricS = 'ho' then LyricS := chr($CE);
+
+ if LyricS = 'ba' then LyricS := chr($CA) + chr($DE);
+ if LyricS = 'bi' then LyricS := chr($CB) + chr($DE);
+ if LyricS = 'bu' then LyricS := chr($CC) + chr($DE);
+ if LyricS = 'be' then LyricS := chr($CD) + chr($DE);
+ if LyricS = 'bo' then LyricS := chr($CE) + chr($DE);
+
+ if LyricS = 'pa' then LyricS := chr($CA) + chr($DF);
+ if LyricS = 'pi' then LyricS := chr($CB) + chr($DF);
+ if LyricS = 'pu' then LyricS := chr($CC) + chr($DF);
+ if LyricS = 'pe' then LyricS := chr($CD) + chr($DF);
+ if LyricS = 'po' then LyricS := chr($CE) + chr($DF);
+
+ if LyricS = 'ma' then LyricS := chr($CF);
+ if LyricS = 'mi' then LyricS := chr($D0);
+ if LyricS = 'mu' then LyricS := chr($D1);
+ if LyricS = 'me' then LyricS := chr($D2);
+ if LyricS = 'mo' then LyricS := chr($D3);
+
+ if LyricS = 'ya' then LyricS := chr($D4);
+ if LyricS = 'yu' then LyricS := chr($D5);
+ if LyricS = 'yo' then LyricS := chr($D6);
+
+ if LyricS = 'ra' then LyricS := chr($D7);
+ if LyricS = 'ri' then LyricS := chr($D8);
+ if LyricS = 'ru' then LyricS := chr($D9);
+ if LyricS = 're' then LyricS := chr($DA);
+ if LyricS = 'ro' then LyricS := chr($DB);
+
+ if LyricS = 'wa' then LyricS := chr($DC);
+ if LyricS = 'n' then LyricS := chr($DD);
+
+ LyricS := ' ' + LyricS;
+ if Space then LyricS := LyricS + ' ';}
+
+
+
+ with Czesci[NrCzesci].Czesc[Czesci[NrCzesci].High] do begin
+ SetLength(Nuta, Length(Nuta) + 1);
+ IlNut := IlNut + 1;
+ HighNut := HighNut + 1;
+ Muzyka.IlNut := Muzyka.IlNut + 1;
+
+ Nuta[HighNut].Start := StartP;
+ if IlNut = 1 then begin
+ StartNote := Nuta[HighNut].Start;
+ if Czesci[NrCzesci].Ilosc = 1 then
+ Start := -100;
+// Start := Nuta[HighNut].Start;
+ end;
+
+ Nuta[HighNut].Dlugosc := DurationP;
+ Muzyka.DlugoscNut := Muzyka.DlugoscNut + Nuta[HighNut].Dlugosc;
+
+ // back to the normal system with normal, golden and now freestyle notes
+ case TypeP of
+ 'F': Nuta[HighNut].Wartosc := 0;
+ ':': Nuta[HighNut].Wartosc := 1;
+ '*': Nuta[HighNut].Wartosc := 2;
+ end;
+ Czesci[NrCzesci].Wartosc := Czesci[NrCzesci].Wartosc + Nuta[HighNut].Dlugosc * Nuta[HighNut].Wartosc;
+
+ Nuta[HighNut].Ton := NoteP;
+ if Nuta[HighNut].Ton < Base[NrCzesci] then Base[NrCzesci] := Nuta[HighNut].Ton;
+ Nuta[HighNut].TonGamy := Nuta[HighNut].TonGamy mod 12;
+
+ Nuta[HighNut].Tekst := Copy(LyricS, 2, 100);
+ Lyric := Lyric + Nuta[HighNut].Tekst;
+
+ if TypeP = 'F' then
+ Nuta[HighNut].FreeStyle := true;
+
+ Koniec := Nuta[HighNut].Start + Nuta[HighNut].Dlugosc;
+ end; // with
+end;
+
+procedure NewSentence(NrCzesciP: integer; Param1, Param2: integer);
+var
+I: Integer;
+begin
+// Log.LogStatus('IlCzesci: ' + IntToStr(Czesci[NrCzesciP].Ilosc), 'NewSentece');
+// Log.LogStatus('Dane: ' + IntToStr(NrCzesciP) + ' ' + IntToStr(Param1) + ' ' + IntToStr(Param2) , 'NewSentece');
+
+ // stara czesc //Alter Satz //Update Old Part
+ Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].BaseNote := Base[NrCzesciP];
+ Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].LyricWidth := glTextWidth(PChar(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Lyric));
+
+ //Total Notes Patch
+ Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes := 0;
+ for I := low(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta) to high(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta) do
+ begin
+ Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes := Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes + Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta[I].Dlugosc * Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Nuta[I].Wartosc;
+ end;
+ //Log.LogError('Total Notes(' + inttostr(Czesci[NrCzesciP].High) +'): ' + inttostr(Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].TotalNotes));
+ //Total Notes Patch End
+
+
+ // nowa czesc //Neuer Satz //Update New Part
+ SetLength(Czesci[NrCzesciP].Czesc, Czesci[NrCzesciP].Ilosc + 1);
+ Czesci[NrCzesciP].High := Czesci[NrCzesciP].High + 1;
+ Czesci[NrCzesciP].Ilosc := Czesci[NrCzesciP].Ilosc + 1;
+ Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].HighNut := -1;
+
+ if not AktSong.Relative then
+ Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Start := Param1;
+
+ if AktSong.Relative then begin
+ Czesci[NrCzesciP].Czesc[Czesci[NrCzesciP].High].Start := Param1;
+ Rel[NrCzesciP] := Rel[NrCzesciP] + Param2;
+ end;
+
+ Base[NrCzesciP] := 100; // high number
+end;
+
+function WczytajCzesci(Name: string): boolean;
+var
+ TempC: char;
+ Tekst: string;
+ CP: integer; // Current Player (0 or 1)
+ Pet: integer;
+ Both: boolean;
+ Param1: integer;
+ Param2: integer;
+ Param3: integer;
+ ParamS: string;
+ I: Integer;
+begin
+ Result := false;
+
+ if not FileExists(Name) then begin
+ Log.LogError('File not found: "' + Name + '"', 'WczytajCzesci');
+ exit;
+ end;
+
+ try
+ MultBPM := 4; // 4 - mnoznik dla czasu nut
+ Mult := 1; // 4 - dokladnosc pomiaru nut
+ Base[0] := 100; // high number
+// Base[1] := 100; // high number
+ Czesci[0].Wartosc := 0;
+// Czesci[1].Wartosc := 0; // here was the error in 0.3.2
+ AktSong.Relative := false;
+
+ Rel[0] := 0;
+// Rel[1] := 0;
+ CP := 0;
+ Both := false;
+ if Length(Player) = 2 then Both := true;
+
+ FileMode := fmOpenRead;
+ AssignFile(Plik, Name);
+ Reset(Plik);
+
+ ReadHeader(AktSong);
+(* if AktSong.Title = 'Hubba Hubba Zoot Zoot' then begin
+ Mult := 2;
+ AktSong.BPM[0].BPM := AktSong.BPM[0].BPM * 2;
+ end;*)
+
+ SetLength(Czesci, 2);
+ for Pet := 0 to High(Czesci) do begin
+ SetLength(Czesci[Pet].Czesc, 1);
+ Czesci[Pet].High := 0;
+ Czesci[Pet].Ilosc := 1;
+ Czesci[Pet].Akt := 0;
+ Czesci[Pet].Resolution := AktSong.Resolution;
+ Czesci[Pet].NotesGAP := AktSong.NotesGAP;
+ Czesci[Pet].Czesc[0].IlNut := 0;
+ Czesci[Pet].Czesc[0].HighNut := -1;
+ end;
+
+// TempC := ':';
+ TempC := PlikC; // read from backup variable, don't use default ':' value
+
+ while (TempC <> 'E') do begin
+ Inc(LineNo);
+ if (TempC = ':') or (TempC = '*') or (TempC = 'F') then begin
+ // wczytuje nute
+ Read(Plik, Param1);
+ Read(Plik, Param2);
+ Read(Plik, Param3);
+ Read(Plik, ParamS);
+
+ // dodaje nute
+ if not Both then
+ // P1
+ DodajNute(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS)
+ else begin
+ // P1 + P2
+ DodajNute(0, TempC, (Param1+Rel[0]) * Mult, Param2 * Mult, Param3, ParamS);
+ DodajNute(1, TempC, (Param1+Rel[1]) * Mult, Param2 * Mult, Param3, ParamS);
+ end;
+ end; // if
+ if TempC = '-' then begin
+ // reads sentence
+ Read(Plik, Param1);
+ if AktSong.Relative then Read(Plik, Param2); // read one more data for relative system
+
+ // new sentence
+ if not Both then
+ // P1
+ NewSentence(0, (Param1 + Rel[0]) * Mult, Param2)
+ else begin
+ // P1 + P2
+ NewSentence(0, (Param1 + Rel[0]) * Mult, Param2);
+ NewSentence(1, (Param1 + Rel[1]) * Mult, Param2);
+ end;
+
+ end; // if
+
+ if TempC = 'B' then begin
+ SetLength(AktSong.BPM, Length(AktSong.BPM) + 1);
+ Read(Plik, AktSong.BPM[High(AktSong.BPM)].StartBeat);
+ AktSong.BPM[High(AktSong.BPM)].StartBeat := AktSong.BPM[High(AktSong.BPM)].StartBeat + Rel[0];
+
+ Read(Plik, Tekst);
+ AktSong.BPM[High(AktSong.BPM)].BPM := StrToFloat(Tekst);
+ AktSong.BPM[High(AktSong.BPM)].BPM := AktSong.BPM[High(AktSong.BPM)].BPM * Mult * MultBPM;
+ end;
+
+
+ if not Both then begin
+ Czesci[CP].Czesc[Czesci[CP].High].BaseNote := Base[CP];
+ Czesci[CP].Czesc[Czesci[CP].High].LyricWidth := glTextWidth(PChar(Czesci[CP].Czesc[Czesci[CP].High].Lyric));
+ //Total Notes Patch
+ Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := 0;
+ for I := low(Czesci[CP].Czesc[Czesci[CP].High].Nuta) to high(Czesci[CP].Czesc[Czesci[CP].High].Nuta) do
+ begin
+ Czesci[CP].Czesc[Czesci[CP].High].TotalNotes := Czesci[CP].Czesc[Czesci[CP].High].TotalNotes + Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Dlugosc * Czesci[CP].Czesc[Czesci[CP].High].Nuta[I].Wartosc;
+ end;
+ //Total Notes Patch End
+ end else begin
+ for Pet := 0 to High(Czesci) do begin
+ Czesci[Pet].Czesc[Czesci[Pet].High].BaseNote := Base[Pet];
+ Czesci[Pet].Czesc[Czesci[Pet].High].LyricWidth := glTextWidth(PChar(Czesci[Pet].Czesc[Czesci[Pet].High].Lyric));
+ //Total Notes Patch
+ Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := 0;
+ for I := low(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) to high(Czesci[Pet].Czesc[Czesci[Pet].High].Nuta) do
+ begin
+ Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes := Czesci[Pet].Czesc[Czesci[Pet].High].TotalNotes + Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Dlugosc * Czesci[Pet].Czesc[Czesci[Pet].High].Nuta[I].Wartosc;
+ end;
+ //Total Notes Patch End
+ end;
+ end;
+
+ Read(Plik, TempC);
+ end; // while}
+
+ CloseFile(Plik);
+ except
+ Log.LogError('Error Loading File: "' + Name + '" in Line ' + inttostr(LineNo));
+ exit;
+ end;
+
+ Result := true;
+end;
+
+function SaveSong(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean;
+var
+ C: integer;
+ N: integer;
+ S: string;
+ B: integer;
+ RelativeSubTime: integer;
+ NoteState: String;
+
+begin
+// Relative := true; // override (idea - use shift+S to save with relative)
+ AssignFile(Plik, Name);
+ Rewrite(Plik);
+
+ WriteLn(Plik, '#TITLE:' + Song.Title + '');
+ WriteLn(Plik, '#ARTIST:' + Song.Artist);
+
+ if Song.Creator <> '' then WriteLn(Plik, '#CREATOR:' + Song.Creator);
+ if Song.Edition <> 'Unknown' then WriteLn(Plik, '#EDITION:' + Song.Edition);
+ if Song.Genre <> 'Unknown' then WriteLn(Plik, '#GENRE:' + Song.Genre);
+ if Song.Language <> 'Unknown' then WriteLn(Plik, '#LANGUAGE:' + Song.Language);
+ if Song.Cover <> '' then WriteLn(Plik, '#COVER:' + Song.Cover);
+
+ WriteLn(Plik, '#MP3:' + Song.Mp3);
+
+ if Song.Background <> '' then WriteLn(Plik, '#BACKGROUND:' + Song.Background);
+ if Song.Video <> '' then WriteLn(Plik, '#VIDEO:' + Song.Video);
+ if Song.VideoGAP <> 0 then WriteLn(Plik, '#VIDEOGAP:' + FloatToStr(Song.VideoGAP));
+ if Song.Resolution <> 4 then WriteLn(Plik, '#RESOLUTION:' + IntToStr(Song.Resolution));
+ if Song.NotesGAP <> 0 then WriteLn(Plik, '#NOTESGAP:' + IntToStr(Song.NotesGAP));
+ if Song.Start <> 0 then WriteLn(Plik, '#START:' + FloatToStr(Song.Start));
+ if Song.Finish <> 0 then WriteLn(Plik, '#END:' + IntToStr(Song.Finish));
+ if Relative then WriteLn(Plik, '#RELATIVE:yes');
+
+ WriteLn(Plik, '#BPM:' + FloatToStr(Song.BPM[0].BPM / 4));
+ WriteLn(Plik, '#GAP:' + FloatToStr(Song.GAP));
+
+ RelativeSubTime := 0;
+ for B := 1 to High(AktSong.BPM) do
+ WriteLn(Plik, 'B ' + FloatToStr(AktSong.BPM[B].StartBeat) + ' ' + FloatToStr(AktSong.BPM[B].BPM/4));
+
+ for C := 0 to Czesc.High do begin
+ for N := 0 to Czesc.Czesc[C].HighNut do begin
+ with Czesc.Czesc[C].Nuta[N] do begin
+
+
+ //Golden + Freestyle Note Patch
+ case Czesc.Czesc[C].Nuta[N].Wartosc of
+ 0: NoteState := 'F ';
+ 1: NoteState := ': ';
+ 2: NoteState := '* ';
+ end; // case
+ S := NoteState + IntToStr(Start-RelativeSubTime) + ' ' + IntToStr(Dlugosc) + ' ' + IntToStr(Ton) + ' ' + Tekst;
+
+
+ WriteLn(Plik, S);
+ end; // with
+ end; // N
+
+ if C < Czesc.High then begin // don't write end of last sentence
+ if not Relative then
+ S := '- ' + IntToStr(Czesc.Czesc[C+1].Start)
+ else begin
+ S := '- ' + IntToStr(Czesc.Czesc[C+1].Start - RelativeSubTime) +
+ ' ' + IntToStr(Czesc.Czesc[C+1].Start - RelativeSubTime);
+ RelativeSubTime := Czesc.Czesc[C+1].Start;
+ end;
+ WriteLn(Plik, S);
+ end;
+
+ end; // C
+
+
+ WriteLn(Plik, 'E');
+ CloseFile(Plik);
+end;
+
+function SaveSongDebug(Song: TSong; Czesc: TCzesci; Name: string; Relative: boolean): boolean;
+var
+ C: integer;
+ N: integer;
+ S: string;
+ STon: integer;
+ SLen: integer;
+ NTot: integer;
+ PlikB: TextFile;
+ LastTime: integer;
+begin
+ AssignFile(Plik, Name);
+ Rewrite(Plik);
+
+ AssignFile(PlikB, 'C:\song db.asm');
+ Rewrite(PlikB);
+
+ NTot := 0;
+ LastTime := 0;
+
+ for C := 0 to Czesc.High do begin
+ WriteLn(Plik, '; ' + IntToStr(C));
+
+ for N := 0 to Czesc.Czesc[C].HighNut do begin
+ with Czesc.Czesc[C].Nuta[N] do begin
+
+ // timespace
+ if LastTime < Start then begin
+ STon := 0;
+ SLen := Round((Start - LastTime) * 16320 / 255 / 12);
+ WriteLn(PlikB, ' .dw ' + IntToStr(STon + SLen*256) + ' ; timespace (0, ' + IntToStr(SLen) + ')');
+
+ end;
+
+
+
+ // ton
+ STon := Round(98940/(2*261.62*Power(1.05946309436, Ton)));
+ S := ' ldi R18, ' + IntToStr(STon);
+ if STon > 255 then begin
+ beep;
+ S := '!!!!' + S;
+ end;
+ WriteLn(Plik, S);
+
+ // length
+ //ldi R19, 43
+ SLen := Round(Dlugosc * 16320 / STon / 12);
+ S := ' ldi R19, ' + IntToStr(SLen);
+ if SLen > 255 then begin
+ beep;
+ S := '!!!!' + S;
+ end;
+ WriteLn(Plik, S);
+
+ // function
+ S := ' rcall playtone';
+ WriteLn(Plik, S);
+
+ // song dw
+ WriteLn(PlikB, ' .dw ' + IntToStr(STon + SLen*256));
+
+
+ LastTime := Start + Dlugosc;
+ Inc(NTot);
+
+ end; // with
+ end; // N
+ WriteLn(Plik, '');
+ WriteLn(PlikB, '');
+ end; // C
+
+ WriteLn(Plik, '; nut ' + IntToStr(NTot));
+ WriteLn(Plik, '; bajtów ' + IntToStr(8*NTot));
+
+ WriteLn(PlikB, ' .dw 0');
+ WriteLn(PlikB, '; nut ' + IntToStr(NTot));
+ WriteLn(PlikB, '; bajtów ' + IntToStr(2*NTot));
+
+
+ CloseFile(Plik);
+ CloseFile(PlikB);
+end;
+
+end.
diff --git a/Game/Code/Classes/URecord.dcu b/Game/Code/Classes/URecord.dcu
new file mode 100644
index 00000000..d28aa4b1
--- /dev/null
+++ b/Game/Code/Classes/URecord.dcu
Binary files differ
diff --git a/Game/Code/Classes/URecord.pas b/Game/Code/Classes/URecord.pas
new file mode 100644
index 00000000..2ec5439a
--- /dev/null
+++ b/Game/Code/Classes/URecord.pas
@@ -0,0 +1,371 @@
+unit URecord;
+
+interface
+uses Classes, Math, SysUtils, {DXSounds, Wave, }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
+// Spectrum: array[1..8192] of single; // sound buffer from above as FFT
+// Spektogram: array[0..100] of TSpekt; // FFT(t)
+
+ // 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;
+ InputSeleceted: 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, ULog;
+
+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
+// Log.LogAnalyze('[Analyze by Autocorrelation]');
+ SzczytJest := false;
+
+ // find maximum volume of first 1024 words of signal
+ MaxV := 0;
+ for S := 1 to 1024 do begin // 0.5.2: fix. was from 0 to 1023
+// Log.LogDebug('1');
+// Log.LogDebug(IntTostr(S));
+ V := Abs(BufferArray[S]) / $10000;
+// Log.LogDebug('2');
+// Log.LogDebug(IntTostr(S) + ': ' + FloatToStr(V) + ', MaxV='+floattostr(maxv)+', buf='+inttostr(length(BufferArray)));
+ if V > MaxV then MaxV := V;
+// Log.LogDebug('3');
+// Log.LogDebug(IntTostr(S) + ': ' + FloatToStr(V) + ', MaxV='+floattostr(maxv)+', buf='+inttostr(length(BufferArray)));
+ end;
+
+
+ // prepare to analyze
+ MaxW := 0;
+
+ // analyze all 12 halftones
+ for T := 0 to 35 do begin // to 11, then 23, now 35 (for Whitney and my high voice)
+ 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;
+
+ //Log.LogDebug('Sound -> AnalyzeByAutocorrelation: MaxV='+floattostr(maxv)+', Threshold='+floattostr(threshold));
+ if MaxV >= Threshold then begin // found acceptable volume // 0.1
+ SzczytJest := true;
+ TonGamy := MaxT mod 12;
+ Ton := MaxT mod 12;
+ end;
+
+// Log.LogAnalyze('--> Weight: ')
+// Log.LogAnalyze('--> Selected: ' + BoolToStr(SzczytJest, true) +
+// ', TonGamy: ' + IntToStr(Ton) +
+// ', MaxV: ' + FloatToStr(MaxV));
+// Log.LogAnalyze('');
+
+
+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 1 - sample 1 and compare n-times
+{ while (Src <= Move) do begin // process by moving Src by one
+ while (Dst < n) do begin // process up to n (4KB) of Signal
+ Count := Count + Abs(Signal[Src] - Signal[Dst]) / $10000;
+ Inc(Dst, Move);
+ Inc(Il);
+ end;
+
+ Inc(Src);
+ Dst := Src + Move;
+ end;}
+
+ // 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;
+ PW: pwordarray;
+ SI: smallintarray;
+ PSI: psmallintarray;
+ I: integer;
+ Skip: integer;
+ P1: integer;
+ P2: integer;
+ Boost: byte;
+begin
+// Log.LogDebug('Record -> GetMicrophone: len='+inttstr(len));
+
+ // 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;
+
+// Log.LogDebug('Record -> GetMicrophone: P1='+inttostr(p1)+', P2='+inttostr(p2));
+
+ // 2 players USB mic, left channel
+ if P1 >= 0 then begin
+ L := Len div 4; // number of samples
+ PB := Buffer;
+// Log.LogDebug('Record -> GetMicrophone -> Sound[P1].BufferNew.Clear');
+ 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
+// if Ini.Debug = 0 then Skip := 2
+// else Skip := 0;
+ 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;
+
+// Log.LogDebug('Record -> GetMicrophone -> Finish');
+
+ Result := true;
+end;
+
+constructor TRecord.Create;
+var
+ SC: integer; // soundcard
+ SCI: integer; // soundcard input
+ Descr: string;
+ InputName: string;
+ 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;
+
+// mic: array[0..15] of integer;
+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);
+// Log.LogError('Device #' + IntToStr(SC+1) + ': ' + Descr);
+ SoundCard[SC].Description := Descr;
+
+ // check for recording inputs
+// mic[device] := -1; // default to no change
+ SCI := 0;
+ BASS_RecordInit(SC);
+ Flags := BASS_RecordGetInput(SCI);
+ InputName := BASS_RecordGetInputName(SCI);
+// Log.LogError('Input #' + IntToStr(SCI) + ' (' + IntToStr(Flags) + '): ' + InputName);
+
+ SetLength(SoundCard[SC].Input, 1);
+ SoundCard[SC].Input[SCI].Name := InputName;
+
+ // process each input
+ while (Flags <> -1) do begin
+ if SCI >= 1 then begin
+ SetLength(SoundCard[SC].Input, SCI+1);
+ InputName := BASS_RecordGetInputName(SCI);
+ SoundCard[SC].Input[SCI].Name := InputName;
+// Log.LogError('Input #' + IntToStr(SCI) + ' (' + IntToStr(Flags) + '): ' + InputName);
+ end;
+
+{ if (flags and BASS_INPUT_TYPE_MASK) = BASS_INPUT_TYPE_MIC then begin
+ mic[device] := input; // auto set microphone
+ end;}
+
+ Inc(SCI);
+ Flags := BASS_RecordGetInput(SCI);
+ 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(SC);
+ Descr := BASS_RecordGetDeviceDescription(SC);
+ end; // while
+end;
+end.
+
+
diff --git a/Game/Code/Classes/UScores.dcu b/Game/Code/Classes/UScores.dcu
new file mode 100644
index 00000000..16454265
--- /dev/null
+++ b/Game/Code/Classes/UScores.dcu
Binary files differ
diff --git a/Game/Code/Classes/UScores.pas b/Game/Code/Classes/UScores.pas
new file mode 100644
index 00000000..f1243868
--- /dev/null
+++ b/Game/Code/Classes/UScores.pas
@@ -0,0 +1,144 @@
+unit UScores;
+
+interface
+
+uses USongs, SQLiteTable3;
+
+procedure InitScore(const Filename: string);
+procedure ReadScore(var Song: TSong);
+procedure WriteScore(var Song: TSong);
+procedure AddScore(var Song: TSong; Level: integer; Name: string; Score: integer);
+
+var
+ScoreDB: TSqliteDatabase;
+sFilename: string;
+
+implementation
+
+uses IniFiles, SysUtils;
+
+procedure InitScore(const Filename: string);
+//var
+ //TableData: TSqliteTable;
+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 );');
+
+ finally
+ //ScoreDB.Free;
+ end;
+
+end;
+
+procedure 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;
+
+procedure AddScore(var Song: TSong; Level: integer; Name: string; Score: integer);
+var
+ID: Integer;
+TableData: TSqliteTable;
+begin
+ //ScoreDB := TSqliteDatabase.Create(sFilename);
+ try
+
+ 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` ) VALUES (NULL , "' + Song.Artist + '", "' + Song.Title + '");');
+ 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;
+
+ finally
+ //ScoreDB.Free;
+ end;
+end;
+
+//Not used with new SQLLite DB System
+procedure WriteScore(var Song: TSong);
+{var
+ F: TIniFile;
+ S: integer;
+ Lev: integer;
+ LevS: string;
+ FileName: string;}
+begin
+ {FileName := Song.Path + ChangeFileExt(Song.FileName, '.sco');
+ if (not FileExists(FileName)) or (FileExists(FileName) and DeleteFile(FileName)) then begin
+ // file has been deleted -> creating new file
+ F := TIniFile.Create(FileName);
+
+ for Lev := 0 to 2 do begin
+ case Lev of
+ 0: LevS := 'Easy';
+ 1: LevS := 'Normal';
+ 2: LevS := 'Hard';
+ end;
+
+ for S := 0 to high(Song.Score[Lev]) do begin
+ F.WriteString(LevS + IntToStr(S+1), 'Name', Song.Score[Lev, S].Name);
+ F.WriteInteger(LevS + IntToStr(S+1), 'Score', Song.Score[Lev, S].Score);
+
+ end; // for S
+ end; // for Lev
+ F.Free;
+ end; // if}
+end;
+
+end.
diff --git a/Game/Code/Classes/USkins.dcu b/Game/Code/Classes/USkins.dcu
new file mode 100644
index 00000000..89ea67c0
--- /dev/null
+++ b/Game/Code/Classes/USkins.dcu
Binary files differ
diff --git a/Game/Code/Classes/USkins.pas b/Game/Code/Classes/USkins.pas
new file mode 100644
index 00000000..6cd4a1db
--- /dev/null
+++ b/Game/Code/Classes/USkins.pas
@@ -0,0 +1,158 @@
+unit USkins;
+
+interface
+
+type
+ TSkinTexture = record
+ Name: string;
+ FileName: string;
+ end;
+
+ TSkinEntry = record
+ Theme: string;
+ Name: string;
+ Path: string;
+ FileName: string;
+ Creator: string; // not used yet
+ end;
+
+ TSkin = class
+ Skin: array of TSkinEntry;
+ SkinTexture: array of TSkinTexture;
+ SkinPath: string;
+ Color: integer;
+ constructor Create;
+ procedure LoadList;
+ procedure ParseDir(Dir: string);
+ procedure LoadHeader(FileName: string);
+ procedure LoadSkin(Name: string);
+ function GetTextureFileName(TextureName: string): string;
+ function GetSkinNumber(Name: string): integer;
+ procedure onThemeChange;
+ end;
+
+var
+ Skin: TSkin;
+
+implementation
+
+uses IniFiles, Classes, SysUtils, ULog, UIni;
+
+constructor TSkin.Create;
+begin
+ LoadList;
+// LoadSkin('Lisek');
+// SkinColor := Color;
+end;
+
+procedure TSkin.LoadList;
+var
+ SR: TSearchRec;
+ SR2: TSearchRec;
+ SLen: integer;
+begin
+ if FindFirst('Skins\*', faDirectory, SR) = 0 then begin
+ repeat
+ if (SR.Name <> '.') and (SR.Name <> '..') then
+ ParseDir('Skins\' + SR.Name + '\');
+ until FindNext(SR) <> 0;
+ end; // if
+ FindClose(SR);
+end;
+
+procedure TSkin.ParseDir(Dir: string);
+var
+ SR: TSearchRec;
+ SLen: integer;
+begin
+ if FindFirst(Dir + '*.ini', faAnyFile, SR) = 0 then begin
+ repeat
+ if (SR.Name <> '.') and (SR.Name <> '..') then
+ LoadHeader(Dir + SR.Name);
+ //Log.LogError(SR.Name);
+ until FindNext(SR) <> 0;
+ end;
+end;
+
+procedure TSkin.LoadHeader(FileName: string);
+var
+ SkinIni: TMemIniFile;
+ S: integer;
+begin
+ SkinIni := TMemIniFile.Create(FileName);
+
+ S := Length(Skin);
+ SetLength(Skin, S+1);
+ Skin[S].Path := IncludeTrailingBackslash(ExtractFileDir(FileName));
+ Skin[S].FileName := ExtractFileName(FileName);
+ Skin[S].Theme := SkinIni.ReadString('Skin', 'Theme', '');
+ Skin[S].Name := SkinIni.ReadString('Skin', 'Name', '');
+ Skin[S].Creator := SkinIni.ReadString('Skin', 'Creator', '');
+
+ SkinIni.Free;
+end;
+
+procedure TSkin.LoadSkin(Name: string);
+var
+ SkinIni: TMemIniFile;
+ SL: TStringList;
+ T: integer;
+ S: integer;
+begin
+ S := GetSkinNumber(Name);
+ SkinPath := Skin[S].Path;
+
+ SkinIni := TMemIniFile.Create(SkinPath + Skin[S].FileName);
+
+ SL := TStringList.Create;
+ SkinIni.ReadSection('Textures', SL);
+
+ SetLength(SkinTexture, SL.Count);
+ for T := 0 to SL.Count-1 do begin
+ SkinTexture[T].Name := SL.Strings[T];
+ SkinTexture[T].FileName := SkinIni.ReadString('Textures', SL.Strings[T], '');
+ end;
+
+ SL.Free;
+ SkinIni.Free;
+end;
+
+function TSkin.GetTextureFileName(TextureName: string): string;
+var
+ T: integer;
+begin
+ Result := '';
+ for T := 0 to High(SkinTexture) do
+ if SkinTexture[T].Name = TextureName then Result := SkinPath + SkinTexture[T].FileName;
+
+{ Result := SkinPath + 'Bar.jpg';
+ if TextureName = 'Ball' then Result := SkinPath + 'Ball.bmp';
+ if Copy(TextureName, 1, 4) = 'Gray' then Result := SkinPath + 'Ball.bmp';
+ if Copy(TextureName, 1, 6) = 'NoteBG' then Result := SkinPath + 'Ball.bmp';}
+end;
+
+function TSkin.GetSkinNumber(Name: string): integer;
+var
+ S: integer;
+begin
+ Result := 0; // set default to the first available skin
+ for S := 0 to High(Skin) do
+ if Skin[S].Name = Name then Result := S;
+end;
+
+procedure TSkin.onThemeChange;
+var
+ S: integer;
+ Name: String;
+begin
+ SetLength(ISkin, 0);
+ Name := Uppercase(ITheme[Ini.Theme]);
+ for S := 0 to High(Skin) do
+ if Name = Uppercase(Skin[S].Theme) then begin
+ SetLength(ISkin, Length(ISkin)+1);
+ ISkin[High(ISkin)] := Skin[S].Name;
+ end;
+
+end;
+
+end.
diff --git a/Game/Code/Classes/USongs.dcu b/Game/Code/Classes/USongs.dcu
new file mode 100644
index 00000000..e58c47d8
--- /dev/null
+++ b/Game/Code/Classes/USongs.dcu
Binary files differ
diff --git a/Game/Code/Classes/USongs.pas b/Game/Code/Classes/USongs.pas
new file mode 100644
index 00000000..c2532a03
--- /dev/null
+++ b/Game/Code/Classes/USongs.pas
@@ -0,0 +1,667 @@
+unit USongs;
+
+interface
+uses SysUtils, ULog, UTexture, UCatCovers;
+
+type
+ TBPM = record
+ BPM: real;
+ StartBeat: real;
+ end;
+
+ TScore = record
+ Name: string;
+ Score: integer;
+ Length: string;
+ end;
+
+ TSong = record
+ Path: string;
+ Folder: string; // for sorting by folder
+ FileName: string;
+
+ // sorting methods
+ Category: array of string; // I think I won't need this
+ Genre: string;
+ Edition: string;
+ Language: string; // 0.5.0: new
+
+ Title: string;
+ Artist: string;
+
+ Text: string;
+ Creator: string;
+
+ Cover: string;
+ CoverTex: TTexture;
+ Mp3: string;
+ Background: string;
+ Video: string;
+ VideoGAP: real;
+ VideoLoaded: boolean; // 0.5.0: true if the video has been loaded
+ NotesGAP: integer;
+ Start: real; // in seconds
+ Finish: integer; // in miliseconds
+ Relative: boolean;
+ Resolution: integer;
+ BPM: array of TBPM;
+ GAP: real; // in miliseconds
+
+ Score: array[0..2] of array of TScore;
+
+ // these are used when sorting is enabled
+ Visible: boolean; // false if hidden, true if visible
+ Main: boolean; // false for songs, true for category buttons
+ OrderNum: integer; // has a number of category for category buttons and songs
+ OrderTyp: integer; // type of sorting for this button (0=name)
+ CatNumber: integer; // Count of Songs in Category for Cats and Number of Song in Category for Songs
+ end;
+
+ TSongs = class
+ Song: array of TSong; // array of songs
+ Selected: integer; // selected song index
+ procedure LoadSongList; // load all songs
+ procedure BrowseDir(Dir: string); // should return number of songs in the future
+ procedure Sort(Order: integer);
+ function FindSongFile(Dir, Mask: string): string;
+ end;
+
+ TCatSongs = class
+ Song: array of TSong; // array of categories with songs
+ Selected: integer; // selected song index
+ Order: integer; // order type (0=title)
+ CatNumShow: integer; // Category Number being seen
+ CatCount: integer; //Number of Categorys
+
+ procedure Refresh; // refreshes arrays by recreating them from Songs array
+// procedure Sort(Order: integer);
+ procedure ShowCategory(Index: integer); // expands all songs in category
+ procedure HideCategory(Index: integer); // hides all songs in category
+ procedure ClickCategoryButton(Index: integer); // uses ShowCategory and HideCategory when needed
+ procedure ShowCategoryList; //Hides all Songs And Show the List of all Categorys
+ function FindNextVisible(SearchFrom:integer): integer; //Find Next visible Song
+ function VisibleSongs: integer; // returns number of visible songs (for tabs)
+ function VisibleIndex(Index: integer): integer; // returns visible song index (skips invisible)
+ end;
+
+var
+ Songs: TSongs; // all songs
+ CatSongs: TCatSongs; // categorized songs
+ AktSong: TSong; // one song *unknown use)
+
+implementation
+
+uses UPliki, UIni, UFiles;
+
+procedure TSongs.LoadSongList;
+begin
+ Log.LogStatus('Initializing', 'LoadSongList');
+
+ // clear
+ Setlength(Song, 0);
+
+ // browse directories
+ BrowseDir(SongPath);
+// if Ini.Debug = 1 then BrowseDir('D:\Extract\Songs\');
+end;
+
+procedure TSongs.BrowseDir(Dir: string);
+var
+ SR: TSearchRec; // for parsing Songs Directory
+ SLen: integer;
+begin
+ if FindFirst(Dir + '*', faDirectory, SR) = 0 then begin
+ repeat
+ if (SR.Name <> '.') and (SR.Name <> '..') then
+ BrowseDir(Dir + Sr.Name + '\');
+ until FindNext(SR) <> 0;
+ end; // if
+ FindClose(SR);
+
+// Log.LogStatus('Parsing directory: ' + Dir + SR.Name, 'LoadSongList');
+
+ if FindFirst(Dir + '*.txt', 0, SR) = 0 then begin
+// Log.LogStatus('Parsing file: ' + Dir + SR.Name + '\' + SRD.Name, 'LoadSongList');
+ repeat
+ SLen := Length(Song);
+ SetLength(Song, SLen + 1);
+ Song[SLen].Path := Dir;
+ Song[SLen].Folder := Copy(Dir, Length(SongPath)+1, 10000);
+ Song[SLen].Folder := Copy(Song[SLen].Folder, 1, Pos('\', Song[SLen].Folder)-1);
+ Song[SLen].FileName := SR.Name;
+
+ if (AnalyseFile(Song[SLen]) = false) then SetLength(Song, SLen)
+ else begin
+ // scanning complete, file is good
+ // if there is no cover then try to find it
+ if Song[SLen].Cover = '' then Song[SLen].Cover := FindSongFile(Dir, '*[CO].jpg');
+// if Song[SLen].Background = '' then begin
+// Song[SLen].Background := FindSongFile(Dir, '*[BG].jpg');
+// end; // no needed here}
+
+ // fix by adding path. no, don't fix it.
+// if Song[SLen].Cover <> '' then
+// Song[SLen].Cover := Song[SLen].Path + Song[SLen].Cover;
+ end;
+
+ until FindNext(SR) <> 0;
+ end; // if FindFirst
+ FindClose(SR);
+end;
+
+procedure TSongs.Sort(Order: integer);
+var
+ S: integer;
+ S2: integer;
+ TempSong: TSong;
+begin
+ case Order of
+ sEdition: // by edition
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if Song[S].Edition < Song[S-1].Edition then begin
+ // zamiana miejscami
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+ end;
+ sGenre: // by genre
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if Song[S].Genre < Song[S-1].Genre then begin
+ // zamiana miejscami
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+ end;
+ sTitle: // by title
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if Song[S].Title < Song[S-1].Title then begin
+ // zamiana miejscami
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+
+ end;
+ sArtist: // by artist
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if Song[S].Artist < Song[S-1].Artist then begin
+ // zamiana miejscami
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+ end;
+ sFolder: // by folder
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if Song[S].Folder < Song[S-1].Folder then begin
+ // zamiana miejscami
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+ end;
+ sTitle2: // by title2
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if Song[S].Title < Song[S-1].Title then begin
+ // zamiana miejscami
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+
+ end;
+ sArtist2: // by artist2
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if Song[S].Artist < Song[S-1].Artist then begin
+ // zamiana miejscami
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+ end;
+ sLanguage: // by Language
+ begin
+ for S2 := 0 to Length(Song)-1 do
+ for S := 1 to Length(Song)-1 do
+ if Song[S].Language < Song[S-1].Language then begin
+ TempSong := Song[S-1];
+ Song[S-1] := Song[S];
+ Song[S] := TempSong;
+ end;
+ end;
+
+ end; // case
+end;
+
+function TSongs.FindSongFile(Dir, Mask: string): string;
+var
+ SR: TSearchRec; // for parsing song directory
+begin
+ Result := '';
+ if FindFirst(Dir + Mask, faDirectory, SR) = 0 then begin
+ Result := SR.Name;
+ end; // if
+ FindClose(SR);
+end;
+
+procedure TCatSongs.Refresh;
+var
+ S: integer; // temporary song index
+ CatLen: integer; // length of CatSongs.Song
+ Letter: char; // current letter for sorting using letter
+ SS: string; // current edition for sorting using edition, genre etc.
+ Order: integer; // number used for ordernum
+ Letter2: char; //
+ CatNumber:integer; // Number of Song in Category
+begin
+ CatNumShow := -1;
+// Songs.Sort(0); // by title
+
+case Ini.Sorting of
+ sEdition: begin
+ Songs.Sort(sArtist);
+ Songs.Sort(sEdition);
+ end;
+ sGenre: begin
+ Songs.Sort(sArtist);
+ Songs.Sort(sGenre);
+ end;
+ sLanguage: begin
+ Songs.Sort(sArtist);
+ Songs.Sort(sLanguage);
+ end;
+ sFolder: begin
+ Songs.Sort(sArtist);
+ Songs.Sort(sFolder);
+ end;
+ sTitle: Songs.Sort(sTitle);
+ sArtist: Songs.Sort(sArtist);
+ sTitle2: Songs.Sort(sTitle2); // by title2
+ sArtist2: Songs.Sort(sArtist2); // by artist2
+
+ end; // case
+
+
+ Letter := ' ';
+ SS := '';
+ Order := 0;
+ CatNumber := 0;
+
+ //Songs leeren
+ SetLength (Song, 0);
+
+ for S := Low(Songs.Song) to High(Songs.Song) do begin
+ if (Ini.Tabs = 1) then
+ if (Ini.Sorting = sEdition) and (SS <> Songs.Song[S].Edition) then begin
+ // add Category Button
+ Inc(Order);
+ SS := Songs.Song[S].Edition;
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := '[' + SS + ']';
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+
+
+ // 0.4.3
+ // if SS = 'Singstar' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
+ // if SS = 'Singstar Part 2' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
+ // if SS = 'Singstar German' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
+ // if SS = 'Singstar Spanish' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
+ // if SS = 'Singstar Italian' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
+ // if SS = 'Singstar French' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar.jpg';
+ // if SS = 'Singstar Party' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar Party.jpg';
+ // if SS = 'Singstar Popworld' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar Popworld.jpg';
+ // if SS = 'Singstar 80s' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar 80s.jpg';
+ // if SS = 'Singstar 80s Polish' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar 80s.jpg';
+ // if SS = 'Singstar Rocks' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar Rocks.jpg';
+ // if SS = 'Singstar Anthems' then CatSongs.Song[CatLen].Cover := CoversPath + 'Singstar Anthems.jpg';
+
+ {// cover-patch
+ if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';//}
+
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS);
+
+ //CatNumber Patch
+ if (SS <> '') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end
+
+ else if (Ini.Sorting = sGenre) and (SS <> Songs.Song[S].Genre) then begin
+ // add Genre Button
+ Inc(Order);
+ SS := Songs.Song[S].Genre;
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := SS;
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+ {// cover-patch
+ if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS);
+
+ //CatNumber Patch
+ if (SS <> '') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end
+
+ else if (Ini.Sorting = sLanguage) and (SS <> Songs.Song[S].Language) then begin
+ // add Language Button
+ Inc(Order);
+ SS := Songs.Song[S].Language;
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := SS;
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+ {// cover-patch
+ if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS);
+
+ //CatNumber Patch
+ if (SS <> '') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end
+
+ else if (Ini.Sorting = sTitle) and (Length(Songs.Song[S].Title)>=1) and (Letter <> Songs.Song[S].Title[1]) then begin
+ // add a letter Category Button
+ Inc(Order);
+ Letter := Songs.Song[S].Title[1];
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := '[' + Letter + ']';
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+// Order := ord(Letter);
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+
+ {// cover-patch
+ if FileExists(CoversPath + 'Title' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Title' + Letter + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter);
+
+ //CatNumber Patch
+ if (Letter <> ' ') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end
+
+ else if (Ini.Sorting = sArtist) and (Length(Songs.Song[S].Artist)>=1) and (Letter <> Songs.Song[S].Artist[1]) then begin
+ // add a letter Category Button
+ Inc(Order);
+ Letter := Songs.Song[S].Artist[1];
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := '[' + Letter + ']';
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+// Order := ord(Letter);
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+ {// cover-patch
+ if FileExists(CoversPath + 'Artist' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Artist' + Letter + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter);
+
+ //CatNumber Patch
+ if (Letter <> ' ') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end
+
+ else if (Ini.Sorting = sFolder) and (SS <> Songs.Song[S].Folder) then begin
+ // 0.5.0: add folder tab
+ Inc(Order);
+ SS := Songs.Song[S].Folder;
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := SS;
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+ {// cover-patch
+ if FileExists(CoversPath + SS + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + SS + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, SS);
+
+ //CatNumber Patch
+ if (SS <> '') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end
+
+ else if (Ini.Sorting = sTitle2) AND (Length(Songs.Song[S].Title)>=1) then begin
+ if (ord(Songs.Song[S].Title[1]) > 47) and (ord(Songs.Song[S].Title[1]) < 58) then Letter2 := '#' else Letter2 := Songs.Song[S].Title[1];
+ if (Letter <> Letter2) then begin
+ // add a letter Category Button
+ Inc(Order);
+ Letter := Letter2;
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := '[' + Letter + ']';
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+// Order := ord(Letter);
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+ {// cover-patch
+ if FileExists(CoversPath + 'Title' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Title' + Letter + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter);
+
+ //CatNumber Patch
+ if (Letter <> ' ') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end;
+ end
+
+ else if (Ini.Sorting = sArtist2) AND (Length(Songs.Song[S].Artist)>=1) then begin
+ if (ord(Songs.Song[S].Artist[1]) > 47) and (ord(Songs.Song[S].Artist[1]) < 58) then Letter2 := '#' else Letter2 := Songs.Song[S].Artist[1];
+ if (Letter <> Letter2) then begin
+ // add a letter Category Button
+ Inc(Order);
+ Letter := Letter2;
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+ CatSongs.Song[CatLen].Artist := '[' + Letter + ']';
+ CatSongs.Song[CatLen].Main := true;
+ CatSongs.Song[CatLen].OrderTyp := 0;
+// Order := ord(Letter);
+ CatSongs.Song[CatLen].OrderNum := Order;
+
+ {// cover-patch
+ if FileExists(CoversPath + 'Artist' + Letter + '.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'Artist' + Letter + '.jpg'
+ else if FileExists(CoversPath + 'NoCover.jpg') then CatSongs.Song[CatLen].Cover := CoversPath + 'NoCover.jpg';}
+ CatSongs.Song[CatLen].Cover := CatCovers.GetCover(Ini.Sorting, Letter);
+
+ //CatNumber Patch
+ if (Letter <> ' ') then
+ begin
+ Song[CatLen - CatNumber - 1].CatNumber := CatNumber;//Set CatNumber of Categroy
+ CatNumber := 0;
+ end;
+
+ CatSongs.Song[CatLen].Visible := true;
+ end;
+ end;
+
+
+ CatLen := Length(CatSongs.Song);
+ SetLength(CatSongs.Song, CatLen+1);
+
+ Inc (CatNumber); //Increase Number in Cat
+
+ CatSongs.Song[CatLen] := Songs.Song[S];
+ CatSongs.Song[CatLen].OrderNum := Order; // assigns category
+ CatSongs.Song[CatLen].CatNumber := CatNumber;
+
+ if (Ini.Tabs = 0) then CatSongs.Song[CatLen].Visible := true
+ else if (Ini.Tabs = 1) then CatSongs.Song[CatLen].Visible := false;
+// if (Ini.Tabs = 1) and (Order = 1) then CatSongs.Song[CatLen].Visible := true; // open first tab
+//CatSongs.Song[CatLen].Visible := true;
+
+ end;
+//CatNumber Patch - Set CatNumber of Last Category
+if (ini.Tabs_at_startup = 1) And (high(Song) >=1) then
+ Song[CatLen - CatNumber].CatNumber := CatNumber;//Set CatNumber of Categroy
+//CatCount Patch
+CatCount := Order;
+end;
+
+procedure TCatSongs.ShowCategory(Index: integer);
+var
+ S: integer; // song
+begin
+ CatNumShow := Index;
+ for S := 0 to high(CatSongs.Song) do begin
+ if CatSongs.Song[S].OrderNum = Index then
+ CatSongs.Song[S].Visible := true
+ else
+ if not CatSongs.Song[S].Main then
+ CatSongs.Song[S].Visible := false;
+ end;
+end;
+
+procedure TCatSongs.HideCategory(Index: integer); // hides all songs in category
+var
+ S: integer; // song
+begin
+ for S := 0 to high(CatSongs.Song) do begin
+ if not CatSongs.Song[S].Main then
+ CatSongs.Song[S].Visible := false // hides all at now
+ end;
+end;
+
+procedure TCatSongs.ClickCategoryButton(Index: integer);
+var
+ Num, S: integer;
+begin
+ Num := CatSongs.Song[Index].OrderNum;
+ if Num <> CatNumShow then
+ begin
+ ShowCategory(Num);
+ //Hide Categorys when in Category Hack
+ for S := low(CatSongs.Song) to high(CatSongs.Song) do begin
+ if CatSongs.Song[S].Main then //Hide all Cats
+ CatSongs.Song[S].Visible := false
+ end;
+ //Hide Categorys when in Category Hack End
+ end
+ else begin
+ ShowCategoryList;
+ end;
+end;
+
+//Hide Categorys when in Category Hack
+procedure TCatSongs.ShowCategoryList;
+var
+ Num, S: integer;
+begin
+ //Hide All Songs Show All Cats
+ for S := 0 to high(CatSongs.Song) do begin
+ if CatSongs.Song[S].Main then
+ CatSongs.Song[S].Visible := true
+ else
+ CatSongs.Song[S].Visible := false
+ end;
+ CatSongs.Selected := CatNumShow; //Show last shown Category
+ CatNumShow := -1;
+end;
+//Hide Categorys when in Category Hack End
+
+//Wrong song selected when tabs on bug
+function TCatSongs.FindNextVisible(SearchFrom:integer): integer;//Find next Visible Song
+var
+ I: Integer;
+ begin
+ Result := -1;
+ I := SearchFrom + 1;
+ while not CatSongs.Song[I].Visible do
+ begin
+ Inc (I);
+ if (I>high(CatSongs.Song)) then
+ I := low(CatSongs.Song);
+ if (I = SearchFrom) then //Make One Round and no song found->quit
+ break;
+ end;
+ end;
+//Wrong song selected when tabs on bug End
+
+function TCatSongs.VisibleSongs: integer;
+var
+ S: integer; // song
+begin
+ Result := 0;
+ for S := 0 to high(CatSongs.Song) do
+ if CatSongs.Song[S].Visible = true then Inc(Result);
+end;
+
+function TCatSongs.VisibleIndex(Index: integer): integer;
+var
+ S: integer; // song
+begin
+ Result := 0;
+ for S := 0 to Index-1 do
+ if CatSongs.Song[S].Visible = true then Inc(Result);
+end;
+
+end.
diff --git a/Game/Code/Classes/UTexture.dcu b/Game/Code/Classes/UTexture.dcu
new file mode 100644
index 00000000..ec06b7e4
--- /dev/null
+++ b/Game/Code/Classes/UTexture.dcu
Binary files differ
diff --git a/Game/Code/Classes/UTexture.pas b/Game/Code/Classes/UTexture.pas
new file mode 100644
index 00000000..767d53ec
--- /dev/null
+++ b/Game/Code/Classes/UTexture.pas
@@ -0,0 +1,811 @@
+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
+uses OpenGL12, Windows, Math, Classes, SysUtils, Graphics, JPEG, UThemes;
+
+procedure glGenTextures(n: GLsizei; var textures: GLuint); stdcall; external opengl32;
+//procedure glBindTexture(target: GLenum; texture: GLuint); stdcall; external opengl32;
+//function gluBuild2DMipmaps (target: GLenum; components, width, height: GLint;
+// format, atype: GLenum; data: Pointer): Integer; stdcall; external glu32;
+//procedure glCopyTexImage2D(target: GLenum; level: GLint; internalFormat: GLenum; x, y: GLint; width, height: GLsizei; border: GLint); 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; Nazwa, Format, Typ: PChar; Col: LongWord): TTexture; overload;
+ function LoadTexture(Nazwa, Format, Typ: PChar; Col: LongWord): TTexture; overload;
+ function LoadTexture(Nazwa: 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
+ Texture: TTextureUnit;
+ TextureDatabase: TTextureDatabase;
+
+
+ // for print screens
+// PrintScreenTex: GLuint;
+// PrintScreenData: array[0..480-1, 0..640-1] of longword;
+ PrintScreenData: array[0..1024*768-1] of longword;
+
+// Tekstur: Gluint;
+ ActTex: GLuint;//integer;
+
+{ Tekstura: array[1..32] of TTekstura;
+ Mipmapping: boolean = true;}
+
+ TexOrygW: integer;
+ TexOrygH: integer;
+ TexNewW: integer;
+ TexNewH: integer;
+{ RLE: array[1..128*128] of byte;
+ RLE2: array[1..128*128] of byte;}
+
+ 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
+
+{ Paleta: array[0..255, 1..4] of byte;
+ Len: integer;}
+ Mipmapping: Boolean;
+
+ CacheMipmap: array[0..256*256*3-1] of byte; // 3KB
+
+
+implementation
+uses ULog, DateUtils, UCovers;
+
+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 not textures has 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);
+{ Covers.Data[0] := 0;
+ Covers.Data[1] := 0;
+ Covers.Data[2] := 0;
+ Covers.Data[3] := 255;
+ Covers.Data[4] := 255;
+ Covers.Data[5] := 255;}
+ 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;
+
+function TTextureUnit.LoadTexture(FromRegistry: boolean; Nazwa, Format, Typ: PChar; Col: LongWord): TTexture;
+var
+ Res: TResourceStream;
+ TextureB: TBitmap;
+ TextureJ: TJPEGImage;
+
+ Pet: integer;
+ Pet2: integer;
+ Pix: integer;
+ ColInt: real;
+ PPix: PByteArray;
+ TempA: integer;
+ Error: integer;
+ SkipX: integer;
+begin
+ Log.BenchmarkStart(4);
+ Mipmapping := true;
+
+ if FromRegistry then begin
+ try
+ Res := TResourceStream.Create(HInstance, Nazwa, Format);
+ except
+ beep;
+ Exit;
+ end;
+ end;
+
+ if FromRegistry or ((not FromRegistry) and FileExists(Nazwa)) then begin
+
+ TextureB := TBitmap.Create;
+
+ if Format = 'JPG' then begin
+ TextureJ := TJPEGImage.Create;
+ if FromRegistry then TextureJ.LoadFromStream(Res)
+ else begin
+ if FileExists(Nazwa) then
+ TextureJ.LoadFromFile(Nazwa)
+ else
+ Exit;
+ end;
+ TextureB.Assign(TextureJ);
+ TextureJ.Free;
+ end;
+ if Format = 'BMP' then begin
+ if FromRegistry then TextureB.LoadFromStream(Res)
+ else TextureB.LoadFromFile(Nazwa);
+ 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 ' + Nazwa + ' 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);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+ if Typ = 'Plain' then begin
+ // wymiary
+ TexOrygW := TextureB.Width;
+ TexOrygH := TextureB.Height;
+ TexNewW := Round(Power(2, Ceil(Log2(TexOrygW))));
+ TexNewH := Round(Power(2, Ceil(Log2(TexOrygH))));
+
+ // kopiowanie
+ TextureB.PixelFormat := pf24bit;
+{ if (TextureB.PixelFormat = pf8bit) then begin
+ for Pet := 0 to TexOrygH-1 do begin
+ for Pet2 := 0 to TexOrygW-1 do begin
+ Pix := TextureB.Canvas.Pixels[Pet2, Pet];
+ TextureD24[Pet*TexNewW + Pet2+1, 1] := Pix;
+ TextureD24[Pet*TexNewW + Pet2+1, 2] := Pix div 256;
+ TextureD24[Pet*TexNewW + Pet2+1, 3] := Pix div (256*256);
+ end;
+ end;
+ end;}
+ if (TexOrygW <= Limit) and (TexOrygW <= Limit) then begin
+ if (TextureB.PixelFormat = pf24bit) then begin
+ for Pet := 0 to TexOrygH-1 do begin
+ PPix := TextureB.ScanLine[Pet];
+ for Pet2 := 0 to TexOrygW-1 do begin
+ TextureD24[Pet*TexNewW + Pet2+1, 1] := PPix[Pet2*3+2];
+ TextureD24[Pet*TexNewW + Pet2+1, 2] := PPix[Pet2*3+1];
+ TextureD24[Pet*TexNewW + Pet2+1, 3] := PPix[Pet2*3];
+ end;
+ end;
+ end;
+ end else begin
+ // limit
+ TexFitW := 4 * (TexOrygW div 4); // fix for bug in gluScaleImage
+ TexFitH := TexOrygH;
+ if (TextureB.PixelFormat = pf24bit) then begin
+ for Pet := 0 to TexOrygH-1 do begin
+ PPix := TextureB.ScanLine[Pet];
+ for Pet2 := 0 to TexOrygW-1 do begin
+ TextureD24[Pet*TexFitW + Pet2+1, 1] := PPix[Pet2*3+2];
+ TextureD24[Pet*TexFitW + Pet2+1, 2] := PPix[Pet2*3+1];
+ TextureD24[Pet*TexFitW + Pet2+1, 3] := PPix[Pet2*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;
+ TexOrygW := Limit;
+ TexOrygH := Limit;
+ end;
+
+ // creating cache mipmap
+ if CreateCacheMipmap then begin
+ if (TexOrygW <> TexNewW) or (TexOrygH <> 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 * (TexOrygW div 4); // 0.5.0: fix for bug in gluScaleImage
+ SkipX := (TexOrygW div 2) mod 2; // 0.5.0: try to center image
+
+ TexFitH := TexOrygH;
+ for Pet := 0 to TexOrygH-1 do begin
+ PPix := TextureB.ScanLine[Pet];
+ for Pet2 := 0 to TexOrygW-1 do begin
+ TextureD242[Pet*TexFitW + Pet2+1, 1] := PPix[(Pet2+SkipX)*3+2];
+ TextureD242[Pet*TexFitW + Pet2+1, 2] := PPix[(Pet2+SkipX)*3+1];
+ TextureD242[Pet*TexFitW + Pet2+1, 3] := PPix[(Pet2+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, TexOrygW, TexOrygH, 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
+ // wymiary
+ TexOrygW := TextureB.Width;
+ TexOrygH := TextureB.Height;
+ TexNewW := Round(Power(2, Ceil(Log2(TexOrygW))));
+ TexNewH := Round(Power(2, Ceil(Log2(TexOrygH))));
+ TextureB.Width := TexNewW;
+ TextureB.Height := TexNewH;
+ // kopiowanie
+ for Pet := 0 to TexOrygH-1 do begin
+ for Pet2 := 0 to TexOrygW-1 do begin
+ Pix := TextureB.Canvas.Pixels[Pet2, Pet];
+ if Pix = Col then begin
+ TextureD32[Pet*TexNewW + Pet2 + 1, 1] := 0;
+ TextureD32[Pet*TexNewW + Pet2 + 1, 2] := 0;
+ TextureD32[Pet*TexNewW + Pet2 + 1, 3] := 0;
+ TextureD32[Pet*TexNewW + Pet2 + 1, 4] := 0;
+ end else begin
+ TextureD32[Pet*TexNewW + Pet2+1, 1] := Pix;
+ TextureD32[Pet*TexNewW + Pet2+1, 2] := Pix div 256;
+ TextureD32[Pet*TexNewW + Pet2+1, 3] := Pix div (256*256);
+ TextureD32[Pet*TexNewW + Pet2+1, 4] := 255;
+ end;
+ 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 = 'Transparent Range' then begin
+ // wymiary
+ TexOrygW := TextureB.Width;
+ TexOrygH := TextureB.Height;
+ TexNewW := Round(Power(2, Ceil(Log2(TexOrygW))));
+ TexNewH := Round(Power(2, Ceil(Log2(TexOrygH))));
+ TextureB.Width := TexNewW;
+ TextureB.Height := TexNewH;
+ // kopiowanie
+ for Pet := 0 to TexOrygH-1 do begin
+ for Pet2 := 0 to TexOrygW-1 do begin
+ Pix := TextureB.Canvas.Pixels[Pet2, Pet];
+ TextureD32[Pet*TexNewW + Pet2+1, 1] := Pix;
+ TextureD32[Pet*TexNewW + Pet2+1, 2] := Pix div 256;
+ TextureD32[Pet*TexNewW + Pet2+1, 3] := Pix div (256*256);
+ TextureD32[Pet*TexNewW + Pet2+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 Pet := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Pet];
+ for Pet2 := 0 to TextureB.Width-1 do begin
+ Pix := PPix[Pet2 * 3];
+ TextureD16[Pet*TextureB.Width + Pet2 + 1, 1] := 255;
+ TextureD16[Pet*TextureB.Width + Pet2 + 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 Pet := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Pet];
+ for Pet2 := 0 to TextureB.Width-1 do begin
+ Pix := PPix[Pet2 * 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[Pet*TextureB.Width + Pet2 + 1, 1] := Col;
+ TextureD16[Pet*TextureB.Width + Pet2 + 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 Pet := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Pet];
+ for Pet2 := 0 to TextureB.Width-1 do begin
+ Pix := PPix[Pet2 * 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[Pet*TextureB.Width + Pet2 + 1, 1] := Col;
+ TextureD16[Pet*TextureB.Width + Pet2 + 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
+ // wymiary
+ TextureB.PixelFormat := pf24bit;
+ TexOrygW := TextureB.Width;
+ TexOrygH := TextureB.Height;
+ TexNewW := Round(Power(2, Ceil(Log2(TexOrygW))));
+ TexNewH := Round(Power(2, Ceil(Log2(TexOrygH))));
+ TextureB.Width := TexNewW;
+ TextureB.Height := TexNewH;
+ // kopiowanie
+ for Pet := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Pet];
+ for Pet2 := 0 to TextureB.Width-1 do begin
+ Pix := PPix[Pet2*3];
+ TextureD32[Pet*TextureB.Width + Pet2 + 1, 1] := 255;
+ TextureD32[Pet*TextureB.Width + Pet2 + 1, 2] := 255;
+ TextureD32[Pet*TextureB.Width + Pet2 + 1, 3] := 255;
+ TextureD32[Pet*TextureB.Width + Pet2 + 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;
+ TexOrygW := TextureB.Width;
+ TexOrygH := TextureB.Height;
+ TexNewW := Round(Power(2, Ceil(Log2(TexOrygW))));
+ TexNewH := Round(Power(2, Ceil(Log2(TexOrygH))));
+ TextureB.Width := TexNewW;
+ TextureB.Height := TexNewH;
+ // kopiowanie
+ for Pet := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Pet];
+ for Pet2 := 0 to TextureB.Width-1 do begin
+ Pix := PPix[Pet2*3];
+ TextureD32[Pet*TextureB.Width + Pet2 + 1, 1] := (Col div $10000) and $FF;
+ TextureD32[Pet*TextureB.Width + Pet2 + 1, 2] := (Col div $100) and $FF;
+ TextureD32[Pet*TextureB.Width + Pet2 + 1, 3] := Col and $FF;
+ TextureD32[Pet*TextureB.Width + Pet2 + 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
+ // wymiary
+ TexOrygW := TextureB.Width;
+ TexOrygH := TextureB.Height;
+ TexNewW := Round(Power(2, Ceil(Log2(TexOrygW))));
+ TexNewH := Round(Power(2, Ceil(Log2(TexOrygH))));
+ TextureB.Width := TexNewW;
+ TextureB.Height := TexNewH;
+ // kopiowanie
+ for Pet := 0 to TextureB.Height-1 do begin
+ for Pet2 := 0 to TextureB.Width-1 do begin
+ Pix := TextureB.Canvas.Pixels[Pet2, Pet];
+ TextureD32[Pet*TextureB.Width + Pet2 + 1, 1] := 127;
+ TextureD32[Pet*TextureB.Width + Pet2 + 1, 2] := 127;
+ TextureD32[Pet*TextureB.Width + Pet2 + 1, 3] := 127;
+ TextureD32[Pet*TextureB.Width + Pet2 + 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 Pet := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Pet];
+ for Pet2 := 0 to TextureB.Width-1 do begin
+ Pix := PPix[Pet2 * 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[Pet*TextureB.Width + Pet2 + 1, 1] := Round(ColInt * 0.75 * 255 + (1 - ColInt) * 255);
+ TextureD32[Pet*TextureB.Width + Pet2 + 1, 2] := Round(ColInt * 0.6 * 255 + (1 - ColInt) * 255);
+ TextureD32[Pet*TextureB.Width + Pet2 + 1, 3] := Round(ColInt * 0.25 * 255 + (1 - ColInt) * 255);
+ TextureD32[Pet*TextureB.Width + Pet2 + 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 Pet := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Pet];
+ for Pet2 := 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[Pet2*3] of
+ 0..191: Pix := $10000 * ((((Col div $10000) and $FF) * PPix[Pet2*3]) div $Bf) + $100 * ((((Col div $100) and $FF) * PPix[Pet2*3]) div $Bf) + (((Col and $FF) * PPix[Pet2*3]) div $Bf);
+ 192: Pix := Col;
+ 193..254: Pix := Col + ($10000 * ((($FF - ((Col div $10000) and $FF)) * ((PPix[Pet2*3] - $C0) * 4) ) div $FF) + $100 * ((($FF - ((Col div $100) and $FF)) * ((PPix[Pet2*3] - $C0) * 4)) div $FF) + ((($FF - (Col and $FF)) * ((PPix[Pet2*3] - $C0) * 4)) div $FF));
+ 255: Pix := $FFFFFF;
+ end;
+// 0.5.0. Original
+// case PPix[Pet2*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[Pet*TextureB.Width + Pet2 + 1, 1] := Pix div $10000;
+ TextureD24[Pet*TextureB.Width + Pet2 + 1, 2] := (Pix div $100) and $FF;
+ TextureD24[Pet*TextureB.Width + Pet2 + 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 Pet := 0 to TextureB.Height-1 do begin
+ PPix := TextureB.ScanLine[Pet];
+ for Pet2 := 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[Pet2*3] of
+ 0: TempA := 0;
+ 1..191: Pix := $10000 * ((((Col div $10000) and $FF) * PPix[Pet2*3]) div $Bf) + $100 * ((((Col div $100) and $FF) * PPix[Pet2*3]) div $Bf) + (((Col and $FF) * PPix[Pet2*3]) div $Bf);
+ 192: Pix := Col;
+ 193..254: Pix := Col + ($10000 * ((($FF - ((Col div $10000) and $FF)) * ((PPix[Pet2*3] - $C0) * 4) ) div $FF) + $100 * ((($FF - ((Col div $100) and $FF)) * ((PPix[Pet2*3] - $C0) * 4)) div $FF) + ((($FF - (Col and $FF)) * ((PPix[Pet2*3] - $C0) * 4)) div $FF));
+ 255: Pix := $FFFFFF;
+ end;
+// 0.5.0 Original
+// case PPix[Pet2*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[Pet*TextureB.Width + Pet2 + 1, 1] := Pix div $10000;
+ TextureD32[Pet*TextureB.Width + Pet2 + 1, 2] := (Pix div $100) and $FF;
+ TextureD32[Pet*TextureB.Width + Pet2 + 1, 3] := Pix and $FF;
+ TextureD32[Pet*TextureB.Width + Pet2 + 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;
+// Inc(ActTex);
+{ Tekst.Tekstura := ActTex;
+ Tekst.W := TexOrygW;
+ Tekst.H := TexOrygH;
+ Tekst.X2 := TexOrygW/TexNewW;
+ Tekst.Y2 := TexOrygH/TexNewH;}
+ 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 := TexOrygW / TexNewW;
+ Result.TexH := TexOrygH / 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 := Nazwa;
+
+ end;
+
+ Log.BenchmarkEnd(4);
+ if Log.BenchmarkTimeLength[4] >= 1 then
+ Log.LogBenchmark('**********> Texture Load Time Warning - ' + Format + '/' + Nazwa + '/' + Typ, 4);
+
+ end; // logerror
+end;
+
+{procedure ResizeTexture(s: pbytearray; d: pbytearray);
+var
+ Pet: integer;
+ Pet2: integer;
+begin
+ for Pet := 0 to TexNewH*4-1 do
+ for Pet2 := 0 to TexNewW-1 do
+ d[Pet*TexNewW + Pet2] := 0;
+
+ for Pet := 0 to TexOrygH-1 do begin
+ for Pet2 := 0 to TexOrygW-1 do begin
+ d[(Pet*TexNewW + Pet2)*4] := Paleta[s[Pet*TexOrygW + Pet2], 1];
+ d[(Pet*TexNewW + Pet2)*4+1] := Paleta[s[Pet*TexOrygW + Pet2], 2];
+ d[(Pet*TexNewW + Pet2)*4+2] := Paleta[s[Pet*TexOrygW + Pet2], 3];
+ d[(Pet*TexNewW + Pet2)*4+3] := Paleta[s[Pet*TexOrygW + Pet2], 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(Nazwa, Format, Typ: PChar; Col: LongWord): TTexture;
+begin
+ Result := LoadTexture(false, Nazwa, Format, Typ, Col);
+// Result := LoadTexture(SkinReg, Nazwa, Format, Typ, Col); // default to SkinReg
+
+end;
+
+function TTextureUnit.LoadTexture(Nazwa: string): TTexture;
+begin
+ Result := LoadTexture(false, pchar(Nazwa), 'JPG', 'Plain', 0);
+end;
+
+function TTextureUnit.CreateTexture(var Data: array of byte; Name: string; W, H: word; Bits: byte): TTexture;
+var
+ Pet: integer;
+ Pet2: 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);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+ 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;
+
+
+// Inc(ActTex);
+{ Tekst.Tekstura := ActTex;
+ Tekst.W := TexOrygW;
+ Tekst.H := TexOrygH;
+ Tekst.X2 := TexOrygW/TexNewW;
+ Tekst.Y2 := TexOrygH/TexNewH;}
+ 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. \ No newline at end of file
diff --git a/Game/Code/Classes/UThemes.dcu b/Game/Code/Classes/UThemes.dcu
new file mode 100644
index 00000000..eb5ec8d4
--- /dev/null
+++ b/Game/Code/Classes/UThemes.dcu
Binary files differ
diff --git a/Game/Code/Classes/UThemes.pas b/Game/Code/Classes/UThemes.pas
new file mode 100644
index 00000000..29647db6
--- /dev/null
+++ b/Game/Code/Classes/UThemes.pas
@@ -0,0 +1,1837 @@
+unit UThemes;
+
+interface
+
+uses IniFiles, SysUtils, Classes;
+
+type
+ TRGB = record
+ R: single;
+ G: single;
+ B: single;
+ end;
+
+ {TSkin = record
+ GrayLeft: string;
+ GrayMid: string;
+ GrayRight: string;
+
+ NoteBGLeft: string;
+ NoteBGMid: string;
+ NoteBGRight: string;
+
+ NoteStar: string;
+
+ Ball: string;
+
+
+
+ //SingBar Mod
+ SingBarBack: string;
+ SingBarBar: string;
+ SingBarFront: string;
+ //end Singbar Mod
+
+ //PhrasenBonus - Line Bonus Mod
+ SingLineBonusBack: string;
+ //PhrasenBonus - Line Bonus Mod
+
+
+
+ WelcomeBG: string;
+
+ Background: string;
+ ScoreBG: string;
+ MainStart: string;
+ MainEditor: string;
+ MainOptions: string;
+ MainExit: string;
+ MainBar: string;
+ Cursor: string;
+
+ SongFade: string;
+ SongCover: string;
+ SongSelection: string;
+
+ SelectSong: string;
+ Button: string;
+ Bar: string;
+ P: string;
+ Arrow: string;
+ Arrow2: string;
+ ButtonF: string;
+ Star: string;
+ Line: string;
+
+// ThemePath: string;
+ SkinReg: boolean;
+ SkinName: string;
+ SkinPath: string;
+ SkinColor: integer;
+ end;}
+
+ TThemeBackground = record
+ Tex: string;
+ end;
+
+ TThemeStatic = record
+ X: integer;
+ Y: integer;
+ Z: real;
+ W: integer;
+ H: integer;
+ Color: string;
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ Tex: string;
+ Typ: string;
+ TexX1: real;
+ TexY1: real;
+ TexX2: real;
+ TexY2: real;
+ end;
+ AThemeStatic = array of TThemeStatic;
+
+ TThemeText = record
+ X: integer;
+ Y: integer;
+ Color: string;
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ Font: integer;
+ Size: integer;
+ Align: integer;
+ Text: string;
+ end;
+ AThemeText = array of TThemeText;
+
+ TThemeButton = record
+ Text: AThemeText;
+ X: integer;
+ Y: integer;
+ W: integer;
+ H: integer;
+ Color: string;
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ Int: real;
+ DColor: string;
+ DColR: real;
+ DColG: real;
+ DColB: real;
+ DInt: real;
+ Tex: string;
+ Typ: string;
+ //Reflection Mod
+ Reflection: Boolean;
+ end;
+
+ TThemeSelect = record
+ Tex: string;
+ TexSBG: string;
+ X: integer;
+ Y: integer;
+ W: integer;
+ H: integer;
+ Text: string;
+ ColR, ColG, ColB, Int: real;
+ DColR, DColG, DColB, DInt: real;
+ TColR, TColG, TColB, TInt: real;
+ TDColR, TDColG, TDColB, TDInt: real;
+ SBGColR, SBGColG, SBGColB, SBGInt: real;
+ SBGDColR, SBGDColG, SBGDColB, SBGDInt: real;
+ STColR, STColG, STColB, STInt: real;
+ STDColR, STDColG, STDColB, STDInt: real;
+ SkipX: integer;
+ end;
+
+ TThemeSelectSlide = record
+ Tex: string;
+ TexSBG: string;
+ X: integer;
+ Y: integer;
+ W: integer;
+ H: integer;
+ Text: string;
+ ColR, ColG, ColB, Int: real;
+ DColR, DColG, DColB, DInt: real;
+ TColR, TColG, TColB, TInt: real;
+ TDColR, TDColG, TDColB, TDInt: real;
+ SBGColR, SBGColG, SBGColB, SBGInt: real;
+ SBGDColR, SBGDColG, SBGDColB, SBGDInt: real;
+ STColR, STColG, STColB, STInt: real;
+ STDColR, STDColG, STDColB, STDInt: real;
+ SkipX: integer;
+ end;
+
+ TThemeBasic = class
+ Background: TThemeBackground;
+ Text: AThemeText;
+ Static: AThemeStatic;
+ end;
+
+ TThemeLoading = class(TThemeBasic)
+ end;
+
+ TThemeMain = class(TThemeBasic)
+ ButtonSolo: TThemeButton;
+// ButtonMulti: TThemeButton;
+ ButtonEditor: TThemeButton;
+ ButtonOptions: TThemeButton;
+ ButtonExit: TThemeButton;
+
+ TextDescription: TThemeText;
+ TextDescriptionLong: TThemeText;
+ Description: array[0..4] of string;
+ DescriptionLong: array[0..4] of string;
+ end;
+
+ TThemeName = class(TThemeBasic)
+ ButtonPlayer: array[1..6] of TThemeButton;
+ end;
+
+ TThemeLevel = class(TThemeBasic)
+ ButtonEasy: TThemeButton;
+ ButtonMedium: TThemeButton;
+ ButtonHard: TThemeButton;
+ end;
+
+ TThemeSong = class(TThemeBasic)
+ TextArtist: TThemeText;
+ TextTitle: TThemeText;
+ TextNumber: TThemeText;
+
+ //Show Cat in TopLeft Mod
+ TextCat: TThemeText;
+ StaticCat: TThemeStatic;
+
+ //Cover Mod
+ Cover: record
+ Reflections: Boolean;
+ X: Integer;
+ Y: Integer;
+ Z: Integer;
+ W: Integer;
+ H: Integer;
+ Style: Integer;
+ end;
+
+ //Equalizer Mod
+ Equalizer: record
+ Visible: Boolean;
+ Direction: Boolean;
+ Alpha: real;
+ X: Integer;
+ Y: Integer;
+ Z: Real;
+ W: Integer;
+ H: Integer;
+ Space: Integer;
+ Bands: Integer;
+ Length: Integer;
+ ColR, ColG, ColB: Real;
+ end;
+
+ //Party Mode
+ StaticTeam1Joker1: TThemeStatic;
+ StaticTeam1Joker2: TThemeStatic;
+ StaticTeam1Joker3: TThemeStatic;
+ StaticTeam1Joker4: TThemeStatic;
+ StaticTeam1Joker5: TThemeStatic;
+ StaticTeam2Joker1: TThemeStatic;
+ StaticTeam2Joker2: TThemeStatic;
+ StaticTeam2Joker3: TThemeStatic;
+ StaticTeam2Joker4: TThemeStatic;
+ StaticTeam2Joker5: TThemeStatic;
+ StaticTeam3Joker1: TThemeStatic;
+ StaticTeam3Joker2: TThemeStatic;
+ StaticTeam3Joker3: TThemeStatic;
+ StaticTeam3Joker4: TThemeStatic;
+ StaticTeam3Joker5: TThemeStatic;
+ end;
+
+ TThemeSing = class(TThemeBasic)
+ StaticP1: TThemeStatic;
+ StaticP1ScoreBG: TThemeStatic; //Static for ScoreBG
+ TextP1: TThemeText;
+ TextP1Score: TThemeText;
+
+
+ StaticP2R: TThemeStatic;
+ StaticP2RScoreBG: TThemeStatic; //Static for ScoreBG
+ TextP2R: TThemeText;
+ TextP2RScore: TThemeText;
+
+ StaticP2M: TThemeStatic;
+ StaticP2MScoreBG: TThemeStatic; //Static for ScoreBG
+ TextP2M: TThemeText;
+ TextP2MScore: TThemeText;
+
+ StaticP3R: TThemeStatic;
+ StaticP3RScoreBG: TThemeStatic; //Static for ScoreBG
+ TextP3R: TThemeText;
+ TextP3RScore: TThemeText;
+ end;
+
+ TThemeScore = class(TThemeBasic)
+ TextArtist: TThemeText;
+ TextTitle: TThemeText;
+
+ PlayerStatic: array[1..6] of AThemeStatic;
+
+ TextName: array[1..6] of TThemeText;
+ TextScore: array[1..6] of TThemeText;
+
+ TextNotes: array[1..6] of TThemeText;
+ TextNotesScore: array[1..6] of TThemeText;
+ TextLineBonus: array[1..6] of TThemeText;
+ TextLineBonusScore: array[1..6] of TThemeText;
+ TextGoldenNotes: array[1..6] of TThemeText;
+ TextGoldenNotesScore: array[1..6] of TThemeText;
+ TextTotal: array[1..6] of TThemeText;
+ TextTotalScore: array[1..6] of TThemeText;
+
+ StaticBoxLightest: array[1..6] of TThemeStatic;
+ StaticBoxLight: array[1..6] of TThemeStatic;
+ StaticBoxDark: array[1..6] of TThemeStatic;
+
+ StaticBackLevel: array[1..6] of TThemeStatic;
+ StaticBackLevelRound: array[1..6] of TThemeStatic;
+ StaticLevel: array[1..6] of TThemeStatic;
+ StaticLevelRound: array[1..6] of TThemeStatic;
+
+// Description: array[0..5] of string;}
+ end;
+
+ TThemeTop5 = class(TThemeBasic)
+ TextLevel: TThemeText;
+ TextArtistTitle: TThemeText;
+
+ StaticNumber: AThemeStatic;
+ TextNumber: AThemeText;
+ TextName: AThemeText;
+ TextScore: AThemeText;
+ end;
+
+ TThemeOptions = class(TThemeBasic)
+ ButtonGame: TThemeButton;
+ ButtonGraphics: TThemeButton;
+ ButtonSound: TThemeButton;
+ ButtonLyrics: TThemeButton;
+ ButtonThemes: TThemeButton;
+ ButtonRecord: TThemeButton;
+ ButtonExit: TThemeButton;
+
+ TextDescription: TThemeText;
+ Description: array[0..6] of string;
+ end;
+
+ TThemeOptionsGame = class(TThemeBasic)
+ SelectPlayers: TThemeSelect;
+ SelectDifficulty: TThemeSelect;
+ SelectLanguage: TThemeSelectSlide;
+ SelectTabs: TThemeSelect;
+ SelectSorting: TThemeSelectSlide;
+ SelectDebug: TThemeSelect;
+ ButtonExit: TThemeButton;
+ end;
+
+ TThemeOptionsGraphics = class(TThemeBasic)
+ SelectFullscreen: TThemeSelect;
+ SelectSlideResolution: TThemeSelectSlide;
+ SelectDepth: TThemeSelect;
+ SelectOscilloscope: TThemeSelect;
+ SelectLineBonus: TThemeSelect;
+ SelectMovieSize: TThemeSelect;
+ ButtonExit: TThemeButton;
+ end;
+
+ TThemeOptionsSound = class(TThemeBasic)
+ SelectMicBoost: TThemeSelect;
+ SelectClickAssist: TThemeSelect;
+ SelectBeatClick: TThemeSelect;
+ SelectThreshold: TThemeSelect;
+ //SelectTwoPlayerMode: TThemeSelect;
+ ButtonExit: TThemeButton;
+ end;
+
+ TThemeOptionsLyrics = class(TThemeBasic)
+ SelectLyricsFont: TThemeSelect;
+ SelectLyricsEffect: TThemeSelect;
+ SelectSolmization: TThemeSelect;
+ ButtonExit: TThemeButton;
+ end;
+
+ TThemeOptionsThemes = class(TThemeBasic)
+ SelectTheme: TThemeSelectSlide;
+ SelectSkin: TThemeSelectSlide;
+ SelectColor: TThemeSelectSlide;
+ ButtonExit: TThemeButton;
+ end;
+
+ TThemeOptionsRecord = class(TThemeBasic)
+ SelectSlideCard: TThemeSelectSlide;
+ SelectSlideInput: TThemeSelectSlide;
+ SelectSlideChannelL: TThemeSelectSlide;
+ SelectSlideChannelR: TThemeSelectSlide;
+ ButtonExit: TThemeButton;
+ end;
+
+ //ScreenSong Menue
+ TThemeSongMenu = class(TThemeBasic)
+ Button1: TThemeButton;
+ Button2: TThemeButton;
+ Button3: TThemeButton;
+ Button4: TThemeButton;
+
+ SelectSlide3: TThemeSelectSlide;
+
+ TextMenu: TThemeText;
+ end;
+
+ //Party Screens
+ TThemePartyNewRound = class(TThemeBasic)
+ TextRound1: TThemeText;
+ TextRound2: TThemeText;
+ TextRound3: TThemeText;
+ TextRound4: TThemeText;
+ TextRound5: TThemeText;
+ TextRound6: TThemeText;
+ TextRound7: TThemeText;
+ TextWinner1: TThemeText;
+ TextWinner2: TThemeText;
+ TextWinner3: TThemeText;
+ TextWinner4: TThemeText;
+ TextWinner5: TThemeText;
+ TextWinner6: TThemeText;
+ TextWinner7: TThemeText;
+ TextNextRound: TThemeText;
+ TextNextRoundNo: TThemeText;
+ TextNextPlayer1: TThemeText;
+ TextNextPlayer2: TThemeText;
+ TextNextPlayer3: TThemeText;
+
+ StaticRound1: TThemeStatic;
+ StaticRound2: TThemeStatic;
+ StaticRound3: TThemeStatic;
+ StaticRound4: TThemeStatic;
+ StaticRound5: TThemeStatic;
+ StaticRound6: TThemeStatic;
+ StaticRound7: TThemeStatic;
+
+ TextScoreTeam1: TThemeText;
+ TextScoreTeam2: TThemeText;
+ TextScoreTeam3: TThemeText;
+ TextNameTeam1: TThemeText;
+ TextNameTeam2: TThemeText;
+ TextNameTeam3: TThemeText;
+ StaticTeam1: TThemeStatic;
+ StaticTeam2: TThemeStatic;
+ StaticTeam3: TThemeStatic;
+
+ ButtonNext: TThemeButton;
+ end;
+
+ TThemePartyScore = class(TThemeBasic)
+ TextScoreTeam1: TThemeText;
+ TextScoreTeam2: TThemeText;
+ TextScoreTeam3: TThemeText;
+ TextNameTeam1: TThemeText;
+ TextNameTeam2: TThemeText;
+ TextNameTeam3: TThemeText;
+ StaticTeam1: TThemeStatic;
+ StaticTeam2: TThemeStatic;
+ StaticTeam3: TThemeStatic;
+
+ TextWinner: TThemeText;
+ end;
+
+ TThemePartyWin = class(TThemeBasic)
+ TextScoreTeam1: TThemeText;
+ TextScoreTeam2: TThemeText;
+ TextScoreTeam3: TThemeText;
+ TextNameTeam1: TThemeText;
+ TextNameTeam2: TThemeText;
+ TextNameTeam3: TThemeText;
+ StaticTeam1: TThemeStatic;
+ StaticTeam2: TThemeStatic;
+ StaticTeam3: TThemeStatic;
+
+ TextWinner: TThemeText;
+ end;
+
+ TThemePartyOptions = class(TThemeBasic)
+ SelectLevel: TThemeSelectSlide;
+ SelectPlayList: TThemeSelectSlide;
+ SelectPlayList2: TThemeSelectSlide;
+ SelectRounds: TThemeSelectSlide;
+ SelectTeams: TThemeSelectSlide;
+ SelectPlayers1: TThemeSelectSlide;
+ SelectPlayers2: TThemeSelectSlide;
+ SelectPlayers3: TThemeSelectSlide;
+
+ {ButtonNext: TThemeButton;
+ ButtonPrev: TThemeButton;}
+ end;
+
+ TThemePartyPlayer = class(TThemeBasic)
+ Team1Name: TThemeButton;
+ Player1Name: TThemeButton;
+ Player2Name: TThemeButton;
+ Player3Name: TThemeButton;
+ Player4Name: TThemeButton;
+
+ Team2Name: TThemeButton;
+ Player5Name: TThemeButton;
+ Player6Name: TThemeButton;
+ Player7Name: TThemeButton;
+ Player8Name: TThemeButton;
+
+ Team3Name: TThemeButton;
+ Player9Name: TThemeButton;
+ Player10Name: TThemeButton;
+ Player11Name: TThemeButton;
+ Player12Name: TThemeButton;
+
+ {ButtonNext: TThemeButton;
+ ButtonPrev: TThemeButton;}
+ end;
+
+ TTheme = class
+ {$IFDEF THEMESAVE}
+ ThemeIni: TIniFile;
+ {$ELSE}
+ ThemeIni: TMemIniFile;
+ {$ENDIF}
+
+ Loading: TThemeLoading;
+ Main: TThemeMain;
+ Name: TThemeName;
+ Level: TThemeLevel;
+ Song: TThemeSong;
+ Sing: TThemeSing;
+ Score: TThemeScore;
+ Top5: TThemeTop5;
+ Options: TThemeOptions;
+ OptionsGame: TThemeOptionsGame;
+ OptionsGraphics: TThemeOptionsGraphics;
+ OptionsSound: TThemeOptionsSound;
+ OptionsLyrics: TThemeOptionsLyrics;
+ OptionsThemes: TThemeOptionsThemes;
+ OptionsRecord: TThemeOptionsRecord;
+ //Menu
+ SongMenu: TThemeSongMenu;
+ //Party Screens:
+ PartyNewRound: TThemePartyNewRound;
+ PartyScore: TThemePartyScore;
+ PartyWin: TThemePartyWin;
+ PartyOptions: TThemePartyOptions;
+ PartyPlayer: TThemePartyPlayer;
+
+ constructor Create(FileName: string); overload; // Initialize theme system
+ constructor Create(FileName: string; Color: integer); overload; // Initialize theme system with color
+ function LoadTheme(FileName: string; sColor: integer): boolean; // Load some theme settings from file
+
+ procedure LoadColors;
+
+ procedure ThemeLoadBasic(Theme: TThemeBasic; Name: string);
+ procedure ThemeLoadBackground(var ThemeBackground: TThemeBackground; Name: string);
+ procedure ThemeLoadText(var ThemeText: TThemeText; Name: string);
+ procedure ThemeLoadTexts(var ThemeText: AThemeText; Name: string);
+ procedure ThemeLoadStatic(var ThemeStatic: TThemeStatic; Name: string);
+ procedure ThemeLoadStatics(var ThemeStatic: AThemeStatic; Name: string);
+ procedure ThemeLoadButton(var ThemeButton: TThemeButton; Name: string);
+ procedure ThemeLoadSelect(var ThemeSelect: TThemeSelect; Name: string);
+ procedure ThemeLoadSelectSlide(var ThemeSelectS: TThemeSelectSlide; Name: string);
+
+ procedure ThemeSave(FileName: string);
+ procedure ThemeSaveBasic(Theme: TThemeBasic; Name: string);
+ procedure ThemeSaveBackground(ThemeBackground: TThemeBackground; Name: string);
+ procedure ThemeSaveStatic(ThemeStatic: TThemeStatic; Name: string);
+ procedure ThemeSaveStatics(ThemeStatic: AThemeStatic; Name: string);
+ procedure ThemeSaveText(ThemeText: TThemeText; Name: string);
+ procedure ThemeSaveTexts(ThemeText: AThemeText; Name: string);
+ procedure ThemeSaveButton(ThemeButton: TThemeButton; Name: string);
+
+ end;
+
+ TColor = record
+ Name: string;
+ RGB: TRGB;
+ end;
+
+function ColorExists(Name: string): integer;
+procedure LoadColor(var R, G, B: real; ColorName: string);
+function GetSystemColor(Color: integer): TRGB;
+function ColorSqrt(RGB: TRGB): TRGB;
+
+var
+ //Skin: TSkin;
+ Theme: TTheme;
+ Color: array of TColor;
+
+implementation
+
+uses
+{$IFDEF TRANSLATE}
+ ULanguage,
+{$ENDIF}
+USkins, UIni;
+
+constructor TTheme.Create(FileName: string);
+begin
+ Create(FileName, 0);
+end;
+
+constructor TTheme.Create(FileName: string; Color: integer);
+begin
+ Loading := TThemeLoading.Create;
+ Main := TThemeMain.Create;
+ Name := TThemeName.Create;
+ Level := TThemeLevel.Create;
+ Song := TThemeSong.Create;
+ Sing := TThemeSing.Create;
+ Score := TThemeScore.Create;
+ Top5 := TThemeTop5.Create;
+ Options := TThemeOptions.Create;
+ OptionsGame := TThemeOptionsGame.Create;
+ OptionsGraphics := TThemeOptionsGraphics.Create;
+ OptionsSound := TThemeOptionsSound.Create;
+ OptionsLyrics := TThemeOptionsLyrics.Create;
+ OptionsThemes := TThemeOptionsThemes.Create;
+ OptionsRecord := TThemeOptionsRecord.Create;
+
+ SongMenu := TThemeSongMenu.Create;
+ //Party Screens
+ PartyNewRound := TThemePartyNewRound.Create;
+ PartyWin := TThemePartyWin.Create;
+ PartyScore := TThemePartyScore.Create;
+ PartyOptions := TThemePartyOptions.Create;
+ PartyPlayer := TThemePartyPlayer.Create;
+
+ LoadTheme(FileName, Color);
+
+
+ {Skin.GrayLeft := 'Left Gray.bmp';
+ Skin.GrayMid := 'Mid Gray.bmp';
+ Skin.GrayRight := 'Right Gray.bmp';
+
+ Skin.NoteBGLeft := 'Note BG Left.bmp';
+ Skin.NoteBGMid := 'Note BG Mid.bmp';
+ Skin.NoteBGRight := 'Note BG Right.bmp';
+
+ Skin.NoteStar := 'Note Star.jpg';
+
+
+
+ //SingBar Mod
+ Skin.SingBarBack := 'Sing Bar Back.jpg';
+ Skin.SingBarBar := 'Sing Bar Bar.jpg';
+ Skin.SingBarFront := 'Sing Bar Front.jpg';
+ //end Singbar Mod
+
+ //PhrasenBonus - Line Bonus Mod
+ Skin.SingLineBonusBack := 'Line Bonus PopUp.jpg';
+
+
+
+
+{ Skin.WelcomeBG := SkinPath + 'Welcome BG.jpg';
+// Skin.Background := SkinPath + 'Background.jpg';
+ Skin.ScoreBG := SkinPath + 'Score BG.jpg';
+// Skin.GameStart := SkinPath + 'Game Start.jpg';
+// Skin.Editor := SkinPath + 'Editor.jpg';
+// Skin.Options := SkinPath + 'Options.jpg';
+// Skin.Exit := SkinPath + 'Exit.jpg';
+
+ Skin.MainStart := SkinPath + 'Main Solo.jpg';
+ Skin.MainEditor := SkinPath + 'Main Multi.jpg';
+ Skin.MainOptions := SkinPath + 'Main Options.jpg';
+ Skin.MainExit := SkinPath + 'Main Exit.jpg';
+ Skin.MainBar := SkinPath + 'Main Bar.jpg';
+ Skin.Cursor := SkinPath + 'Main Cursor.jpg';
+
+ Skin.SongFade := SkinPath + 'Song Fade.jpg';}{
+ Skin.SongCover := 'Song Cover.jpg';
+ {Skin.SongSelection := SkinPath + 'Song Selection.jpg';
+
+ Skin.SelectSong := SkinPath + 'Select Song.jpg';}{
+// Skin.Button := SkinPath + 'MusicWheelItem song.jpg';
+ Skin.Bar := 'Bar.jpg';
+{ Skin.P := SkinPath + 'P.jpg';
+ Skin.Arrow := SkinPath + 'Arrow.jpg';
+ Skin.Arrow2 := SkinPath + 'Arrow 2.jpg';}{
+ Skin.ButtonF := 'Button.jpg';
+ Skin.Ball := 'Ball3.bmp';
+{ Skin.Star := SkinPath + 'Star.bmp';
+ Skin.Line := SkinPath + 'Line.jpg';}
+end;
+
+
+function TTheme.LoadTheme(FileName: string; sColor: integer): boolean;
+var
+ I: integer;
+ Path: string;
+begin
+ Result := false;
+ if FileExists(FileName) then begin
+ Result := true;
+
+ {$IFDEF THEMESAVE}
+ ThemeIni := TIniFile.Create(FileName);
+ {$ELSE}
+ ThemeIni := TMemIniFile.Create(FileName);
+ {$ENDIF}
+
+ if ThemeIni.ReadString('Theme', 'Name', '') <> '' then begin
+
+ {Skin.SkinName := ThemeIni.ReadString('Theme', 'Name', 'Singstar');
+ Skin.SkinPath := 'Skins\' + Skin.SkinName + '\';
+ Skin.SkinReg := false; }
+ Skin.Color := sColor;
+
+ Skin.LoadSkin(ISkin[Ini.SkinNo]);
+
+ LoadColors;
+
+// ThemeIni.Free;
+// ThemeIni := TIniFile.Create('Themes\Singstar\Main.ini');
+
+ // Loading
+ ThemeLoadBasic(Loading, 'Loading');
+
+ // Main
+ ThemeLoadBasic(Main, 'Main');
+
+ ThemeLoadText(Main.TextDescription, 'MainTextDescription');
+ ThemeLoadText(Main.TextDescriptionLong, 'MainTextDescriptionLong');
+ ThemeLoadButton(Main.ButtonSolo, 'MainButtonSolo');
+ ThemeLoadButton(Main.ButtonEditor, 'MainButtonEditor');
+ ThemeLoadButton(Main.ButtonOptions, 'MainButtonOptions');
+ ThemeLoadButton(Main.ButtonExit, 'MainButtonExit');
+
+ //Score Text Translation Start
+
+ {$IFDEF TRANSLATE}
+ Main.Description[0] := Language.Translate('SING_SING');
+ Main.DescriptionLong[0] := Language.Translate('SING_SING_DESC');
+ Main.Description[1] := Language.Translate('SING_EDITOR');
+ Main.DescriptionLong[1] := Language.Translate('SING_EDITOR_DESC');
+ Main.Description[2] := Language.Translate('SING_GAME_OPTIONS');
+ Main.DescriptionLong[2] := Language.Translate('SING_GAME_OPTIONS_DESC');
+ Main.Description[3] := Language.Translate('SING_EXIT');
+ Main.DescriptionLong[3] := Language.Translate('SING_EXIT_DESC');
+ {$ENDIF}
+
+ //Score Text Translation End
+
+ Main.TextDescription.Text := Main.Description[0];
+ Main.TextDescriptionLong.Text := Main.DescriptionLong[0];
+
+ // Name
+ ThemeLoadBasic(Name, 'Name');
+
+ for I := 1 to 6 do
+ ThemeLoadButton(Name.ButtonPlayer[I], 'NameButtonPlayer'+IntToStr(I));
+
+ // Level
+ ThemeLoadBasic(Level, 'Level');
+
+ ThemeLoadButton(Level.ButtonEasy, 'LevelButtonEasy');
+ ThemeLoadButton(Level.ButtonMedium, 'LevelButtonMedium');
+ ThemeLoadButton(Level.ButtonHard, 'LevelButtonHard');
+
+
+ // Song
+ ThemeLoadBasic(Song, 'Song');
+
+ ThemeLoadText(Song.TextArtist, 'SongTextArtist');
+ ThemeLoadText(Song.TextTitle, 'SongTextTitle');
+ ThemeLoadText(Song.TextNumber, 'SongTextNumber');
+
+ //Show Cat in TopLeft Mod
+ ThemeLoadStatic(Song.StaticCat, 'SongStaticCat');
+ ThemeLoadText(Song.TextCat, 'SongTextCat');
+
+ //Load Cover Pos and Size from Theme Mod
+ Song.Cover.X := ThemeIni.ReadInteger('SongCover', 'X', 400);
+ Song.Cover.Y := ThemeIni.ReadInteger('SongCover', 'Y', 100);
+ Song.Cover.Z := ThemeIni.ReadInteger('SongCover', 'Z', 250);
+ Song.Cover.W := ThemeIni.ReadInteger('SongCover', 'W', 200);
+ Song.Cover.H := ThemeIni.ReadInteger('SongCover', 'H', 200);
+ Song.Cover.Style := ThemeIni.ReadInteger('SongCover', 'Style', 5);
+ Song.Cover.Reflections := (ThemeIni.ReadInteger('SongCover', 'Reflections', 0) = 1);
+ //Load Cover Pos and Size from Theme Mod End
+
+ //Load Equalizer Pos and Size from Theme Mod
+ Song.Equalizer.Visible := (ThemeIni.ReadInteger('SongEqualizer', 'Visible', 0) = 1);
+ Song.Equalizer.Direction := (ThemeIni.ReadInteger('SongEqualizer', 'Direction', 0) = 1);
+ Song.Equalizer.Alpha := ThemeIni.ReadInteger('SongEqualizer', 'Alpha', 1);
+ Song.Equalizer.Space := ThemeIni.ReadInteger('SongEqualizer', 'Space', 1);
+ Song.Equalizer.X := ThemeIni.ReadInteger('SongEqualizer', 'X', 650);
+ Song.Equalizer.Y := ThemeIni.ReadInteger('SongEqualizer', 'Y', 430);
+ Song.Equalizer.Z := ThemeIni.ReadInteger('SongEqualizer', 'Z', 1);
+ Song.Equalizer.W := ThemeIni.ReadInteger('SongEqualizer', 'PieceW', 8);
+ Song.Equalizer.H := ThemeIni.ReadInteger('SongEqualizer', 'PieceH', 8);
+ Song.Equalizer.Bands := ThemeIni.ReadInteger('SongEqualizer', 'Bands', 5);
+ Song.Equalizer.Length := ThemeIni.ReadInteger('SongEqualizer', 'Length', 12);
+
+ //Party Mode
+ ThemeLoadStatic(Song.StaticTeam1Joker1, 'SongStaticTeam1Joker1');
+ ThemeLoadStatic(Song.StaticTeam1Joker2, 'SongStaticTeam1Joker2');
+ ThemeLoadStatic(Song.StaticTeam1Joker3, 'SongStaticTeam1Joker3');
+ ThemeLoadStatic(Song.StaticTeam1Joker4, 'SongStaticTeam1Joker4');
+ ThemeLoadStatic(Song.StaticTeam1Joker5, 'SongStaticTeam1Joker5');
+
+ ThemeLoadStatic(Song.StaticTeam2Joker1, 'SongStaticTeam2Joker1');
+ ThemeLoadStatic(Song.StaticTeam2Joker2, 'SongStaticTeam2Joker2');
+ ThemeLoadStatic(Song.StaticTeam2Joker3, 'SongStaticTeam2Joker3');
+ ThemeLoadStatic(Song.StaticTeam2Joker4, 'SongStaticTeam2Joker4');
+ ThemeLoadStatic(Song.StaticTeam2Joker5, 'SongStaticTeam2Joker5');
+
+ ThemeLoadStatic(Song.StaticTeam3Joker1, 'SongStaticTeam3Joker1');
+ ThemeLoadStatic(Song.StaticTeam3Joker2, 'SongStaticTeam3Joker2');
+ ThemeLoadStatic(Song.StaticTeam3Joker3, 'SongStaticTeam3Joker3');
+ ThemeLoadStatic(Song.StaticTeam3Joker4, 'SongStaticTeam3Joker4');
+ ThemeLoadStatic(Song.StaticTeam3Joker5, 'SongStaticTeam3Joker5');
+
+ //Color
+ I := ColorExists(ThemeIni.ReadString('SongEqualizer', 'Color', 'Black'));
+ if I >= 0 then begin
+ Song.Equalizer.ColR := Color[I].RGB.R;
+ Song.Equalizer.ColG := Color[I].RGB.G;
+ Song.Equalizer.ColB := Color[I].RGB.B;
+ end;
+ //Load Equalizer Pos and Size from Theme Mod End
+
+ // Sing
+ ThemeLoadBasic(Sing, 'Sing');
+
+ ThemeLoadStatic(Sing.StaticP1, 'SingP1Static');
+
+
+ //ScoreBG Mod
+ ThemeLoadStatic(Sing.StaticP1ScoreBG, 'SingP1Static2');//ScoreBG
+ //end ScoreBG Mod
+
+
+ ThemeLoadText(Sing.TextP1, 'SingP1Text');
+ ThemeLoadText(Sing.TextP1Score, 'SingP1TextScore');
+
+ ThemeLoadStatic(Sing.StaticP2R, 'SingP2RStatic');
+
+
+
+ //ScoreBG Mod
+ ThemeLoadStatic(Sing.StaticP2RScoreBG, 'SingP2RStatic2');
+ //end ScoreBG Mod
+
+
+
+ ThemeLoadText(Sing.TextP2R, 'SingP2RText');
+ ThemeLoadText(Sing.TextP2RScore, 'SingP2RTextScore');
+
+ ThemeLoadStatic(Sing.StaticP2M, 'SingP2MStatic');
+
+
+ //ScoreBG Mod
+ ThemeLoadStatic(Sing.StaticP2MScoreBG, 'SingP2MStatic2');
+ //end ScoreBG Mod
+
+
+
+ ThemeLoadText(Sing.TextP2M, 'SingP2MText');
+ ThemeLoadText(Sing.TextP2MScore, 'SingP2MTextScore');
+
+ ThemeLoadStatic(Sing.StaticP3R, 'SingP3RStatic');
+
+
+ //ScoreBG Mod
+ ThemeLoadStatic(Sing.StaticP3RScoreBG, 'SingP3RStatic2');
+ //end ScoreBG Mod
+
+
+
+ ThemeLoadText(Sing.TextP3R, 'SingP3RText');
+ ThemeLoadText(Sing.TextP3RScore, 'SingP3RTextScore');
+
+ // Score
+ ThemeLoadBasic(Score, 'Score');
+
+ ThemeLoadText(Score.TextArtist, 'ScoreTextArtist');
+ ThemeLoadText(Score.TextTitle, 'ScoreTextTitle');
+
+ for I := 1 to 6 do begin
+ ThemeLoadStatics(Score.PlayerStatic[I], 'ScorePlayer' + IntToStr(I) + 'Static');
+
+ ThemeLoadText(Score.TextName[I], 'ScoreTextName' + IntToStr(I));
+ ThemeLoadText(Score.TextScore[I], 'ScoreTextScore' + IntToStr(I));
+ ThemeLoadText(Score.TextNotes[I], 'ScoreTextNotes' + IntToStr(I));
+ ThemeLoadText(Score.TextNotesScore[I], 'ScoreTextNotesScore' + IntToStr(I));
+ ThemeLoadText(Score.TextLineBonus[I], 'ScoreTextLineBonus' + IntToStr(I));
+ ThemeLoadText(Score.TextLineBonusScore[I], 'ScoreTextLineBonusScore' + IntToStr(I));
+ ThemeLoadText(Score.TextGoldenNotes[I], 'ScoreTextGoldenNotes' + IntToStr(I));
+ ThemeLoadText(Score.TextGoldenNotesScore[I], 'ScoreTextGoldenNotesScore' + IntToStr(I));
+ ThemeLoadText(Score.TextTotal[I], 'ScoreTextTotal' + IntToStr(I));
+ ThemeLoadText(Score.TextTotalScore[I], 'ScoreTextTotalScore' + IntToStr(I));
+
+ ThemeLoadStatic(Score.StaticBoxLightest[I], 'ScoreStaticBoxLightest' + IntToStr(I));
+ ThemeLoadStatic(Score.StaticBoxLight[I], 'ScoreStaticBoxLight' + IntToStr(I));
+ ThemeLoadStatic(Score.StaticBoxDark[I], 'ScoreStaticBoxDark' + IntToStr(I));
+
+ ThemeLoadStatic(Score.StaticBackLevel[I], 'ScoreStaticBackLevel' + IntToStr(I));
+ ThemeLoadStatic(Score.StaticBackLevelRound[I], 'ScoreStaticBackLevelRound' + IntToStr(I));
+ ThemeLoadStatic(Score.StaticLevel[I], 'ScoreStaticLevel' + IntToStr(I));
+ ThemeLoadStatic(Score.StaticLevelRound[I], 'ScoreStaticLevelRound' + IntToStr(I));
+ end;
+
+ // Top5
+ ThemeLoadBasic(Top5, 'Top5');
+
+ ThemeLoadText(Top5.TextLevel, 'Top5TextLevel');
+ ThemeLoadText(Top5.TextArtistTitle, 'Top5TextArtistTitle');
+ ThemeLoadStatics(Top5.StaticNumber, 'Top5StaticNumber');
+ ThemeLoadTexts(Top5.TextNumber, 'Top5TextNumber');
+ ThemeLoadTexts(Top5.TextName, 'Top5TextName');
+ ThemeLoadTexts(Top5.TextScore, 'Top5TextScore');
+
+ // Options
+ ThemeLoadBasic(Options, 'Options');
+
+ ThemeLoadButton(Options.ButtonGame, 'OptionsButtonGame');
+ ThemeLoadButton(Options.ButtonGraphics, 'OptionsButtonGraphics');
+ ThemeLoadButton(Options.ButtonSound, 'OptionsButtonSound');
+ ThemeLoadButton(Options.ButtonLyrics, 'OptionsButtonLyrics');
+ ThemeLoadButton(Options.ButtonThemes, 'OptionsButtonThemes');
+ ThemeLoadButton(Options.ButtonRecord, 'OptionsButtonRecord');
+ ThemeLoadButton(Options.ButtonExit, 'OptionsButtonExit');
+
+ {$IFDEF TRANSLATE}
+ Options.Description[0] := Language.Translate('SING_OPTIONS_GAME');
+ Options.Description[1] := Language.Translate('SING_OPTIONS_GRAPHICS');
+ Options.Description[2] := Language.Translate('SING_OPTIONS_SOUND');
+ Options.Description[3] := Language.Translate('SING_OPTIONS_LYRICS');
+ Options.Description[4] := Language.Translate('SING_OPTIONS_THEMES');
+ Options.Description[5] := Language.Translate('SING_OPTIONS_RECORD');
+ Options.Description[6] := Language.Translate('SING_OPTIONS_EXIT');
+ {$ENDIF}
+
+ ThemeLoadText(Options.TextDescription, 'OptionsTextDescription');
+ Options.TextDescription.Text := Options.Description[0];
+
+ // Options Game
+ ThemeLoadBasic(OptionsGame, 'OptionsGame');
+
+ ThemeLoadSelect(OptionsGame.SelectPlayers, 'OptionsGameSelectPlayers');
+ ThemeLoadSelect(OptionsGame.SelectDifficulty, 'OptionsGameSelectDifficulty');
+ ThemeLoadSelectSlide(OptionsGame.SelectLanguage, 'OptionsGameSelectSlideLanguage');
+ ThemeLoadSelect(OptionsGame.SelectTabs, 'OptionsGameSelectTabs');
+ ThemeLoadSelectSlide(OptionsGame.SelectSorting, 'OptionsGameSelectSlideSorting');
+ ThemeLoadSelect(OptionsGame.SelectDebug, 'OptionsGameSelectDebug');
+ ThemeLoadButton(OptionsGame.ButtonExit, 'OptionsGameButtonExit');
+
+ // Options Graphics
+ ThemeLoadBasic(OptionsGraphics, 'OptionsGraphics');
+
+ ThemeLoadSelect(OptionsGraphics.SelectFullscreen, 'OptionsGraphicsSelectFullscreen');
+ ThemeLoadSelectSlide(OptionsGraphics.SelectSlideResolution, 'OptionsGraphicsSelectSlideResolution');
+ ThemeLoadSelect(OptionsGraphics.SelectDepth, 'OptionsGraphicsSelectDepth');
+ ThemeLoadSelect(OptionsGraphics.SelectOscilloscope, 'OptionsGraphicsSelectOscilloscope');
+ ThemeLoadSelect(OptionsGraphics.SelectLineBonus, 'OptionsGraphicsSelectLineBonus');
+ ThemeLoadSelect(OptionsGraphics.SelectMovieSize, 'OptionsGraphicsSelectMovieSize');
+ ThemeLoadButton(OptionsGraphics.ButtonExit, 'OptionsGraphicsButtonExit');
+
+ // Options Sound
+ ThemeLoadBasic(OptionsSound, 'OptionsSound');
+
+ ThemeLoadSelect(OptionsSound.SelectMicBoost, 'OptionsSoundSelectMicBoost');
+ ThemeLoadSelect(OptionsSound.SelectClickAssist, 'OptionsSoundSelectClickAssist');
+ ThemeLoadSelect(OptionsSound.SelectBeatClick, 'OptionsSoundSelectBeatClick');
+ ThemeLoadSelect(OptionsSound.SelectThreshold, 'OptionsSoundSelectThreshold');
+ //ThemeLoadSelect(OptionsSound.SelectTwoPlayerMode, 'OptionsSoundSelectTwoPlayerMode');
+ ThemeLoadButton(OptionsSound.ButtonExit, 'OptionsSoundButtonExit');
+
+ // Options Lyrics
+ ThemeLoadBasic(OptionsLyrics, 'OptionsLyrics');
+
+ ThemeLoadSelect(OptionsLyrics.SelectLyricsFont, 'OptionsLyricsSelectLyricsFont');
+ ThemeLoadSelect(OptionsLyrics.SelectLyricsEffect, 'OptionsLyricsSelectLyricsEffect');
+ ThemeLoadSelect(OptionsLyrics.SelectSolmization, 'OptionsLyricsSelectSolmization');
+ ThemeLoadButton(OptionsLyrics.ButtonExit, 'OptionsLyricsButtonExit');
+
+ // Options Themes
+ ThemeLoadBasic(OptionsThemes, 'OptionsThemes');
+
+ ThemeLoadSelectSlide(OptionsThemes.SelectTheme, 'OptionsThemesSelectTheme');
+ ThemeLoadSelectSlide(OptionsThemes.SelectSkin, 'OptionsThemesSelectSkin');
+ ThemeLoadSelectSlide(OptionsThemes.SelectColor, 'OptionsThemesSelectColor');
+ ThemeLoadButton(OptionsThemes.ButtonExit, 'OptionsThemesButtonExit');
+
+ // Options Record
+ ThemeLoadBasic(OptionsRecord, 'OptionsRecord');
+
+ ThemeLoadSelectSlide(OptionsRecord.SelectSlideCard, 'OptionsRecordSelectSlideCard');
+ ThemeLoadSelectSlide(OptionsRecord.SelectSlideInput, 'OptionsRecordSelectSlideInput');
+ ThemeLoadSelectSlide(OptionsRecord.SelectSlideChannelL, 'OptionsRecordSelectSlideChannelL');
+ ThemeLoadSelectSlide(OptionsRecord.SelectSlideChannelR, 'OptionsRecordSelectSlideChannelR');
+ ThemeLoadButton(OptionsRecord.ButtonExit, 'OptionsRecordButtonExit');
+
+ //Song Menu
+ ThemeLoadBasic (SongMenu, 'SongMenu');
+ ThemeLoadButton(SongMenu.Button1, 'SongMenuButton1');
+ ThemeLoadButton(SongMenu.Button2, 'SongMenuButton2');
+ ThemeLoadButton(SongMenu.Button3, 'SongMenuButton3');
+ ThemeLoadButton(SongMenu.Button4, 'SongMenuButton4');
+ ThemeLoadSelectSlide(SongMenu.SelectSlide3, 'SongMenuSelectSlide3');
+
+ ThemeLoadText(SongMenu.TextMenu, 'SongMenuTextMenu');
+
+ //Party Screens:
+ //Party NewRound
+ ThemeLoadBasic(PartyNewRound, 'PartyNewRound');
+
+ ThemeLoadText (PartyNewRound.TextRound1, 'PartyNewRoundTextRound1');
+ ThemeLoadText (PartyNewRound.TextRound2, 'PartyNewRoundTextRound2');
+ ThemeLoadText (PartyNewRound.TextRound3, 'PartyNewRoundTextRound3');
+ ThemeLoadText (PartyNewRound.TextRound4, 'PartyNewRoundTextRound4');
+ ThemeLoadText (PartyNewRound.TextRound5, 'PartyNewRoundTextRound5');
+ ThemeLoadText (PartyNewRound.TextRound6, 'PartyNewRoundTextRound6');
+ ThemeLoadText (PartyNewRound.TextRound7, 'PartyNewRoundTextRound7');
+ ThemeLoadText (PartyNewRound.TextWinner1, 'PartyNewRoundTextWinner1');
+ ThemeLoadText (PartyNewRound.TextWinner2, 'PartyNewRoundTextWinner2');
+ ThemeLoadText (PartyNewRound.TextWinner3, 'PartyNewRoundTextWinner3');
+ ThemeLoadText (PartyNewRound.TextWinner4, 'PartyNewRoundTextWinner4');
+ ThemeLoadText (PartyNewRound.TextWinner5, 'PartyNewRoundTextWinner5');
+ ThemeLoadText (PartyNewRound.TextWinner6, 'PartyNewRoundTextWinner6');
+ ThemeLoadText (PartyNewRound.TextWinner7, 'PartyNewRoundTextWinner7');
+ ThemeLoadText (PartyNewRound.TextNextRound, 'PartyNewRoundTextNextRound');
+ ThemeLoadText (PartyNewRound.TextNextRoundNo, 'PartyNewRoundTextNextRoundNo');
+ ThemeLoadText (PartyNewRound.TextNextPlayer1, 'PartyNewRoundTextNextPlayer1');
+ ThemeLoadText (PartyNewRound.TextNextPlayer2, 'PartyNewRoundTextNextPlayer2');
+ ThemeLoadText (PartyNewRound.TextNextPlayer3, 'PartyNewRoundTextNextPlayer3');
+
+ ThemeLoadStatic (PartyNewRound.StaticRound1, 'PartyNewRoundStaticRound1');
+ ThemeLoadStatic (PartyNewRound.StaticRound2, 'PartyNewRoundStaticRound2');
+ ThemeLoadStatic (PartyNewRound.StaticRound3, 'PartyNewRoundStaticRound3');
+ ThemeLoadStatic (PartyNewRound.StaticRound4, 'PartyNewRoundStaticRound4');
+ ThemeLoadStatic (PartyNewRound.StaticRound5, 'PartyNewRoundStaticRound5');
+ ThemeLoadStatic (PartyNewRound.StaticRound6, 'PartyNewRoundStaticRound6');
+ ThemeLoadStatic (PartyNewRound.StaticRound7, 'PartyNewRoundStaticRound7');
+
+ ThemeLoadText (PartyNewRound.TextScoreTeam1, 'PartyNewRoundTextScoreTeam1');
+ ThemeLoadText (PartyNewRound.TextScoreTeam2, 'PartyNewRoundTextScoreTeam2');
+ ThemeLoadText (PartyNewRound.TextScoreTeam3, 'PartyNewRoundTextScoreTeam3');
+ ThemeLoadText (PartyNewRound.TextNameTeam1, 'PartyNewRoundTextNameTeam1');
+ ThemeLoadText (PartyNewRound.TextNameTeam2, 'PartyNewRoundTextNameTeam2');
+ ThemeLoadText (PartyNewRound.TextNameTeam3, 'PartyNewRoundTextNameTeam3');
+
+ ThemeLoadStatic (PartyNewRound.StaticTeam1, 'PartyNewRoundStaticTeam1');
+ ThemeLoadStatic (PartyNewRound.StaticTeam2, 'PartyNewRoundStaticTeam2');
+ ThemeLoadStatic (PartyNewRound.StaticTeam3, 'PartyNewRoundStaticTeam3');
+
+ ThemeLoadButton (PartyNewRound.ButtonNext, 'PartyNewRoundButtonNext');
+
+ //Party Score
+ ThemeLoadBasic(PartyScore, 'PartyScore');
+
+ ThemeLoadText (PartyScore.TextScoreTeam1, 'PartyScoreTextScoreTeam1');
+ ThemeLoadText (PartyScore.TextScoreTeam2, 'PartyScoreTextScoreTeam2');
+ ThemeLoadText (PartyScore.TextScoreTeam3, 'PartyScoreTextScoreTeam3');
+ ThemeLoadText (PartyScore.TextNameTeam1, 'PartyScoreTextNameTeam1');
+ ThemeLoadText (PartyScore.TextNameTeam2, 'PartyScoreTextNameTeam2');
+ ThemeLoadText (PartyScore.TextNameTeam3, 'PartyScoreTextNameTeam3');
+
+ ThemeLoadStatic (PartyScore.StaticTeam1, 'PartyScoreStaticTeam1');
+ ThemeLoadStatic (PartyScore.StaticTeam2, 'PartyScoreStaticTeam2');
+ ThemeLoadStatic (PartyScore.StaticTeam3, 'PartyScoreStaticTeam3');
+
+ ThemeLoadText (PartyScore.TextWinner, 'PartyScoreTextWinner');
+
+ //Party Win
+ ThemeLoadBasic(PartyWin, 'PartyWin');
+
+ ThemeLoadText (PartyWin.TextScoreTeam1, 'PartyWinTextScoreTeam1');
+ ThemeLoadText (PartyWin.TextScoreTeam2, 'PartyWinTextScoreTeam2');
+ ThemeLoadText (PartyWin.TextScoreTeam3, 'PartyWinTextScoreTeam3');
+ ThemeLoadText (PartyWin.TextNameTeam1, 'PartyWinTextNameTeam1');
+ ThemeLoadText (PartyWin.TextNameTeam2, 'PartyWinTextNameTeam2');
+ ThemeLoadText (PartyWin.TextNameTeam3, 'PartyWinTextNameTeam3');
+
+ ThemeLoadStatic (PartyWin.StaticTeam1, 'PartyWinStaticTeam1');
+ ThemeLoadStatic (PartyWin.StaticTeam2, 'PartyWinStaticTeam2');
+ ThemeLoadStatic (PartyWin.StaticTeam3, 'PartyWinStaticTeam3');
+
+ ThemeLoadText (PartyWin.TextWinner, 'PartyWinTextWinner');
+
+ //Party Options
+ ThemeLoadBasic(PartyOptions, 'PartyOptions');
+ ThemeLoadSelectSlide(PartyOptions.SelectLevel, 'PartyOptionsSelectLevel');
+ ThemeLoadSelectSlide(PartyOptions.SelectPlayList, 'PartyOptionsSelectPlayList');
+ ThemeLoadSelectSlide(PartyOptions.SelectPlayList2, 'PartyOptionsSelectPlayList2');
+ ThemeLoadSelectSlide(PartyOptions.SelectRounds, 'PartyOptionsSelectRounds');
+ ThemeLoadSelectSlide(PartyOptions.SelectTeams, 'PartyOptionsSelectTeams');
+ ThemeLoadSelectSlide(PartyOptions.SelectPlayers1, 'PartyOptionsSelectPlayers1');
+ ThemeLoadSelectSlide(PartyOptions.SelectPlayers2, 'PartyOptionsSelectPlayers2');
+ ThemeLoadSelectSlide(PartyOptions.SelectPlayers3, 'PartyOptionsSelectPlayers3');
+
+ {ThemeLoadButton (ButtonNext, 'ButtonNext');
+ ThemeLoadButton (ButtonPrev, 'ButtonPrev');}
+
+ //Party Player
+ ThemeLoadBasic(PartyPlayer, 'PartyPlayer');
+ ThemeLoadButton(PartyPlayer.Team1Name, 'PartyPlayerTeam1Name');
+ ThemeLoadButton(PartyPlayer.Player1Name, 'PartyPlayerPlayer1Name');
+ ThemeLoadButton(PartyPlayer.Player2Name, 'PartyPlayerPlayer2Name');
+ ThemeLoadButton(PartyPlayer.Player3Name, 'PartyPlayerPlayer3Name');
+ ThemeLoadButton(PartyPlayer.Player4Name, 'PartyPlayerPlayer4Name');
+
+ ThemeLoadButton(PartyPlayer.Team2Name, 'PartyPlayerTeam2Name');
+ ThemeLoadButton(PartyPlayer.Player5Name, 'PartyPlayerPlayer5Name');
+ ThemeLoadButton(PartyPlayer.Player6Name, 'PartyPlayerPlayer6Name');
+ ThemeLoadButton(PartyPlayer.Player7Name, 'PartyPlayerPlayer7Name');
+ ThemeLoadButton(PartyPlayer.Player8Name, 'PartyPlayerPlayer8Name');
+
+ ThemeLoadButton(PartyPlayer.Team3Name, 'PartyPlayerTeam3Name');
+ ThemeLoadButton(PartyPlayer.Player9Name, 'PartyPlayerPlayer9Name');
+ ThemeLoadButton(PartyPlayer.Player10Name, 'PartyPlayerPlayer10Name');
+ ThemeLoadButton(PartyPlayer.Player11Name, 'PartyPlayerPlayer11Name');
+ ThemeLoadButton(PartyPlayer.Player12Name, 'PartyPlayerPlayer12Name');
+
+ {ThemeLoadButton(ButtonNext, 'PartyPlayerButtonNext');
+ ThemeLoadButton(ButtonPrev, 'PartyPlayerButtonPrev');}
+ end;
+
+ ThemeIni.Free;
+ end;
+end;
+
+procedure TTheme.ThemeLoadBasic(Theme: TThemeBasic; Name: string);
+begin
+ ThemeLoadBackground(Theme.Background, Name);
+ ThemeLoadTexts(Theme.Text, Name + 'Text');
+ ThemeLoadStatics(Theme.Static, Name + 'Static');
+end;
+
+procedure TTheme.ThemeLoadBackground(var ThemeBackground: TThemeBackground; Name: string);
+begin
+ ThemeBackground.Tex := ThemeIni.ReadString(Name + 'Background', 'Tex', '');
+end;
+
+procedure TTheme.ThemeLoadText(var ThemeText: TThemeText; Name: string);
+var
+ C: integer;
+begin
+ DecimalSeparator := '.';
+ ThemeText.X := ThemeIni.ReadInteger(Name, 'X', 0);
+ ThemeText.Y := ThemeIni.ReadInteger(Name, 'Y', 0);
+
+ ThemeText.ColR := ThemeIni.ReadFloat(Name, 'ColR', 0);
+ ThemeText.ColG := ThemeIni.ReadFloat(Name, 'ColG', 0);
+ ThemeText.ColB := ThemeIni.ReadFloat(Name, 'ColB', 0);
+
+ ThemeText.Font := ThemeIni.ReadInteger(Name, 'Font', 0);
+ ThemeText.Size := ThemeIni.ReadInteger(Name, 'Size', 0);
+ ThemeText.Align := ThemeIni.ReadInteger(Name, 'Align', 0);
+
+ {$IFDEF TRANSLATE}
+ ThemeText.Text := Language.Translate(ThemeIni.ReadString(Name, 'Text', ''));
+ {$ELSE}
+ ThemeText.Text := ThemeIni.ReadString(Name, 'Text', '');
+ {$ENDIF}
+
+ ThemeText.Color := ThemeIni.ReadString(Name, 'Color', '');
+
+ C := ColorExists(ThemeText.Color);
+ if C >= 0 then begin
+ ThemeText.ColR := Color[C].RGB.R;
+ ThemeText.ColG := Color[C].RGB.G;
+ ThemeText.ColB := Color[C].RGB.B;
+ end;
+
+ DecimalSeparator := ',';
+end;
+
+procedure TTheme.ThemeLoadTexts(var ThemeText: AThemeText; Name: string);
+var
+ T: integer;
+begin
+ T := 1;
+ while ThemeIni.SectionExists(Name + IntToStr(T)) do begin
+ SetLength(ThemeText, T);
+ ThemeLoadText(ThemeText[T-1], Name + IntToStr(T));
+ Inc(T);
+ end;
+end;
+
+procedure TTheme.ThemeLoadStatic(var ThemeStatic: TThemeStatic; Name: string);
+var
+ C: integer;
+begin
+ DecimalSeparator := '.';
+
+ ThemeStatic.Tex := ThemeIni.ReadString(Name, 'Tex', '');
+
+ ThemeStatic.X := ThemeIni.ReadInteger(Name, 'X', 0);
+ ThemeStatic.Y := ThemeIni.ReadInteger(Name, 'Y', 0);
+ ThemeStatic.Z := ThemeIni.ReadFloat(Name, 'Z', 0);
+ ThemeStatic.W := ThemeIni.ReadInteger(Name, 'W', 0);
+ ThemeStatic.H := ThemeIni.ReadInteger(Name, 'H', 0);
+
+ ThemeStatic.Typ := ThemeIni.ReadString(Name, 'Type', '');
+ ThemeStatic.Color := ThemeIni.ReadString(Name, 'Color', '');
+
+ C := ColorExists(ThemeStatic.Color);
+ if C >= 0 then begin
+ ThemeStatic.ColR := Color[C].RGB.R;
+ ThemeStatic.ColG := Color[C].RGB.G;
+ ThemeStatic.ColB := Color[C].RGB.B;
+ end;
+
+ ThemeStatic.TexX1 := ThemeIni.ReadFloat(Name, 'TexX1', 0);
+ ThemeStatic.TexY1 := ThemeIni.ReadFloat(Name, 'TexY1', 0);
+ ThemeStatic.TexX2 := ThemeIni.ReadFloat(Name, 'TexX2', 1);
+ ThemeStatic.TexY2 := ThemeIni.ReadFloat(Name, 'TexY2', 1);
+
+ DecimalSeparator := ',';
+end;
+
+procedure TTheme.ThemeLoadStatics(var ThemeStatic: AThemeStatic; Name: string);
+var
+ S: integer;
+begin
+ S := 1;
+ while ThemeIni.SectionExists(Name + IntToStr(S)) do begin
+ SetLength(ThemeStatic, S);
+ ThemeLoadStatic(ThemeStatic[S-1], Name + IntToStr(S));
+ Inc(S);
+ end;
+end;
+
+procedure TTheme.ThemeLoadButton(var ThemeButton: TThemeButton; Name: string);
+var
+ C: integer;
+ TLen: integer;
+ T: integer;
+begin
+ DecimalSeparator := '.';
+ ThemeButton.Tex := ThemeIni.ReadString(Name, 'Tex', '');
+ ThemeButton.X := ThemeIni.ReadInteger(Name, 'X', 0);
+ ThemeButton.Y := ThemeIni.ReadInteger(Name, 'Y', 0);
+ ThemeButton.W := ThemeIni.ReadInteger(Name, 'W', 0);
+ ThemeButton.H := ThemeIni.ReadInteger(Name, 'H', 0);
+
+ ThemeButton.Typ := ThemeIni.ReadString(Name, 'Type', '');
+
+ //Reflection Mod
+ ThemeButton.Reflection := (ThemeIni.ReadInteger(Name, 'Reflection', 0) = 1);
+
+ ThemeButton.ColR := ThemeIni.ReadFloat(Name, 'ColR', 1);
+ ThemeButton.ColG := ThemeIni.ReadFloat(Name, 'ColG', 1);
+ ThemeButton.ColB := ThemeIni.ReadFloat(Name, 'ColB', 1);
+ ThemeButton.Int := ThemeIni.ReadFloat(Name, 'Int', 1);
+ ThemeButton.DColR := ThemeIni.ReadFloat(Name, 'DColR', 1);
+ ThemeButton.DColG := ThemeIni.ReadFloat(Name, 'DColG', 1);
+ ThemeButton.DColB := ThemeIni.ReadFloat(Name, 'DColB', 1);
+ ThemeButton.DInt := ThemeIni.ReadFloat(Name, 'DInt', 1);
+
+ ThemeButton.Color := ThemeIni.ReadString(Name, 'Color', '');
+ C := ColorExists(ThemeButton.Color);
+ if C >= 0 then begin
+ ThemeButton.ColR := Color[C].RGB.R;
+ ThemeButton.ColG := Color[C].RGB.G;
+ ThemeButton.ColB := Color[C].RGB.B;
+ end;
+
+ ThemeButton.DColor := ThemeIni.ReadString(Name, 'DColor', '');
+ C := ColorExists(ThemeButton.DColor);
+ if C >= 0 then begin
+ ThemeButton.DColR := Color[C].RGB.R;
+ ThemeButton.DColG := Color[C].RGB.G;
+ ThemeButton.DColB := Color[C].RGB.B;
+ end;
+
+ TLen := ThemeIni.ReadInteger(Name, 'Texts', 0);
+ SetLength(ThemeButton.Text, TLen);
+ for T := 1 to TLen do
+ ThemeLoadText(ThemeButton.Text[T-1], Name + 'Text' + IntToStr(T));
+
+ DecimalSeparator := ',';
+end;
+
+procedure TTheme.ThemeLoadSelect(var ThemeSelect: TThemeSelect; Name: string);
+var
+ C: integer;
+begin
+ DecimalSeparator := '.';
+
+ {$IFDEF TRANSLATE}
+ ThemeSelect.Text := Language.Translate(ThemeIni.ReadString(Name, 'Text', ''));
+ {$ELSE}
+ ThemeSelect.Text := ThemeIni.ReadString(Name, 'Text', '');
+ {$ENDIF}
+
+ ThemeSelect.Tex := {Skin.SkinPath + }ThemeIni.ReadString(Name, 'Tex', '');
+ ThemeSelect.TexSBG := {Skin.SkinPath + }ThemeIni.ReadString(Name, 'TexSBG', '');
+
+ ThemeSelect.X := ThemeIni.ReadInteger(Name, 'X', 0);
+ ThemeSelect.Y := ThemeIni.ReadInteger(Name, 'Y', 0);
+ ThemeSelect.W := ThemeIni.ReadInteger(Name, 'W', 0);
+ ThemeSelect.H := ThemeIni.ReadInteger(Name, 'H', 0);
+ ThemeSelect.SkipX := ThemeIni.ReadInteger(Name, 'SkipX', 0);
+
+
+ LoadColor(ThemeSelect.ColR, ThemeSelect.ColG, ThemeSelect.ColB, ThemeIni.ReadString(Name, 'Color', ''));
+ ThemeSelect.Int := ThemeIni.ReadFloat(Name, 'Int', 1);
+ LoadColor(ThemeSelect.DColR, ThemeSelect.DColG, ThemeSelect.DColB, ThemeIni.ReadString(Name, 'DColor', ''));
+ ThemeSelect.DInt := ThemeIni.ReadFloat(Name, 'DInt', 1);
+
+ LoadColor(ThemeSelect.TColR, ThemeSelect.TColG, ThemeSelect.TColB, ThemeIni.ReadString(Name, 'TColor', ''));
+ ThemeSelect.TInt := ThemeIni.ReadFloat(Name, 'TInt', 1);
+ LoadColor(ThemeSelect.TDColR, ThemeSelect.TDColG, ThemeSelect.TDColB, ThemeIni.ReadString(Name, 'TDColor', ''));
+ ThemeSelect.TDInt := ThemeIni.ReadFloat(Name, 'TDInt', 1);
+
+ LoadColor(ThemeSelect.SBGColR, ThemeSelect.SBGColG, ThemeSelect.SBGColB, ThemeIni.ReadString(Name, 'SBGColor', ''));
+ ThemeSelect.SBGInt := ThemeIni.ReadFloat(Name, 'SBGInt', 1);
+ LoadColor(ThemeSelect.SBGDColR, ThemeSelect.SBGDColG, ThemeSelect.SBGDColB, ThemeIni.ReadString(Name, 'SBGDColor', ''));
+ ThemeSelect.SBGDInt := ThemeIni.ReadFloat(Name, 'SBGDInt', 1);
+
+ LoadColor(ThemeSelect.STColR, ThemeSelect.STColG, ThemeSelect.STColB, ThemeIni.ReadString(Name, 'STColor', ''));
+ ThemeSelect.STInt := ThemeIni.ReadFloat(Name, 'STInt', 1);
+ LoadColor(ThemeSelect.STDColR, ThemeSelect.STDColG, ThemeSelect.STDColB, ThemeIni.ReadString(Name, 'STDColor', ''));
+ ThemeSelect.STDInt := ThemeIni.ReadFloat(Name, 'STDInt', 1);
+
+
+ DecimalSeparator := ',';
+end;
+
+procedure TTheme.ThemeLoadSelectSlide(var ThemeSelectS: TThemeSelectSlide; Name: string);
+var
+ C: integer;
+begin
+ DecimalSeparator := '.';
+
+ {$IFDEF TRANSLATE}
+ ThemeSelectS.Text := Language.Translate(ThemeIni.ReadString(Name, 'Text', ''));
+ {$ELSE}
+ ThemeSelectS.Text := ThemeIni.ReadString(Name, 'Text', '');
+ {$ENDIF}
+
+ ThemeSelectS.Tex := {Skin.SkinPath + }ThemeIni.ReadString(Name, 'Tex', '');
+ ThemeSelectS.TexSBG := {Skin.SkinPath + }ThemeIni.ReadString(Name, 'TexSBG', '');
+
+ ThemeSelectS.X := ThemeIni.ReadInteger(Name, 'X', 0);
+ ThemeSelectS.Y := ThemeIni.ReadInteger(Name, 'Y', 0);
+ ThemeSelectS.W := ThemeIni.ReadInteger(Name, 'W', 0);
+ ThemeSelectS.H := ThemeIni.ReadInteger(Name, 'H', 0);
+ ThemeSelectS.SkipX := ThemeIni.ReadInteger(Name, 'SkipX', 0);
+
+
+ LoadColor(ThemeSelectS.ColR, ThemeSelectS.ColG, ThemeSelectS.ColB, ThemeIni.ReadString(Name, 'Color', ''));
+ ThemeSelectS.Int := ThemeIni.ReadFloat(Name, 'Int', 1);
+ LoadColor(ThemeSelectS.DColR, ThemeSelectS.DColG, ThemeSelectS.DColB, ThemeIni.ReadString(Name, 'DColor', ''));
+ ThemeSelectS.DInt := ThemeIni.ReadFloat(Name, 'DInt', 1);
+
+ LoadColor(ThemeSelectS.TColR, ThemeSelectS.TColG, ThemeSelectS.TColB, ThemeIni.ReadString(Name, 'TColor', ''));
+ ThemeSelectS.TInt := ThemeIni.ReadFloat(Name, 'TInt', 1);
+ LoadColor(ThemeSelectS.TDColR, ThemeSelectS.TDColG, ThemeSelectS.TDColB, ThemeIni.ReadString(Name, 'TDColor', ''));
+ ThemeSelectS.TDInt := ThemeIni.ReadFloat(Name, 'TDInt', 1);
+
+ LoadColor(ThemeSelectS.SBGColR, ThemeSelectS.SBGColG, ThemeSelectS.SBGColB, ThemeIni.ReadString(Name, 'SBGColor', ''));
+ ThemeSelectS.SBGInt := ThemeIni.ReadFloat(Name, 'SBGInt', 1);
+ LoadColor(ThemeSelectS.SBGDColR, ThemeSelectS.SBGDColG, ThemeSelectS.SBGDColB, ThemeIni.ReadString(Name, 'SBGDColor', ''));
+ ThemeSelectS.SBGDInt := ThemeIni.ReadFloat(Name, 'SBGDInt', 1);
+
+ LoadColor(ThemeSelectS.STColR, ThemeSelectS.STColG, ThemeSelectS.STColB, ThemeIni.ReadString(Name, 'STColor', ''));
+ ThemeSelectS.STInt := ThemeIni.ReadFloat(Name, 'STInt', 1);
+ LoadColor(ThemeSelectS.STDColR, ThemeSelectS.STDColG, ThemeSelectS.STDColB, ThemeIni.ReadString(Name, 'STDColor', ''));
+ ThemeSelectS.STDInt := ThemeIni.ReadFloat(Name, 'STDInt', 1);
+
+
+ DecimalSeparator := ',';
+end;
+
+procedure TTheme.LoadColors;
+var
+ SL: TStringList;
+ C: integer;
+ S: string;
+ Col: integer;
+ RGB: TRGB;
+begin
+ SL := TStringList.Create;
+ ThemeIni.ReadSection('Colors', SL);
+
+ // normal colors
+ SetLength(Color, SL.Count);
+ for C := 0 to SL.Count-1 do begin
+ Color[C].Name := SL.Strings[C];
+
+ S := ThemeIni.ReadString('Colors', SL.Strings[C], '');
+
+ Color[C].RGB.R := StrToInt(Copy(S, 1, Pos(' ' , S)-1))/255;
+ Delete(S, 1, Pos(' ', S));
+
+ Color[C].RGB.G := StrToInt(Copy(S, 1, Pos(' ' , S)-1))/255;
+ Delete(S, 1, Pos(' ', S));
+
+ Color[C].RGB.B := StrToInt(S)/255;
+ end;
+
+ // skin color
+ SetLength(Color, SL.Count + 3);
+ C := SL.Count;
+ Color[C].Name := 'ColorDark';
+ Color[C].RGB := GetSystemColor(Skin.Color); //Ini.Color);
+
+ C := C+1;
+ Color[C].Name := 'ColorLight';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ C := C+1;
+ Color[C].Name := 'ColorLightest';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ // players colors
+ SetLength(Color, Length(Color)+18);
+
+ // P1
+ C := C+1;
+ Color[C].Name := 'P1Dark';
+ Color[C].RGB := GetSystemColor(0); // 0 - blue
+
+ C := C+1;
+ Color[C].Name := 'P1Light';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ C := C+1;
+ Color[C].Name := 'P1Lightest';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ // P2
+ C := C+1;
+ Color[C].Name := 'P2Dark';
+ Color[C].RGB := GetSystemColor(3); // 3 - red
+
+ C := C+1;
+ Color[C].Name := 'P2Light';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ C := C+1;
+ Color[C].Name := 'P2Lightest';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ // P3
+ C := C+1;
+ Color[C].Name := 'P3Dark';
+ Color[C].RGB := GetSystemColor(1); // 1 - green
+
+ C := C+1;
+ Color[C].Name := 'P3Light';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ C := C+1;
+ Color[C].Name := 'P3Lightest';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ // P4
+ C := C+1;
+ Color[C].Name := 'P4Dark';
+ Color[C].RGB := GetSystemColor(4); // 4 - brown
+
+ C := C+1;
+ Color[C].Name := 'P4Light';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ C := C+1;
+ Color[C].Name := 'P4Lightest';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ // P5
+ C := C+1;
+ Color[C].Name := 'P5Dark';
+ Color[C].RGB := GetSystemColor(5); // 5 - yellow
+
+ C := C+1;
+ Color[C].Name := 'P5Light';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ C := C+1;
+ Color[C].Name := 'P5Lightest';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ // P6
+ C := C+1;
+ Color[C].Name := 'P6Dark';
+ Color[C].RGB := GetSystemColor(6); // 6 - violet
+
+ C := C+1;
+ Color[C].Name := 'P6Light';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+ C := C+1;
+ Color[C].Name := 'P6Lightest';
+ Color[C].RGB := ColorSqrt(Color[C-1].RGB);
+
+
+ SL.Free;
+end;
+
+function ColorExists(Name: string): integer;
+var
+ C: integer;
+begin
+ Result := -1;
+ for C := 0 to High(Color) do
+ if Color[C].Name = Name then Result := C;
+end;
+
+procedure LoadColor(var R, G, B: real; ColorName: string);
+var
+ C: integer;
+begin
+ C := ColorExists(ColorName);
+ if C >= 0 then begin
+ R := Color[C].RGB.R;
+ G := Color[C].RGB.G;
+ B := Color[C].RGB.B;
+ end;
+end;
+
+function GetSystemColor(Color: integer): TRGB;
+begin
+ case Color of
+ 0: begin
+ // blue
+ Result.R := 71/255;
+ Result.G := 175/255;
+ Result.B := 247/255;
+ end;
+ 1: begin
+ // green
+ Result.R := 63/255;
+ Result.G := 191/255;
+ Result.B := 63/255;
+ end;
+ 2: begin
+ // pink
+ Result.R := 255/255;
+{ Result.G := 63/255;
+ Result.B := 192/255;}
+ Result.G := 175/255;
+ Result.B := 247/255;
+ end;
+ 3: begin
+ // red
+ Result.R := 247/255;
+ Result.G := 71/255;
+ Result.B := 71/255;
+ end;
+ //'Violet', 'Orange', 'Yellow', 'Brown', 'Black'
+ //New Theme-Color Patch
+ 4: begin
+ // violet
+ Result.R := 230/255;
+ Result.G := 63/255;
+ Result.B := 230/255;
+ end;
+ 5: begin
+ // orange
+ Result.R := 255/255;
+ Result.G := 144/255;
+ Result.B := 0;
+ end;
+ 6: begin
+ // yellow
+ Result.R := 230/255;
+ Result.G := 230/255;
+ Result.B := 95/255;
+ end;
+ 7: begin
+ // brown
+ Result.R := 192/255;
+ Result.G := 127/255;
+ Result.B := 31/255;
+ end;
+ 8: begin
+ // black
+ Result.R := 0;
+ Result.G := 0;
+ Result.B := 0;
+ end;
+ //New Theme-Color Patch End
+
+ end;
+
+ // pink
+// Col := clRed;
+// Color[C].ColR := (32 + Col and $FF) / (255 + 32);
+// Color[C].ColG := (32 + Col div 256 and $FF) / (255 + 32);
+// Color[C].ColB := (32 + Col div (256*256) and $FF) / (255 + 32);
+
+ // purple
+// Color[C].ColR := 220/255;
+// Color[C].ColG := 95/255;
+// Color[C].ColB := 220/255;}
+
+end;
+
+function ColorSqrt(RGB: TRGB): TRGB;
+begin
+ Result.R := sqrt(RGB.R);
+ Result.G := sqrt(RGB.G);
+ Result.B := sqrt(RGB.B);
+end;
+
+procedure TTheme.ThemeSave(FileName: string);
+var
+ I: integer;
+begin
+ {$IFDEF THEMESAVE}
+ ThemeIni := TIniFile.Create(FileName);
+ {$ELSE}
+ ThemeIni := TMemIniFile.Create(FileName);
+ {$ENDIF}
+
+ ThemeSaveBasic(Loading, 'Loading');
+
+ ThemeSaveBasic(Main, 'Main');
+ ThemeSaveText(Main.TextDescription, 'MainTextDescription');
+ ThemeSaveText(Main.TextDescriptionLong, 'MainTextDescriptionLong');
+ ThemeSaveButton(Main.ButtonSolo, 'MainButtonSolo');
+ ThemeSaveButton(Main.ButtonEditor, 'MainButtonEditor');
+ ThemeSaveButton(Main.ButtonOptions, 'MainButtonOptions');
+ ThemeSaveButton(Main.ButtonExit, 'MainButtonExit');
+
+ ThemeSaveBasic(Name, 'Name');
+ for I := 1 to 6 do
+ ThemeSaveButton(Name.ButtonPlayer[I], 'NameButtonPlayer' + IntToStr(I));
+
+ ThemeSaveBasic(Level, 'Level');
+ ThemeSaveButton(Level.ButtonEasy, 'LevelButtonEasy');
+ ThemeSaveButton(Level.ButtonMedium, 'LevelButtonMedium');
+ ThemeSaveButton(Level.ButtonHard, 'LevelButtonHard');
+
+ ThemeSaveBasic(Song, 'Song');
+ ThemeSaveText(Song.TextArtist, 'SongTextArtist');
+ ThemeSaveText(Song.TextTitle, 'SongTextTitle');
+ ThemeSaveText(Song.TextNumber, 'SongTextNumber');
+
+ //Show CAt in Top Left Mod
+ ThemeSaveText(Song.TextCat, 'SongTextCat');
+ ThemeSaveStatic(Song.StaticCat, 'SongStaticCat');
+
+ ThemeSaveBasic(Sing, 'Sing');
+ ThemeSaveStatic(Sing.StaticP1, 'SingP1Static');
+
+
+
+ //ScoreBG Mod
+ ThemeSaveStatic(Sing.StaticP1ScoreBG, 'SingP1Static2');
+ //end ScoreBG Mod
+
+
+
+ ThemeSaveText(Sing.TextP1, 'SingP1Text');
+ ThemeSaveText(Sing.TextP1Score, 'SingP1TextScore');
+
+ ThemeSaveStatic(Sing.StaticP2R, 'SingP2RStatic');
+
+
+
+ //ScoreBG Mod
+ ThemeSaveStatic(Sing.StaticP2RScoreBG, 'SingP2RStatic2');
+ //end ScoreBG Mod
+
+
+
+ ThemeSaveText(Sing.TextP2R, 'SingP2RText');
+ ThemeSaveText(Sing.TextP2RScore, 'SingP2RTextScore');
+
+ ThemeSaveStatic(Sing.StaticP2M, 'SingP2MStatic');
+
+
+
+ //ScoreBG Mod
+ ThemeSaveStatic(Sing.StaticP2MScoreBG, 'SingP2MStatic2');
+ //end ScoreBG Mod
+
+
+
+
+ ThemeSaveText(Sing.TextP2M, 'SingP2MText');
+ ThemeSaveText(Sing.TextP2MScore, 'SingP2MTextScore');
+
+ ThemeSaveStatic(Sing.StaticP3R, 'SingP3RStatic');
+
+
+
+ //ScoreBG Mod
+ ThemeSaveStatic(Sing.StaticP3RScoreBG, 'SingP3RStatic2');
+ //end ScoreBG Mod
+
+
+
+
+ ThemeSaveText(Sing.TextP3R, 'SingP3RText');
+ ThemeSaveText(Sing.TextP3RScore, 'SingP3RTextScore');
+
+ ThemeSaveBasic(Score, 'Score');
+ ThemeSaveText(Score.TextArtist, 'ScoreTextArtist');
+ ThemeSaveText(Score.TextTitle, 'ScoreTextTitle');
+
+ for I := 1 to 6 do begin
+ ThemeSaveStatics(Score.PlayerStatic[I], 'ScorePlayer' + IntToStr(I) + 'Static');
+
+ ThemeSaveText(Score.TextName[I], 'ScoreTextName' + IntToStr(I));
+ ThemeSaveText(Score.TextScore[I], 'ScoreTextScore' + IntToStr(I));
+ ThemeSaveText(Score.TextNotes[I], 'ScoreTextNotes' + IntToStr(I));
+ ThemeSaveText(Score.TextNotesScore[I], 'ScoreTextNotesScore' + IntToStr(I));
+ ThemeSaveText(Score.TextLineBonus[I], 'ScoreTextLineBonus' + IntToStr(I));
+ ThemeSaveText(Score.TextLineBonusScore[I], 'ScoreTextLineBonusScore' + IntToStr(I));
+ ThemeSaveText(Score.TextGoldenNotes[I], 'ScoreTextGoldenNotes' + IntToStr(I));
+ ThemeSaveText(Score.TextGoldenNotesScore[I], 'ScoreTextGoldenNotesScore' + IntToStr(I));
+ ThemeSaveText(Score.TextTotal[I], 'ScoreTextTotal' + IntToStr(I));
+ ThemeSaveText(Score.TextTotalScore[I], 'ScoreTextTotalScore' + IntToStr(I));
+
+ ThemeSaveStatic(Score.StaticBackLevel[I], 'ScoreStaticBackLevel' + IntToStr(I));
+ ThemeSaveStatic(Score.StaticBackLevelRound[I], 'ScoreStaticBackLevelRound' + IntToStr(I));
+ ThemeSaveStatic(Score.StaticLevel[I], 'ScoreStaticLevel' + IntToStr(I));
+ ThemeSaveStatic(Score.StaticLevelRound[I], 'ScoreStaticLevelRound' + IntToStr(I));
+ end;
+
+ ThemeSaveBasic(Top5, 'Top5');
+ ThemeSaveText(Top5.TextLevel, 'Top5TextLevel');
+ ThemeSaveText(Top5.TextArtistTitle, 'Top5TextArtistTitle');
+ ThemeSaveStatics(Top5.StaticNumber, 'Top5StaticNumber');
+ ThemeSaveTexts(Top5.TextNumber, 'Top5TextNumber');
+ ThemeSaveTexts(Top5.TextName, 'Top5TextName');
+ ThemeSaveTexts(Top5.TextScore, 'Top5TextScore');
+
+
+ ThemeIni.Free;
+end;
+
+procedure TTheme.ThemeSaveBasic(Theme: TThemeBasic; Name: string);
+begin
+ ThemeIni.WriteInteger(Name, 'Texts', Length(Theme.Text));
+
+ ThemeSaveBackground(Theme.Background, Name + 'Background');
+ ThemeSaveStatics(Theme.Static, Name + 'Static');
+ ThemeSaveTexts(Theme.Text, Name + 'Text');
+end;
+
+procedure TTheme.ThemeSaveBackground(ThemeBackground: TThemeBackground; Name: string);
+begin
+ if ThemeBackground.Tex <> '' then
+ ThemeIni.WriteString(Name, 'Tex', ThemeBackground.Tex)
+ else begin
+ ThemeIni.EraseSection(Name);
+ end;
+end;
+
+procedure TTheme.ThemeSaveStatic(ThemeStatic: TThemeStatic; Name: string);
+begin
+ DecimalSeparator := '.';
+ ThemeIni.WriteInteger(Name, 'X', ThemeStatic.X);
+ ThemeIni.WriteInteger(Name, 'Y', ThemeStatic.Y);
+ ThemeIni.WriteInteger(Name, 'W', ThemeStatic.W);
+ ThemeIni.WriteInteger(Name, 'H', ThemeStatic.H);
+
+ ThemeIni.WriteString(Name, 'Tex', ThemeStatic.Tex);
+ ThemeIni.WriteString(Name, 'Type', ThemeStatic.Typ);
+ ThemeIni.WriteString(Name, 'Color', ThemeStatic.Color);
+
+ ThemeIni.WriteFloat(Name, 'TexX1', ThemeStatic.TexX1);
+ ThemeIni.WriteFloat(Name, 'TexY1', ThemeStatic.TexY1);
+ ThemeIni.WriteFloat(Name, 'TexX2', ThemeStatic.TexX2);
+ ThemeIni.WriteFloat(Name, 'TexY2', ThemeStatic.TexY2);
+
+ DecimalSeparator := ',';
+end;
+
+procedure TTheme.ThemeSaveStatics(ThemeStatic: AThemeStatic; Name: string);
+var
+ S: integer;
+begin
+ for S := 0 to Length(ThemeStatic)-1 do
+ ThemeSaveStatic(ThemeStatic[S], Name + {'Static' +} IntToStr(S+1));
+
+ ThemeIni.EraseSection(Name + {'Static' + }IntToStr(S+1));
+end;
+
+procedure TTheme.ThemeSaveText(ThemeText: TThemeText; Name: string);
+begin
+ DecimalSeparator := '.';
+ ThemeIni.WriteInteger(Name, 'X', ThemeText.X);
+ ThemeIni.WriteInteger(Name, 'Y', ThemeText.Y);
+
+ ThemeIni.WriteInteger(Name, 'Font', ThemeText.Font);
+ ThemeIni.WriteInteger(Name, 'Size', ThemeText.Size);
+ ThemeIni.WriteInteger(Name, 'Align', ThemeText.Align);
+
+ ThemeIni.WriteString(Name, 'Text', ThemeText.Text);
+ ThemeIni.WriteString(Name, 'Color', ThemeText.Color);
+
+ DecimalSeparator := ',';
+end;
+
+procedure TTheme.ThemeSaveTexts(ThemeText: AThemeText; Name: string);
+var
+ T: integer;
+begin
+ for T := 0 to Length(ThemeText)-1 do
+ ThemeSaveText(ThemeText[T], Name + {'Text' + }IntToStr(T+1));
+
+ ThemeIni.EraseSection(Name + {'Text' + }IntToStr(T+1));
+end;
+
+procedure TTheme.ThemeSaveButton(ThemeButton: TThemeButton; Name: string);
+var
+ T: integer;
+begin
+ DecimalSeparator := '.';
+ ThemeIni.WriteString(Name, 'Tex', ThemeButton.Tex);
+ ThemeIni.WriteInteger(Name, 'X', ThemeButton.X);
+ ThemeIni.WriteInteger(Name, 'Y', ThemeButton.Y);
+ ThemeIni.WriteInteger(Name, 'W', ThemeButton.W);
+ ThemeIni.WriteInteger(Name, 'H', ThemeButton.H);
+
+ ThemeIni.WriteString(Name, 'Type', ThemeButton.Typ);
+ ThemeIni.WriteInteger(Name, 'Texts', Length(ThemeButton.Text));
+
+ ThemeIni.WriteString(Name, 'Color', ThemeButton.Color);
+
+{ ThemeButton.ColR := ThemeIni.ReadFloat(Name, 'ColR', 1);
+ ThemeButton.ColG := ThemeIni.ReadFloat(Name, 'ColG', 1);
+ ThemeButton.ColB := ThemeIni.ReadFloat(Name, 'ColB', 1);
+ ThemeButton.Int := ThemeIni.ReadFloat(Name, 'Int', 1);
+ ThemeButton.DColR := ThemeIni.ReadFloat(Name, 'DColR', 1);
+ ThemeButton.DColG := ThemeIni.ReadFloat(Name, 'DColG', 1);
+ ThemeButton.DColB := ThemeIni.ReadFloat(Name, 'DColB', 1);
+ ThemeButton.DInt := ThemeIni.ReadFloat(Name, 'DInt', 1);}
+
+{ C := ColorExists(ThemeIni.ReadString(Name, 'Color', ''));
+ if C >= 0 then begin
+ ThemeButton.ColR := Color[C].RGB.R;
+ ThemeButton.ColG := Color[C].RGB.G;
+ ThemeButton.ColB := Color[C].RGB.B;
+ end;
+
+ C := ColorExists(ThemeIni.ReadString(Name, 'DColor', ''));
+ if C >= 0 then begin
+ ThemeButton.DColR := Color[C].RGB.R;
+ ThemeButton.DColG := Color[C].RGB.G;
+ ThemeButton.DColB := Color[C].RGB.B;
+ end;}
+
+ for T := 0 to High(ThemeButton.Text) do
+ ThemeSaveText(ThemeButton.Text[T], Name + 'Text' + IntToStr(T+1));
+
+ DecimalSeparator := ',';
+end;
+
+
+end.
diff --git a/Game/Code/Classes/UTime.dcu b/Game/Code/Classes/UTime.dcu
new file mode 100644
index 00000000..f69b60f7
--- /dev/null
+++ b/Game/Code/Classes/UTime.dcu
Binary files differ
diff --git a/Game/Code/Classes/UTime.pas b/Game/Code/Classes/UTime.pas
new file mode 100644
index 00000000..29e972ae
--- /dev/null
+++ b/Game/Code/Classes/UTime.pas
@@ -0,0 +1,81 @@
+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.
diff --git a/Game/Code/Menu/UDisplay.dcu b/Game/Code/Menu/UDisplay.dcu
new file mode 100644
index 00000000..f4f89245
--- /dev/null
+++ b/Game/Code/Menu/UDisplay.dcu
Binary files differ
diff --git a/Game/Code/Menu/UDisplay.pas b/Game/Code/Menu/UDisplay.pas
new file mode 100644
index 00000000..6d0443cc
--- /dev/null
+++ b/Game/Code/Menu/UDisplay.pas
@@ -0,0 +1,289 @@
+unit UDisplay;
+
+interface
+
+uses Windows, SDL, UMenu, OpenGL12, SysUtils;
+
+type
+ TDisplay = class
+ ActualScreen: PMenu;
+ NextScreen: PMenu;
+
+ h_DC: HDC;
+ h_RC: HGLRC;
+
+// FadeType: integer;
+ FadeTex: glUInt;
+ LastFade: real;
+ Fade: real;
+ function Draw: Boolean;
+ procedure PrintScreen;
+ constructor Create;
+ procedure ScreenShot;
+ end;
+
+var
+ Display: TDisplay;
+// ActualScreen: PMenu;
+// NextScreen: PMenu;
+
+implementation
+
+uses UGraphic, UTime, Graphics, Jpeg, UPliki, UTexture;
+
+constructor TDisplay.Create;
+begin
+ inherited Create;
+// FadeType := 0;
+ Fade := 0;
+end;
+
+function TDisplay.Draw: Boolean;
+var
+ S: integer;
+ Col: real;
+ Surface: PSDL_Surface;
+begin
+ Result := True;
+
+ Col := 1;
+ if (ParamStr(1) = '-black') or (ParamStr(1) = '-fsblack') then
+ Col := 0;
+
+ glClearColor(Col, Col, Col , 1);
+ 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; // it's easier than rewriting code
+ glViewPort((S-1) * ScreenW div Screens, 0, ScreenW div Screens, ScreenH);
+
+ ActualScreen.SetAnimationProgress(1);
+ if not assigned (NextScreen) then Result := ActualScreen.Draw
+ else begin
+ LastFade := Fade;
+ Fade := Fade + TimeSkip * 6; // * 4
+
+ {//Create Fading texture
+ if Fade = 0 then
+ begin
+ Surface := SDL_GetVideoSurface;
+ glGenTextures(1, FadeTex);
+
+ glBindTexture(GL_TEXTURE_2D, FadeTex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, Surface.pitch div Surface.format.BytesPerPixel);
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, 800, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE, Surface.pixels);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ end;}
+
+ ActualScreen.ShowFinish := false;
+
+ //Fade = 2 (Belnding) Mod
+ if (FadeTex > 0) then
+ begin
+ ActualScreen.SetAnimationProgress(Fade-1);
+ ActualScreen.Draw;
+ glBindTexture(GL_TEXTURE_2D, FadeTex);
+ glColor4f(Col, Col, Col, 1-Fade); // 0
+ glEnable(GL_BLEND);
+ glBegin(GL_QUADS);
+ glVertex2f(0, 0);
+ glVertex2f(0, 600);
+ glVertex2f(800, 600);
+ glVertex2f(800, 0);
+ glEnd;
+ glDisable(GL_BLEND);
+ end
+ else
+ begin
+ case ActualScreen.Fade of
+ 0: begin
+ if Fade < 1 then begin
+ ActualScreen.SetAnimationProgress(1-Fade);
+ ActualScreen.Draw;
+ glColor4f(Col, Col, Col, Fade); // 0
+ end else begin
+ ActualScreen.SetAnimationProgress(Fade-1);
+ ActualScreen.Draw;
+ glColor4f(Col, Col, Col, 1-Fade); // 0
+ end;
+ glEnable(GL_BLEND);
+ glBegin(GL_QUADS);
+ glVertex2f(0, 0);
+ glVertex2f(0, 600);
+ glVertex2f(800, 600);
+ glVertex2f(800, 0);
+ glEnd;
+ glDisable(GL_BLEND);
+ end;
+ 2: begin
+ if Fade < 1 then begin
+ ActualScreen.SetAnimationProgress(1-Fade);
+ ActualScreen.Draw;
+ //glColor4f(Col, Col, Col, Fade); // 0
+ glColor4f(1, 1, 1, 1); // 0
+ //Fade := 1
+ end;
+ glEnable(GL_BLEND);
+ glBegin(GL_QUADS);
+ glVertex2f(0, 0);
+ glVertex2f(0, 600);
+ glVertex2f(800, 600);
+ glVertex2f(800, 0);
+ glEnd;
+ glDisable(GL_BLEND);
+ end;
+ end; // case
+ end;
+
+ if (LastFade < 1 ) and (Fade >= 1) then begin
+ if (ActualScreen.Fade = 2) then
+ begin
+ ScreenShot;
+ //Create Fading Texture
+ Surface := SDL_GetVideoSurface;
+ glGenTextures(1, FadeTex);
+
+ glBindTexture(GL_TEXTURE_2D, FadeTex);
+ 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);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, Surface.pitch div Surface.format.BytesPerPixel);
+ glTexImage2D(GL_TEXTURE_2D, 0, 3, 800, 600, 0, GL_RGBA, GL_UNSIGNED_BYTE, Surface.pixels);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ end;
+
+ // pokazuje 2 ekran, ale nie kasuje informacji o NextScreen
+ ActualScreen.onHide;
+ ActualScreen := NextScreen;
+ ActualScreen.onShow;
+ end;
+
+ if Fade >= 2 then begin
+ if (FadeTex > 0) then //Delete Fade Tex
+ begin
+ glDeleteTextures(1, @FadeTex);
+ FadeTex := 0;
+ end;
+
+ // koniec fade'a
+ ActualScreen := NextScreen;
+ NextScreen := nil;
+ ActualScreen.onShowFinish;
+ ActualScreen.ShowFinish := true;
+ end;
+ end; // if
+ 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;
+ ForceDirectories(ScreenshotsPath);
+ 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 + }'screenshot' + 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 := ScreenH;
+ FileInfo.biHeight := ScreenW;
+ 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;
+
+
+end.
diff --git a/Game/Code/Menu/UDrawTexture.dcu b/Game/Code/Menu/UDrawTexture.dcu
new file mode 100644
index 00000000..9e6402a9
--- /dev/null
+++ b/Game/Code/Menu/UDrawTexture.dcu
Binary files differ
diff --git a/Game/Code/Menu/UDrawTexture.pas b/Game/Code/Menu/UDrawTexture.pas
new file mode 100644
index 00000000..5a543f33
--- /dev/null
+++ b/Game/Code/Menu/UDrawTexture.pas
@@ -0,0 +1,101 @@
+unit UDrawTexture;
+
+interface
+uses UTexture;
+
+procedure DrawLine(X1, Y1, X2, Y2, ColR, ColG, ColB: real);
+procedure DrawQuad(X, Y, W, H, ColR, ColG, ColB: real);
+procedure DrawTexture(Texture: TTexture);
+
+implementation
+uses OpenGL12;
+
+procedure DrawLine(X1, Y1, X2, Y2, ColR, ColG, ColB: real);
+begin
+ glColor3f(ColR, ColG, ColB);
+ glBegin(GL_LINES);
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y2);
+ glEnd;
+end;
+
+procedure DrawQuad(X, Y, W, H, ColR, ColG, ColB: real);
+begin
+ glColor3f(ColR, ColG, ColB);
+ glBegin(GL_QUADS);
+ glVertex2f(x, y);
+ glVertex2f(x, y+h);
+ glVertex2f(x+w, y+h);
+ glVertex2f(x+w, y);
+ glEnd;
+end;
+
+procedure DrawTexture(Texture: TTexture);
+var
+ x1, x2, x3, x4: real;
+ y1, y2, y3, y4: real;
+ xt1, xt2, xt3, xt4: real;
+ yt1, yt2, yt3, yt4: real;
+begin
+ with Texture do begin
+ // rysuje paski gracza
+ glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glDepthRange(0, 10);
+ glDepthFunc(GL_LEQUAL);
+// glDepthFunc(GL_GEQUAL);
+ glEnable(GL_DEPTH_TEST);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+// glBlendFunc(GL_SRC_COLOR, GL_ZERO);
+ glBindTexture(GL_TEXTURE_2D, TexNum);
+
+ x1 := x;
+ x2 := x;
+ x3 := x+w*scaleW;
+ x4 := x+w*scaleW;
+ y1 := y;
+ y2 := y+h*scaleH;
+ y3 := y+h*scaleH;
+ y4 := y;
+ if Rot <> 0 then begin
+ xt1 := x1 - (x + w/2);
+ xt2 := x2 - (x + w/2);
+ xt3 := x3 - (x + w/2);
+ xt4 := x4 - (x + w/2);
+ yt1 := y1 - (y + h/2);
+ yt2 := y2 - (y + h/2);
+ yt3 := y3 - (y + h/2);
+ yt4 := y4 - (y + h/2);
+
+ x1 := (x + w/2) + xt1 * cos(Rot) - yt1 * sin(Rot);
+ x2 := (x + w/2) + xt2 * cos(Rot) - yt2 * sin(Rot);
+ x3 := (x + w/2) + xt3 * cos(Rot) - yt3 * sin(Rot);
+ x4 := (x + w/2) + xt4 * cos(Rot) - yt4 * sin(Rot);
+
+ y1 := (y + h/2) + yt1 * cos(Rot) + xt1 * sin(Rot);
+ y2 := (y + h/2) + yt2 * cos(Rot) + xt2 * sin(Rot);
+ y3 := (y + h/2) + yt3 * cos(Rot) + xt3 * sin(Rot);
+ y4 := (y + h/2) + yt4 * cos(Rot) + xt4 * sin(Rot);
+
+ end;
+
+{ glBegin(GL_QUADS);
+ glTexCoord2f(0, 0); glVertex3f(x1, y1, z);
+ glTexCoord2f(0, TexH); glVertex3f(x2, y2, z);
+ glTexCoord2f(TexW, TexH); glVertex3f(x3, y3, z);
+ glTexCoord2f(TexW, 0); glVertex3f(x4, y4, z);
+ glEnd;}
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(TexX1*TexW, TexY1*TexH); glVertex3f(x1, y1, z);
+ glTexCoord2f(TexX1*TexW, TexY2*TexH); glVertex3f(x2, y2, z);
+ glTexCoord2f(TexX2*TexW, TexY2*TexH); glVertex3f(x3, y3, z);
+ glTexCoord2f(TexX2*TexW, TexY1*TexH); glVertex3f(x4, y4, z);
+ glEnd;
+ end;
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_TEXTURE_2D);
+end;
+
+end.
diff --git a/Game/Code/Menu/UMenu.dcu b/Game/Code/Menu/UMenu.dcu
new file mode 100644
index 00000000..126834d8
--- /dev/null
+++ b/Game/Code/Menu/UMenu.dcu
Binary files differ
diff --git a/Game/Code/Menu/UMenu.pas b/Game/Code/Menu/UMenu.pas
new file mode 100644
index 00000000..7c256b5c
--- /dev/null
+++ b/Game/Code/Menu/UMenu.pas
@@ -0,0 +1,1136 @@
+unit UMenu;
+
+interface
+
+uses OpenGL12, SysUtils, UTexture, UMenuStatic, UMenuText, UMenuButton, UMenuSelect, UMenuSelectSlide,
+ UMenuInteract, UThemes;
+
+type
+{ Int16 = SmallInt;}
+
+ PMenu = ^TMenu;
+ TMenu = class
+ protected
+ Interactions: array of TInteract;
+ SelInteraction: integer;
+ Static: array of TStatic;
+ Button: array of TButton;
+ Selects: array of TSelect;
+ SelectsS: array of TSelectSlide;
+ BackImg: TTexture;
+ BackW: integer;
+ BackH: integer;
+ public
+ Text: array of TText;
+ mX: integer; // mouse X
+ mY: integer; // mouse Y
+
+ Fade: integer; // fade type
+ ShowFinish: boolean; // true if there is no fade
+
+
+ destructor Destroy; override;
+ constructor Create; overload; virtual;
+ constructor Create(Back: string); overload; virtual; // Back is a JPG resource name for background
+ constructor Create(Back: string; W, H: integer); overload; virtual; // W and H are the number of overlaps
+
+ // interaction
+ procedure AddInteraction(Typ, Num: integer);
+ procedure SetInteraction(Num: integer);
+ property Interaction: integer read SelInteraction write SetInteraction;
+
+ // background
+ procedure AddBackground(Name: string);
+
+ // static
+ function AddStatic(ThemeStatic: TThemeStatic): integer; overload;
+ function AddStatic(X, Y, W, H: real; Name: string): integer; overload;
+ function AddStatic(X, Y, W, H: real; Name, Format, Typ: string): integer; overload;
+ function AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; Name, Format, Typ: string): integer; overload;
+ function AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; Name, Format, Typ: string): integer; overload;
+ function AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; Name, Format, Typ: string; Color: integer): integer; overload;
+ function AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; Name, Format, Typ: string; Color: integer): integer; overload;
+ function AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; TexX1, TexY1, TexX2, TexY2: real; Name, Format, Typ: string; Color: integer): integer; overload;
+
+ // text
+ function AddText(ThemeText: TThemeText): integer; overload;
+ function AddText(X, Y: real; Tekst: string): integer; overload;
+ function AddText(X, Y: real; Style: integer; Size, ColR, ColG, ColB: real; Tekst: string): integer; overload;
+ function AddText(X, Y: real; Style: integer; Size, ColR, ColG, ColB: real; Align: integer; Tekst: string): integer; overload;
+
+ // button
+ function AddButton(ThemeButton: TThemeButton): integer; overload;
+ function AddButton(X, Y, W, H: real; Name: String): integer; overload;
+ function AddButton(X, Y, W, H: real; Name, Format, Typ: String; Reflection: Boolean): integer; overload;
+ function AddButton(X, Y, W, H, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt: real; Name, Format, Typ: String; Reflection: Boolean): integer; overload;
+ procedure ClearButtons;
+ procedure AddButtonText(AddX, AddY: real; AddText: string); overload;
+ procedure AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; AddText: string); overload;
+ procedure AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; AddText: string); overload;
+
+ // select
+ function AddSelect(ThemeSelect: TThemeSelect; var Data: integer; Values: array of string): integer; overload;
+ function AddSelect(X, Y, W, H, SkipX, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt,
+ TColR, TColG, TColB, TInt, TDColR, TDColG, TDColB, TDInt,
+ SBGColR, SBGColG, SBGColB, SBGInt, SBGDColR, SBGDColG, SBGDColB, SBGDInt,
+ STColR, STColG, STColB, STInt, STDColR, STDColG, STDColB, STDInt: real;
+ Name, Typ: String; SBGName, SBGTyp: String;
+ Caption: string; var Data: integer): integer; overload;
+ procedure AddSelectOption(AddX, AddY: real; AddText: string); overload;
+ procedure AddSelectOption(SelectNo: Cardinal; AddX, AddY: real; AddText: string); overload;
+ procedure UpdateSelectOptions(ThemeSelect: TThemeSelect; SelectNum: integer; Values: array of string; var Data: integer);
+
+ // select slide
+ function AddSelectSlide(ThemeSelectS: TThemeSelectSlide; var Data: integer; Values: array of string): integer; overload;
+ function AddSelectSlide(X, Y, W, H, SkipX, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt,
+ TColR, TColG, TColB, TInt, TDColR, TDColG, TDColB, TDInt,
+ SBGColR, SBGColG, SBGColB, SBGInt, SBGDColR, SBGDColG, SBGDColB, SBGDInt,
+ STColR, STColG, STColB, STInt, STDColR, STDColG, STDColB, STDInt: real;
+ Name, Typ: String; SBGName, SBGTyp: String;
+ Caption: string; var Data: integer): integer; overload;
+ procedure AddSelectSlideOption(AddText: string); overload;
+ procedure AddSelectSlideOption(SelectNo: Cardinal; AddText: string); overload;
+ procedure UpdateSelectSlideOptions(ThemeSelectSlide: TThemeSelectSlide; SelectNum: integer; Values: array of string; var Data: integer);
+
+
+// function AddWidget(X, Y : UInt16; WidgetSrc : PSDL_Surface): Int16;
+// procedure ClearWidgets(MinNumber : Int16);
+ procedure FadeTo(Screen: PMenu);
+
+ function DrawBG: boolean; virtual;
+ function DrawFG: boolean; virtual;
+ function Draw: boolean; virtual;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown : Boolean): Boolean; virtual;
+ function ParseMouse(Typ: integer; X: integer; Y: integer): Boolean; virtual; abstract;
+ function InRegion(X1, Y1, X2, Y2, X, Y: real): Boolean;
+ function InStaticRegion(StaticNr: integer; X, Y: integer): Boolean;
+ procedure onShow; virtual;
+ procedure onShowFinish; virtual;
+ procedure onHide; virtual;
+
+ procedure SetAnimationProgress(Progress: real); virtual;
+
+
+ procedure InteractNext; virtual;
+ procedure InteractCustom(CustomSwitch: integer); virtual;
+ procedure InteractPrev; virtual;
+ procedure InteractInc; virtual;
+ procedure InteractDec; virtual;
+
+ procedure AddBox(X, Y, W, H: real);
+ end;
+
+const
+ pmMove = 1;
+ pmClick = 2;
+ pmUnClick = 3;
+
+ iButton = 0; // interaction type
+ iSelect = 1;
+ iText = 2;
+ iSelectS = 3;
+
+// fBlack = 0; // fade type
+// fWhite = 1;
+
+implementation
+
+uses UMain, UDrawTexture, UGraphic, UDisplay, UCovers, USkins;
+
+destructor TMenu.Destroy;
+begin
+ inherited;
+end;
+
+constructor TMenu.Create;
+begin
+ Fade := 0;//fWhite;
+
+ SetLength(Static, 0);
+ SetLength(Button, 0);
+
+ BackImg.TexNum := -1;
+end;
+
+constructor TMenu.Create(Back: String);
+begin
+ inherited Create;
+
+ if Back <> '' then begin
+// BackImg := Texture.LoadTexture(true, PChar(Back), 'JPG', 'Plain', 0);
+ BackImg := Texture.LoadTexture(PChar(Back), 'JPG', 'Plain', 0); // new theme system
+ BackImg.W := 800;//640;
+ BackImg.H := 600;//480;
+ BackW := 1;
+ BackH := 1;
+ end else
+ BackImg.TexNum := -1;
+end;
+
+constructor TMenu.Create(Back: string; W, H: integer);
+begin
+ Create(Back);
+ BackImg.W := BackImg.W / W;
+ BackImg.H := BackImg.H / H;
+ BackW := W;
+ BackH := H;
+end;
+
+procedure TMenu.AddInteraction(Typ, Num: integer);
+var
+ IntNum: integer;
+begin
+ IntNum := Length(Interactions);
+ SetLength(Interactions, IntNum+1);
+ Interactions[IntNum].Typ := Typ;
+ Interactions[IntNum].Num := Num;
+ Interaction := 0;
+end;
+
+procedure TMenu.SetInteraction(Num: integer);
+var
+ OldNum, OldTyp: integer;
+ NewNum, NewTyp: integer;
+begin
+ // set inactive
+ OldNum := Interactions[Interaction].Num;
+ OldTyp := Interactions[Interaction].Typ;
+ case OldTyp of
+ iButton: Button[OldNum].Selected := False;
+ iSelect: Selects[OldNum].Selected := False;
+ iText: Text[OldNum].Selected := False;
+ iSelectS: SelectsS[OldNum].Selected := False;
+ end;
+
+ // set active
+ SelInteraction := Num;
+ NewNum := Interactions[Interaction].Num;
+ NewTyp := Interactions[Interaction].Typ;
+ case NewTyp of
+ iButton: Button[NewNum].Selected := True;
+ iSelect: Selects[NewNum].Selected := True;
+ iText: Text[NewNum].Selected := True;
+ iSelectS: SelectsS[NewNum].Selected := True;
+ end;
+end;
+
+procedure TMenu.AddBackground(Name: string);
+begin
+ if Name <> '' then begin
+// BackImg := Texture.LoadTexture(false, PChar(Skin.SkinPath + FileName), 'JPG', 'Plain', 0); // new theme system
+ BackImg := Texture.GetTexture(Skin.GetTextureFileName(Name), 'Plain');
+ BackImg.W := 800;
+ BackImg.H := 600;
+ BackW := 1;
+ BackH := 1;
+ end;
+end;
+
+function TMenu.AddStatic(ThemeStatic: TThemeStatic): integer;
+begin
+ Result := AddStatic(ThemeStatic.X, ThemeStatic.Y, ThemeStatic.W, ThemeStatic.H, ThemeStatic.Z,
+ ThemeStatic.ColR, ThemeStatic.ColG, ThemeStatic.ColB,
+ ThemeStatic.TexX1, ThemeStatic.TexY1, ThemeStatic.TexX2, ThemeStatic.TexY2,
+ {<0.5.1: Skin.SkinPath + ThemeStatic.Tex, 0.5.1:} Skin.GetTextureFileName(ThemeStatic.Tex),
+ 'JPG', ThemeStatic.Typ, $FFFFFF);
+ //'Font Black');
+end;
+
+function TMenu.AddStatic(X, Y, W, H: real; Name: string): integer;
+begin
+ Result := AddStatic(X, Y, W, H, Name, 'JPG', 'Plain');
+end;
+
+function TMenu.AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; Name, Format, Typ: string): integer;
+var
+ StatNum: integer;
+begin
+ Result := AddStatic(X, Y, W, H, ColR, ColG, ColB, Name, Format, Typ, $FFFFFF);
+end;
+
+function TMenu.AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; Name, Format, Typ: string): integer;
+var
+ StatNum: integer;
+begin
+ Result := AddStatic(X, Y, W, H, Z, ColR, ColG, ColB, Name, Format, Typ, $FFFFFF);
+end;
+
+function TMenu.AddStatic(X, Y, W, H: real; Name, Format, Typ: string): integer;
+var
+ StatNum: integer;
+begin
+ // adds static
+ StatNum := Length(Static);
+ SetLength(Static, StatNum + 1);
+// Static[StatNum] := TStatic.Create(Texture.LoadTexture(PChar(Name), PChar(Format), PChar(Typ), $FF00FF)); // $FFFFFF
+// Static[StatNum] := TStatic.Create(Texture.LoadTexture(Skin.SkinReg, PChar(Name), PChar(Format), PChar(Typ), $FF00FF)); // new skin system
+ Static[StatNum] := TStatic.Create(Texture.LoadTexture(PChar(Name), PChar(Format), PChar(Typ), $FF00FF)); // new skin
+
+ // configures static
+ Static[StatNum].Texture.X := X;
+ Static[StatNum].Texture.Y := Y;
+ Static[StatNum].Texture.W := W;
+ Static[StatNum].Texture.H := H;
+ Static[StatNum].Visible := true;
+ Result := StatNum;
+end;
+
+function TMenu.AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; Name, Format, Typ: string; Color: integer): integer;
+var
+ StatNum: integer;
+begin
+ Result := AddStatic(X, Y, W, H, 0, ColR, ColG, ColB, Name, Format, Typ, Color);
+end;
+
+function TMenu.AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; Name, Format, Typ: string; Color: integer): integer;
+begin
+ Result := AddStatic(X, Y, W, H, Z, ColR, ColG, ColB, 0, 0, 1, 1, Name, Format, Typ, Color);
+//
+end;
+
+function TMenu.AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; TexX1, TexY1, TexX2, TexY2: real; Name, Format, Typ: string; Color: integer): integer;
+var
+ StatNum: integer;
+begin
+ // adds static
+ StatNum := Length(Static);
+ SetLength(Static, StatNum + 1);
+// Static[StatNum] := TStatic.Create(Texture.LoadTexture(PChar(Name), PChar(Format), PChar(Typ), Color));
+// Static[StatNum] := TStatic.Create(Texture.LoadTexture(Skin.SkinReg, PChar(Name), PChar(Format), PChar(Typ), Color)); // new skin system
+Static[StatNum] := TStatic.Create(Texture.LoadTexture(PChar(Name), PChar(Format), PChar(Typ), Color)); // new skin
+// Static[StatNum] := TStatic.Create(Texture.GetTexture(Name, Typ));
+
+ // configures static
+ Static[StatNum].Texture.X := X;
+ Static[StatNum].Texture.Y := Y;
+ Static[StatNum].Texture.W := W;
+ Static[StatNum].Texture.H := H;
+ Static[StatNum].Texture.Z := Z;
+ Static[StatNum].Texture.ColR := ColR;
+ Static[StatNum].Texture.ColG := ColG;
+ Static[StatNum].Texture.ColB := ColB;
+ Static[StatNum].Texture.TexX1 := TexX1;
+ Static[StatNum].Texture.TexY1 := TexY1;
+ Static[StatNum].Texture.TexX2 := TexX2;
+ Static[StatNum].Texture.TexY2 := TexY2;
+ Static[StatNum].Texture.Alpha := 1;
+ Static[StatNum].Visible := true;
+ Result := StatNum;
+end;
+
+function TMenu.AddText(ThemeText: TThemeText): integer;
+begin
+ Result := AddText(ThemeText.X, ThemeText.Y, ThemeText.Font, ThemeText.Size,
+ ThemeText.ColR, ThemeText.ColG, ThemeText.ColB, ThemeText.Align, ThemeText.Text);
+end;
+
+function TMenu.AddText(X, Y: real; Tekst: string): integer;
+var
+ TextNum: integer;
+begin
+ // adds text
+ TextNum := Length(Text);
+ SetLength(Text, TextNum + 1);
+ Text[TextNum] := TText.Create(X, Y, Tekst);
+ Result := TextNum;
+end;
+
+function TMenu.AddText(X, Y: real; Style: integer; Size, ColR, ColG, ColB: real; Tekst: string): integer;
+begin
+ Result := AddText(X, Y, Style, Size, ColR, ColG, ColB, 0, Tekst);
+end;
+
+function TMenu.AddText(X, Y: real; Style: integer; Size, ColR, ColG, ColB: real; Align: integer; Tekst: string): integer;
+var
+ TextNum: integer;
+begin
+ // adds text
+ TextNum := Length(Text);
+ SetLength(Text, TextNum + 1);
+ Text[TextNum] := TText.Create(X, Y, Style, Size, ColR, ColG, ColB, Align, Tekst);
+ Result := TextNum;
+end;
+
+
+// Method to add a button in our TMenu. It returns the assigned ButtonNumber
+function TMenu.AddButton(ThemeButton: TThemeButton): integer;
+var
+ BT: integer;
+ BTLen: integer;
+ temp: integer;
+begin
+{ Result := AddButton(ThemeButton.X, ThemeButton.Y, ThemeButton.W, ThemeButton.H,
+ ThemeButton.ColR, ThemeButton.ColG, ThemeButton.ColB, ThemeButton.Int,
+ ThemeButton.DColR, ThemeButton.DColG, ThemeButton.DColB, ThemeButton.DInt,
+ ThemeButton.Tex, 'JPG', 'Font Black');}
+
+ Result := AddButton(ThemeButton.X, ThemeButton.Y, ThemeButton.W, ThemeButton.H,
+ ThemeButton.ColR, ThemeButton.ColG, ThemeButton.ColB, ThemeButton.Int,
+ ThemeButton.DColR, ThemeButton.DColG, ThemeButton.DColB, ThemeButton.DInt,
+ Skin.GetTextureFileName(ThemeButton.Tex), 'JPG', ThemeButton.Typ, ThemeButton.Reflection);
+
+
+ BTLen := Length(ThemeButton.Text);
+ for BT := 0 to BTLen-1 do begin
+ AddButtonText(ThemeButton.Text[BT].X, ThemeButton.Text[BT].Y,
+ ThemeButton.Text[BT].ColR, ThemeButton.Text[BT].ColG, ThemeButton.Text[BT].ColB,
+ ThemeButton.Text[BT].Font, ThemeButton.Text[BT].Size, ThemeButton.Text[BT].Align,
+ ThemeButton.Text[BT].Text);
+ end;
+end;
+
+function TMenu.AddButton(X, Y, W, H: real; Name: String): integer;
+begin
+ Result := AddButton(X, Y, W, H, Name, 'JPG', 'Plain', False);
+end;
+
+function TMenu.AddButton(X, Y, W, H: real; Name, Format, Typ: String; Reflection: Boolean): integer;
+begin
+ Result := AddButton(X, Y, W, H, 1, 1, 1, 1, 1, 1, 1, 0.5, Name, 'JPG', 'Plain', Reflection);
+end;
+
+function TMenu.AddButton(X, Y, W, H, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt: real; Name, Format, Typ: String; Reflection: Boolean): integer;
+var
+ ButNum : integer;
+begin
+ // adds button
+ ButNum := Length(Button);
+ SetLength(Button, ButNum + 1);
+// Button[ButNum] := TButton.Create(Texture.GetTexture(Name, Typ));
+
+ // check here for cache
+// Texture.GetTexture(Name, Typ, false); // preloads textures and creates cahce mipmap when needed
+// if Covers.CoverExists(Name) then
+ Button[ButNum] := TButton.Create(Texture.GetTexture(Name, Typ, true)); // use cache texture
+// else
+// Button[ButNum] := TButton.Create(Texture.GetTexture(Name, Typ, false)); // don't use cache texture}
+
+ // configures button
+ Button[ButNum].Texture.X := X;
+ Button[ButNum].Texture.Y := Y;
+ Button[ButNum].Texture.W := W;
+ Button[ButNum].Texture.H := H;
+ Button[ButNum].SelectColR := ColR;
+ Button[ButNum].SelectColG := ColG;
+ Button[ButNum].SelectColB := ColB;
+ Button[ButNum].SelectInt := Int;
+ Button[ButNum].DeselectColR := DColR;
+ Button[ButNum].DeselectColG := DColG;
+ Button[ButNum].DeselectColB := DColB;
+ Button[ButNum].DeselectInt := DInt;
+ Button[ButNum].Texture.TexX1 := 0;
+ Button[ButNum].Texture.TexY1 := 0;
+ Button[ButNum].Texture.TexX2 := 1;
+ Button[ButNum].Texture.TexY2 := 1;
+ Button[ButNum].SetSelect(false);
+
+ Button[ButNum].Reflection := Reflection;
+
+ // adds interaction
+ AddInteraction(iButton, ButNum);
+ Interaction := 0;
+end;
+
+procedure TMenu.ClearButtons;
+begin
+ Setlength(Button, 0);
+end;
+
+// Method to draw our TMenu and all his child buttons
+function TMenu.DrawBG: boolean;
+var
+ PetX: integer;
+ PetY: integer;
+begin
+// glClearColor(1, 1, 1, 1);
+// glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity;
+ glOrtho(0, RenderW, RenderH, 0, -1, 100);
+ glMatrixMode(GL_MODELVIEW);
+
+ BackImg.ColR := 1;
+ BackImg.ColG := 1;
+ BackImg.ColB := 1;
+ BackImg.TexX1 := 0;
+ BackImg.TexY1 := 0;
+ BackImg.TexX2 := 1;
+ BackImg.TexY2 := 1;
+ if (BackImg.TexNum <> -1) then begin
+ // draw texture with overlapping
+ for PetY := 1 to BackH do
+ for PetX := 1 to BackW do begin
+ BackImg.X := (PetX-1)/BackW * 800; //640
+ BackImg.Y := (PetY-1)/BackH * 600; //480
+ DrawTexture(BackImg);
+ end; // for PetX
+ end; // if
+end;
+
+function TMenu.DrawFG: boolean;
+var
+ J: Integer;
+begin
+ // We don't forget about newly implemented static for nice skin ...
+ for J := 0 to Length(Static) - 1 do
+ Static[J].Draw;
+
+ // ... and slightly implemented menutext unit
+ for J := 0 to Length(Text) - 1 do
+ Text[J].Draw;
+
+ // Second, we draw all of our buttons
+ for J := 0 to Length(Button) - 1 do
+ Button[J].Draw;
+
+ // Third, we draw all of our selects
+ for J := 0 to Length(Selects) - 1 do
+ Selects[J].Draw(1);
+
+ for J := 0 to Length(SelectsS) - 1 do
+ SelectsS[J].Draw;
+
+ // Third, we draw all our widgets
+// for J := 0 to Length(WidgetsSrc) - 1 do
+// SDL_BlitSurface(WidgetsSrc[J], nil, ParentBackBuf, WidgetsRect[J]);
+ Result := True;
+end;
+
+function TMenu.Draw: boolean;
+begin
+ DrawBG;
+ DrawFG;
+ Result := True;
+end;
+
+{function TMenu.GetNextScreen(): PMenu;
+begin
+ Result := NextScreen;
+end;}
+
+{function TMenu.AddWidget(X, Y : UInt16; WidgetSrc : PSDL_Surface): Int16;
+var
+ WidgetNum : Int16;
+
+begin
+ If (Assigned(WidgetSrc)) Then
+ begin
+ WidgetNum := Length(WidgetsSrc);
+
+ SetLength(WidgetsSrc, WidgetNum + 1);
+ SetLength(WidgetsRect, WidgetNum + 1);
+
+ WidgetsSrc[WidgetNum] := WidgetSrc;
+ WidgetsRect[WidgetNum] := new(PSDL_Rect);
+ WidgetsRect[WidgetNum]^.x := X;
+ WidgetsRect[WidgetNum]^.y := Y;
+ WidgetsRect[WidgetNum]^.w := WidgetSrc^.w;
+ WidgetsRect[WidgetNum]^.h := WidgetSrc^.h;
+
+ Result := WidgetNum;
+ end
+ else
+ Result := -1;
+end;}
+
+{procedure TMenu.ClearWidgets(MinNumber : Int16);
+var
+ J : Int16;
+begin
+ For J := MinNumber to (Length(WidgetsSrc) - 1) do
+ begin
+ SDL_FreeSurface(WidgetsSrc[J]);
+ dispose(WidgetsRect[J]);
+ end;
+
+ SetLength(WidgetsSrc, MinNumber);
+ SetLength(WidgetsRect, MinNumber);
+end;}
+
+procedure TMenu.InteractNext;
+var
+ Num: integer;
+ Typ: integer;
+ Again: boolean;
+begin
+ Again := true;
+
+ // change interaction as long as it's needed
+ while (Again = true) do begin
+ Num := (Interaction + 1) Mod Length(Interactions);
+ Interaction := Num;
+ Again := false; // reset, default to accept changing interaction
+
+
+ // checking newly interacted element
+ Num := Interactions[Interaction].Num;
+ Typ := Interactions[Interaction].Typ;
+ case Typ of
+ iButton:
+ begin
+ if Button[Num].Selectable = false then Again := True;
+ end;
+ end; // case
+ end; // while
+end;
+
+
+procedure TMenu.InteractPrev;
+var
+ Num: integer;
+ Typ: integer;
+ Again: boolean;
+begin
+ Again := true;
+
+ // change interaction as long as it's needed
+ while (Again = true) do begin
+ Num := SelInteraction - 1;
+ if Num = -1 then Num := High(Interactions);
+ Interaction := Num;
+ Again := false; // reset, default to accept changing interaction
+
+ // checking newly interacted element
+ Num := Interactions[Interaction].Num;
+ Typ := Interactions[Interaction].Typ;
+ case Typ of
+ iButton:
+ begin
+ if Button[Num].Selectable = false then Again := True;
+ end;
+ end; // case
+ end; // while
+
+end;
+
+
+procedure TMenu.InteractCustom(CustomSwitch: integer);
+var
+ Num: integer;
+ Typ: integer;
+ Again: boolean;
+begin
+ if num<0 then begin
+ CustomSwitch:= CustomSwitch*(-1);
+ Again := true;
+ // change interaction as long as it's needed
+ while (Again = true) do begin
+ Num := SelInteraction - CustomSwitch;
+ if Num = -1 then Num := High(Interactions);
+ Interaction := Num;
+ Again := false; // reset, default to accept changing interaction
+
+ // checking newly interacted element
+ Num := Interactions[Interaction].Num;
+ Typ := Interactions[Interaction].Typ;
+ case Typ of
+ iButton:
+ begin
+ if Button[Num].Selectable = false then Again := True;
+ end;
+ end; // case
+ end; // while
+ end
+ else if num>0 then begin
+ Again := true;
+ // change interaction as long as it's needed
+ while (Again = true) do begin
+ Num := (Interaction + CustomSwitch) Mod Length(Interactions);
+ Interaction := Num;
+ Again := false; // reset, default to accept changing interaction
+
+
+ // checking newly interacted element
+ Num := Interactions[Interaction].Num;
+ Typ := Interactions[Interaction].Typ;
+ case Typ of
+ iButton:
+ begin
+ if Button[Num].Selectable = false then Again := True;
+ end;
+ end; // case
+ end; // while
+ end
+end;
+
+
+procedure TMenu.FadeTo(Screen: PMenu);
+begin
+ Display.Fade := 0;
+ Display.NextScreen := Screen;
+end;
+
+procedure TMenu.AddButtonText(AddX, AddY: real; AddText: string);
+begin
+ AddButtonText(AddX, AddY, 1, 1, 1, AddText);
+end;
+
+procedure TMenu.AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; AddText: string);
+var
+ Il: integer;
+begin
+ with Button[High(Button)] do begin
+ Il := Length(Text);
+ SetLength(Text, Il+1);
+ Text[Il] := TText.Create(X + AddX, Y + AddY, AddText);
+ Text[Il].ColR := ColR;
+ Text[Il].ColG := ColG;
+ Text[Il].ColB := ColB;
+ Text[Il].Int := 1;//0.5;
+ end;
+end;
+
+procedure TMenu.AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; AddText: string);
+var
+ Il: integer;
+begin
+ with Button[High(Button)] do begin
+ Il := Length(Text);
+ SetLength(Text, Il+1);
+ Text[Il] := TText.Create(X + AddX, Y + AddY, AddText);
+ Text[Il].ColR := ColR;
+ Text[Il].ColG := ColG;
+ Text[Il].ColB := ColB;
+ Text[Il].Int := 1;//0.5;
+ Text[Il].Style := Font;
+ Text[Il].Size := Size;
+ Text[Il].Align := Align;
+ end;
+end;
+
+function TMenu.AddSelect(ThemeSelect: TThemeSelect; var Data: integer; Values: array of string): integer;
+var
+ SO: integer;
+begin
+ Result := AddSelect(ThemeSelect.X, ThemeSelect.Y, ThemeSelect.W, ThemeSelect.H, ThemeSelect.SkipX,
+ ThemeSelect.ColR, ThemeSelect.ColG, ThemeSelect.ColB, ThemeSelect.Int,
+ ThemeSelect.DColR, ThemeSelect.DColG, ThemeSelect.DColB, ThemeSelect.DInt,
+ ThemeSelect.TColR, ThemeSelect.TColG, ThemeSelect.TColB, ThemeSelect.TInt,
+ ThemeSelect.TDColR, ThemeSelect.TDColG, ThemeSelect.TDColB, ThemeSelect.TDInt,
+ ThemeSelect.SBGColR, ThemeSelect.SBGColG, ThemeSelect.SBGColB, ThemeSelect.SBGInt,
+ ThemeSelect.SBGDColR, ThemeSelect.SBGDColG, ThemeSelect.SBGDColB, ThemeSelect.SBGDInt,
+ ThemeSelect.STColR, ThemeSelect.STColG, ThemeSelect.STColB, ThemeSelect.STInt,
+ ThemeSelect.STDColR, ThemeSelect.STDColG, ThemeSelect.STDColB, ThemeSelect.STDInt,
+ Skin.GetTextureFileName(ThemeSelect.Tex), 'Font Black',
+ Skin.GetTextureFileName(ThemeSelect.TexSBG), 'Font Black',
+ ThemeSelect.Text, Data);
+ for SO := 0 to High(Values) do
+ AddSelectOption(ThemeSelect.X + ThemeSelect.W + ThemeSelect.SkipX + SO * 100 + 20, ThemeSelect.Y + 20, Values[SO]);
+end;
+
+function TMenu.AddSelect(X, Y, W, H, SkipX, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt,
+ TColR, TColG, TColB, TInt, TDColR, TDColG, TDColB, TDInt,
+ SBGColR, SBGColG, SBGColB, SBGInt, SBGDColR, SBGDColG, SBGDColB, SBGDInt,
+ STColR, STColG, STColB, STInt, STDColR, STDColG, STDColB, STDInt: real;
+ Name, Typ: String; SBGName, SBGTyp: String;
+ Caption: string; var Data: integer): integer;
+var
+ S: integer;
+begin
+ S := Length(Selects);
+ SetLength(Selects, S + 1);
+ Selects[S] := TSelect.Create;
+
+ Selects[S].Texture := Texture.GetTexture(Name, Typ);
+ Selects[S].X := X;
+ Selects[S].Y := Y;
+ Selects[S].W := W;
+ Selects[S].H := H;
+ Selects[S].ColR := ColR;
+ Selects[S].ColG := ColG;
+ Selects[S].ColB := ColB;
+ Selects[S].Int := Int;
+ Selects[S].DColR := DColR;
+ Selects[S].DColG := DColG;
+ Selects[S].DColB := DColB;
+ Selects[S].DInt := DInt;
+
+ Selects[S].TextureSBG := Texture.GetTexture(SBGName, SBGTyp);
+ Selects[S].TextureSBG.X := X + W + SkipX;
+ Selects[S].TextureSBG.Y := Y;
+ Selects[S].TextureSBG.W := 450;
+ Selects[S].TextureSBG.H := H;
+ Selects[S].SBGColR := SBGColR;
+ Selects[S].SBGColG := SBGColG;
+ Selects[S].SBGColB := SBGColB;
+ Selects[S].SBGInt := SBGInt;
+ Selects[S].SBGDColR := SBGDColR;
+ Selects[S].SBGDColG := SBGDColG;
+ Selects[S].SBGDColB := SBGDColB;
+ Selects[S].SBGDInt := SBGDInt;
+
+ Selects[S].Text.X := X + 20;
+ Selects[S].Text.Y := Y + 20;
+ Selects[S].Text.Text := Caption;
+ Selects[S].Text.Size := 10;
+ Selects[S].Text.Visible := true;
+ Selects[S].TColR := TColR;
+ Selects[S].TColG := TColG;
+ Selects[S].TColB := TColB;
+ Selects[S].TInt := TInt;
+ Selects[S].TDColR := TDColR;
+ Selects[S].TDColG := TDColG;
+ Selects[S].TDColB := TDColB;
+ Selects[S].TDInt := TDInt;
+
+ Selects[S].STColR := STColR;
+ Selects[S].STColG := STColG;
+ Selects[S].STColB := STColB;
+ Selects[S].STInt := STInt;
+ Selects[S].STDColR := STDColR;
+ Selects[S].STDColG := STDColG;
+ Selects[S].STDColB := STDColB;
+ Selects[S].STDInt := STDInt;
+
+ // new
+ Selects[S].Texture.TexX1 := 0;
+ Selects[S].Texture.TexY1 := 0;
+ Selects[S].Texture.TexX2 := 1;
+ Selects[S].Texture.TexY2 := 1;
+ Selects[S].TextureSBG.TexX1 := 0;
+ Selects[S].TextureSBG.TexY1 := 0;
+ Selects[S].TextureSBG.TexX2 := 1;
+ Selects[S].TextureSBG.TexY2 := 1;
+
+ // Sets Data to copy the value of selectops to global value;
+ Selects[S].PData := @Data;
+
+ // Sets default value of selectopt from Data;
+ Selects[S].SelectedOption := Data;
+
+ // Disables default selection
+ Selects[S].SetSelect(false);
+
+ // adds interaction
+ AddInteraction(iSelect, S);
+end;
+
+procedure TMenu.AddSelectOption(AddX, AddY: real; AddText: string);
+begin
+ AddSelectOption (High(Selects), AddX, AddY, AddText);
+end;
+
+procedure TMenu.AddSelectOption(SelectNo: Cardinal; AddX, AddY: real; AddText: string);
+var
+ SO: integer;
+begin
+ SO := Length(Selects[SelectNo].TextOpt);
+ SetLength(Selects[SelectNo].TextOpt, SO + 1);
+
+ Selects[SelectNo].TextOpt[SO] := TText.Create;
+
+ Selects[SelectNo].TextOpt[SO].X := AddX;
+ Selects[SelectNo].TextOpt[SO].Y := AddY;
+ Selects[SelectNo].TextOpt[SO].Text := AddText;
+ Selects[SelectNo].TextOpt[SO].Size := 10;
+ Selects[SelectNo].TextOpt[SO].ColR := Selects[SelectNo].STDColR;
+ Selects[SelectNo].TextOpt[SO].ColG := Selects[SelectNo].STDColG;
+ Selects[SelectNo].TextOpt[SO].ColB := Selects[SelectNo].STDColB;
+ Selects[SelectNo].TextOpt[SO].Int := Selects[SelectNo].STDInt;
+ Selects[SelectNo].TextOpt[SO].Visible := true;
+
+ if SO = Selects[SelectNo].PData^ then Selects[SelectNo].SelectedOption := SO;
+end;
+
+procedure TMenu.UpdateSelectOptions(ThemeSelect: TThemeSelect; SelectNum: integer; Values: array of string; var Data: integer);
+var
+ SO: integer;
+begin
+ SetLength(Selects[SelectNum].TextOpt, 0);
+ for SO := 0 to High(Values) do
+ AddSelectOption(SelectNum, ThemeSelect.X + ThemeSelect.W + ThemeSelect.SkipX + SO * 100 + 20, ThemeSelect.Y + 20, Values[SO]);
+end;
+
+function TMenu.AddSelectSlide(ThemeSelectS: TThemeSelectSlide; var Data: integer; Values: array of string): integer;
+var
+ SO: integer;
+begin
+ Result := AddSelectSlide(ThemeSelectS.X, ThemeSelectS.Y, ThemeSelectS.W, ThemeSelectS.H, ThemeSelectS.SkipX,
+ ThemeSelectS.ColR, ThemeSelectS.ColG, ThemeSelectS.ColB, ThemeSelectS.Int,
+ ThemeSelectS.DColR, ThemeSelectS.DColG, ThemeSelectS.DColB, ThemeSelectS.DInt,
+ ThemeSelectS.TColR, ThemeSelectS.TColG, ThemeSelectS.TColB, ThemeSelectS.TInt,
+ ThemeSelectS.TDColR, ThemeSelectS.TDColG, ThemeSelectS.TDColB, ThemeSelectS.TDInt,
+ ThemeSelectS.SBGColR, ThemeSelectS.SBGColG, ThemeSelectS.SBGColB, ThemeSelectS.SBGInt,
+ ThemeSelectS.SBGDColR, ThemeSelectS.SBGDColG, ThemeSelectS.SBGDColB, ThemeSelectS.SBGDInt,
+ ThemeSelectS.STColR, ThemeSelectS.STColG, ThemeSelectS.STColB, ThemeSelectS.STInt,
+ ThemeSelectS.STDColR, ThemeSelectS.STDColG, ThemeSelectS.STDColB, ThemeSelectS.STDInt,
+ Skin.GetTextureFileName(ThemeSelectS.Tex), 'Font Black',
+ Skin.GetTextureFileName(ThemeSelectS.TexSBG), 'Font Black',
+ ThemeSelectS.Text, Data);
+ for SO := 0 to High(Values) do
+ AddSelectSlideOption(Values[SO]);
+
+ //Generate Lines
+ SelectsS[High(SelectsS)].GenLines;
+
+ SelectsS[High(SelectsS)].SelectedOption := SelectsS[High(SelectsS)].SelectOptInt; // refresh
+end;
+
+function TMenu.AddSelectSlide(X, Y, W, H, SkipX, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt,
+ TColR, TColG, TColB, TInt, TDColR, TDColG, TDColB, TDInt,
+ SBGColR, SBGColG, SBGColB, SBGInt, SBGDColR, SBGDColG, SBGDColB, SBGDInt,
+ STColR, STColG, STColB, STInt, STDColR, STDColG, STDColB, STDInt: real;
+ Name, Typ: String; SBGName, SBGTyp: String;
+ Caption: string; var Data: integer): integer;
+var
+ S: integer;
+ I: integer;
+begin
+ S := Length(SelectsS);
+ SetLength(SelectsS, S + 1);
+ SelectsS[S] := TSelectSlide.Create;
+
+ SelectsS[S].Texture := Texture.GetTexture(Name, Typ);
+ SelectsS[S].X := X;
+ SelectsS[S].Y := Y;
+ SelectsS[S].W := W;
+ SelectsS[S].H := H;
+ SelectsS[S].ColR := ColR;
+ SelectsS[S].ColG := ColG;
+ SelectsS[S].ColB := ColB;
+ SelectsS[S].Int := Int;
+ SelectsS[S].DColR := DColR;
+ SelectsS[S].DColG := DColG;
+ SelectsS[S].DColB := DColB;
+ SelectsS[S].DInt := DInt;
+
+ SelectsS[S].TextureSBG := Texture.GetTexture(SBGName, SBGTyp);
+ SelectsS[S].TextureSBG.X := X + W + SkipX;
+ SelectsS[S].TextureSBG.Y := Y;
+ SelectsS[S].TextureSBG.W := 450;
+ SelectsS[S].TextureSBG.H := H;
+ SelectsS[S].SBGColR := SBGColR;
+ SelectsS[S].SBGColG := SBGColG;
+ SelectsS[S].SBGColB := SBGColB;
+ SelectsS[S].SBGInt := SBGInt;
+ SelectsS[S].SBGDColR := SBGDColR;
+ SelectsS[S].SBGDColG := SBGDColG;
+ SelectsS[S].SBGDColB := SBGDColB;
+ SelectsS[S].SBGDInt := SBGDInt;
+
+ SelectsS[S].Text.X := X + 20;
+ SelectsS[S].Text.Y := Y + 20;
+ SelectsS[S].Text.Text := Caption;
+ SelectsS[S].Text.Size := 10;
+ SelectsS[S].Text.Visible := true;
+ SelectsS[S].TColR := TColR;
+ SelectsS[S].TColG := TColG;
+ SelectsS[S].TColB := TColB;
+ SelectsS[S].TInt := TInt;
+ SelectsS[S].TDColR := TDColR;
+ SelectsS[S].TDColG := TDColG;
+ SelectsS[S].TDColB := TDColB;
+ SelectsS[S].TDInt := TDInt;
+
+ SelectsS[S].STColR := STColR;
+ SelectsS[S].STColG := STColG;
+ SelectsS[S].STColB := STColB;
+ SelectsS[S].STInt := STInt;
+ SelectsS[S].STDColR := STDColR;
+ SelectsS[S].STDColG := STDColG;
+ SelectsS[S].STDColB := STDColB;
+ SelectsS[S].STDInt := STDInt;
+
+ // new
+ SelectsS[S].Texture.TexX1 := 0;
+ SelectsS[S].Texture.TexY1 := 0;
+ SelectsS[S].Texture.TexX2 := 1;
+ SelectsS[S].Texture.TexY2 := 1;
+ SelectsS[S].TextureSBG.TexX1 := 0;
+ SelectsS[S].TextureSBG.TexY1 := 0;
+ SelectsS[S].TextureSBG.TexX2 := 1;
+ SelectsS[S].TextureSBG.TexY2 := 1;
+
+ // Sets Data to copy the value of selectops to global value;
+ SelectsS[S].PData := @Data;
+ // Configures Select options
+ {//SelectsS[S].TextOpt[0].Text := IntToStr(I+1);
+ SelectsS[S].TextOpt[0].Size := 10;
+ SelectsS[S].TextOpt[0].Align := 1;
+
+ SelectsS[S].TextOpt[0].ColR := SelectsS[S].STDColR;
+ SelectsS[S].TextOpt[0].ColG := SelectsS[S].STDColG;
+ SelectsS[S].TextOpt[0].ColB := SelectsS[S].STDColB;
+ SelectsS[S].TextOpt[0].Int := SelectsS[S].STDInt;
+ SelectsS[S].TextOpt[0].Visible := true; }
+
+ // Sets default value of selectopt from Data;
+ SelectsS[S].SelectedOption := Data;
+
+ // Disables default selection
+ SelectsS[S].SetSelect(false);
+
+ {// Configures 3 select options
+ for I := 0 to 2 do begin
+ SelectsS[S].TextOpt[I].X := SelectsS[S].TextureSBG.X + 20 + (50 + 20) + (150 - 20) * I;
+ SelectsS[S].TextOpt[I].Y := SelectsS[S].TextureSBG.Y + 20;
+ SelectsS[S].TextOpt[I].Text := IntToStr(I+1);
+ SelectsS[S].TextOpt[I].Size := 10;
+ SelectsS[S].TextOpt[I].Align := 1;
+
+
+ SelectsS[S].TextOpt[I].ColR := SelectsS[S].STDColR;
+ SelectsS[S].TextOpt[I].ColG := SelectsS[S].STDColG;
+ SelectsS[S].TextOpt[I].ColB := SelectsS[S].STDColB;
+ SelectsS[S].TextOpt[I].Int := SelectsS[S].STDInt;
+ SelectsS[S].TextOpt[I].Visible := true;
+ end;}
+
+
+ // adds interaction
+ AddInteraction(iSelectS, S);
+ Result := S;
+end;
+
+procedure TMenu.AddSelectSlideOption(AddText: string);
+begin
+ AddSelectSlideOption(High(SelectsS), AddText);
+end;
+
+procedure TMenu.AddSelectSlideOption(SelectNo: Cardinal; AddText: string);
+var
+ SO: integer;
+begin
+ SO := Length(SelectsS[SelectNo].TextOptT);
+
+ SetLength(SelectsS[SelectNo].TextOptT, SO + 1);
+ SelectsS[SelectNo].TextOptT[SO] := AddText;
+
+ //SelectsS[S].SelectedOption := SelectsS[S].SelectOptInt; // refresh
+
+ //if SO = Selects[S].PData^ then Selects[S].SelectedOption := SO;
+end;
+
+procedure TMenu.UpdateSelectSlideOptions(ThemeSelectSlide: TThemeSelectSlide; SelectNum: integer; Values: array of string; var Data: integer);
+var
+ SO: integer;
+begin
+ SetLength(SelectsS[SelectNum].TextOptT, 0);
+ for SO := 0 to High(Values) do
+ AddSelectSlideOption(SelectNum, Values[SO]);
+
+ SelectsS[SelectNum].GenLines;
+
+// SelectsS[SelectNum].SelectedOption := SelectsS[SelectNum].SelectOptInt; // refresh
+// SelectS[SelectNum].SetSelectOpt(Data);
+// SelectS[SelectNum].SelectedOption := 0;//Data;
+
+// Log.LogError(IntToStr(High(SelectsS[SelectNum].TextOptT)));
+// if 0 <= High(SelectsS[SelectNum].TextOptT) then
+
+ SelectsS[SelectNum].PData := @Data;
+ SelectsS[SelectNum].SelectedOption := Data;
+end;
+
+function TMenu.InRegion(X1, Y1, X2, Y2, X, Y: real): Boolean;
+begin
+ Result := false;
+ X1 := X1 * RenderW/640;
+ X2 := X2 * RenderW/640;
+ Y1 := Y1 * RenderH/480;
+ Y2 := Y2 * RenderH/480;
+ if (X >= X1) and (X <= X2) and (Y >= Y1) and (Y <= Y2) then
+ Result := true;
+end;
+
+function TMenu.InStaticRegion(StaticNr: integer; X, Y: integer): Boolean;
+begin
+ Result := InRegion(Static[StaticNr].Texture.X,
+ Static[StaticNr].Texture.Y,
+ Static[StaticNr].Texture.X + Static[StaticNr].Texture.W - 1,
+ Static[StaticNr].Texture.Y + Static[StaticNr].Texture.H - 1,
+ X, Y);
+end;
+
+procedure TMenu.InteractInc;
+var
+ Num: integer;
+ Value: integer;
+begin
+ case Interactions[Interaction].Typ of
+ iSelect: begin
+ Num := Interactions[Interaction].Num;
+ Value := Selects[Num].SelectedOption;
+ Value := (Value + 1) Mod (Length(Selects[Num].TextOpt));
+ Selects[Num].SelectedOption := Value;
+ end;
+ iSelectS: begin
+ Num := Interactions[Interaction].Num;
+ Value := SelectsS[Num].SelectedOption;
+// Value := (Value + 1) Mod (Length(SelectsS[Num].TextOptT));
+
+ // limit
+ Value := Value + 1;
+ if Value <= High(SelectsS[Num].TextOptT) then
+ SelectsS[Num].SelectedOption := Value;
+ end;
+ end;
+end;
+
+procedure TMenu.InteractDec;
+var
+ Num: integer;
+ Value: integer;
+begin
+ case Interactions[Interaction].Typ of
+ iSelect: begin
+ Num := Interactions[Interaction].Num;
+ Value := Selects[Num].SelectedOption;
+ Value := Value - 1;
+ if Value = -1 then
+ Value := High(Selects[Num].TextOpt);
+ Selects[Num].SelectedOption := Value;
+ end;
+ iSelectS: begin
+ Num := Interactions[Interaction].Num;
+ Value := SelectsS[Num].SelectedOption;
+ Value := Value - 1;
+// if Value = -1 then
+// Value := High(SelectsS[Num].TextOptT);
+
+ if Value >= 0 then
+ SelectsS[Num].SelectedOption := Value;
+ end;
+ end
+end;
+
+procedure TMenu.AddBox(X, Y, W, H: real);
+begin
+ AddStatic(X, Y, W, H, 0, 0, 0, Skin.GetTextureFileName('Bar'), 'JPG', 'Font Black');
+ AddStatic(X+2, Y+2, W-4, H-4, 1, 1, 1, Skin.GetTextureFileName('Bar'), 'JPG', 'Font Black');
+end;
+
+procedure TMenu.onShow;
+begin
+// nothing
+// beep;
+end;
+
+procedure TMenu.onShowFinish;
+begin
+// nothing
+// beep;
+end;
+
+procedure TMenu.onHide;
+begin
+// nothing
+// beep;
+end;
+
+function TMenu.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+// nothing
+// Beep;
+ Result := true;
+end;
+
+procedure TMenu.SetAnimationProgress(Progress: real);
+begin
+// nothing
+//beep;
+end;
+
+end.
+
diff --git a/Game/Code/Menu/UMenuButton.dcu b/Game/Code/Menu/UMenuButton.dcu
new file mode 100644
index 00000000..b97d1670
--- /dev/null
+++ b/Game/Code/Menu/UMenuButton.dcu
Binary files differ
diff --git a/Game/Code/Menu/UMenuButton.pas b/Game/Code/Menu/UMenuButton.pas
new file mode 100644
index 00000000..e42a5488
--- /dev/null
+++ b/Game/Code/Menu/UMenuButton.pas
@@ -0,0 +1,238 @@
+unit UMenuButton;
+
+interface
+uses TextGL, UTexture, OpenGL12, UMenuText;
+
+type
+ TButton = class
+ private
+ SelectBool: Boolean;
+ 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
+// 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;
+
+ Selectable: boolean;
+
+ SelectColR: real;
+ SelectColG: real;
+ SelectColB: real;
+ SelectInt: real;
+ SelectTInt: real;
+
+ DeselectColR: real;
+ DeselectColG: real;
+ DeselectColB: real;
+ DeselectInt: real;
+ DeselectTInt: real;
+
+ procedure SetY(Value: real);
+ procedure SetSelect(Value: Boolean);
+ property X: real read Texture.x write Texture.x;
+ property Y: real read Texture.y write SetY;
+ property Z: real read Texture.z write Texture.z;
+ property W: real read Texture.w write Texture.w;
+ property H: real read Texture.h write Texture.h;
+ property Selected: Boolean read SelectBool write SetSelect;
+
+ procedure Draw;
+
+ constructor Create(Textura: TTexture); overload;
+ destructor Destroy; override;
+ end;
+
+implementation
+uses UDrawTexture, SysUtils;
+
+procedure TButton.SetY(Value: real);
+var
+ dY: real;
+ T: integer; // text
+begin
+ dY := Value - Texture.y;
+
+ Texture.y := Value;
+
+ for T := 0 to High(Text) do
+ Text[T].Y := Text[T].Y + dY;
+
+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;
+ 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;
+ 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;
+
+ // 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;
+
+
+end;
+
+// ***** Public methods ****** //
+
+procedure TButton.Draw;
+var
+ T: integer;
+begin
+ if Visible then begin
+ DrawTexture(Texture);
+
+ 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
+ with Texture do
+ begin
+ //Bind Tex and GL Attributes
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glDepthRange(0, 10);
+ glDepthFunc(GL_LEQUAL);
+ //glDepthFunc(GL_GEQUAL);
+ glEnable(GL_DEPTH_TEST);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ //glBlendFunc(GL_SRC_COLOR, GL_ZERO);
+ 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+ 15, 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 + 15, 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 + 15, 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 + 15, z);
+ glEnd;
+ 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;
+ Texture.ColR := 0;
+ Texture.ColG := 0.5;
+ Texture.ColB := 0;
+ Texture.Int := 1;
+end;
+
+
+end.
diff --git a/Game/Code/Menu/UMenuInteract.dcu b/Game/Code/Menu/UMenuInteract.dcu
new file mode 100644
index 00000000..785be771
--- /dev/null
+++ b/Game/Code/Menu/UMenuInteract.dcu
Binary files differ
diff --git a/Game/Code/Menu/UMenuInteract.pas b/Game/Code/Menu/UMenuInteract.pas
new file mode 100644
index 00000000..3f2960b8
--- /dev/null
+++ b/Game/Code/Menu/UMenuInteract.pas
@@ -0,0 +1,14 @@
+unit UMenuInteract;
+
+interface
+
+type
+ TInteract = record // for moving thru menu
+ Typ: integer; // 0 - button, 1 - select
+ Num: integer; // number of this item in proper list like buttons, selects
+ end;
+
+implementation
+
+end.
+ \ No newline at end of file
diff --git a/Game/Code/Menu/UMenuSelect.dcu b/Game/Code/Menu/UMenuSelect.dcu
new file mode 100644
index 00000000..9d483c33
--- /dev/null
+++ b/Game/Code/Menu/UMenuSelect.dcu
Binary files differ
diff --git a/Game/Code/Menu/UMenuSelect.pas b/Game/Code/Menu/UMenuSelect.pas
new file mode 100644
index 00000000..f7bb871f
--- /dev/null
+++ b/Game/Code/Menu/UMenuSelect.pas
@@ -0,0 +1,198 @@
+unit UMenuSelect;
+
+interface
+uses TextGL, UTexture, OpenGL12, UMenuText;
+
+type
+ PSelect = ^TSelect;
+ TSelect = class
+ private
+ SelectBool: boolean;
+ public
+ // objects
+ Text: TText; // Main Text
+ TextOpt: array of TText; // Options Text
+ Texture: TTexture; // Select Texture
+ TextureSBG: TTexture; // Background Selections Texture
+ TextureS: array of TTexture; // Selections Texture
+ SelectOptInt: integer;
+ PData: ^integer;
+
+ // for selection and deselection
+ // main static
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ Int: real;
+ DColR: real;
+ DColG: real;
+ DColB: real;
+ DInt: real;
+
+ // main text
+ TColR: real;
+ TColG: real;
+ TColB: real;
+ TInt: real;
+ TDColR: real;
+ TDColG: real;
+ TDColB: real;
+ TDInt: real;
+
+ // selection background static
+ SBGColR: real;
+ SBGColG: real;
+ SBGColB: real;
+ SBGInt: real;
+ SBGDColR: real;
+ SBGDColG: real;
+ SBGDColB: real;
+ SBGDInt: real;
+
+ // selection statics
+ SColR: real;
+ SColG: real;
+ SColB: real;
+ SInt: real;
+ SDColR: real;
+ SDColG: real;
+ SDColB: real;
+ SDInt: real;
+
+ // selection text
+ STColR: real;
+ STColG: real;
+ STColB: real;
+ STInt: real;
+ STDColR: real;
+ STDColG: real;
+ STDColB: real;
+ STDInt: real;
+
+ // position and size
+ property X: real read Texture.x write Texture.x;
+ property Y: real read Texture.y write Texture.y;
+ property W: real read Texture.w write Texture.w;
+ property H: real read Texture.h write Texture.h;
+// property X2: real read Texture2.x write Texture2.x;
+// property Y2: real read Texture2.y write Texture2.y;
+// property W2: real read Texture2.w write Texture2.w;
+// property H2: real read Texture2.h write Texture2.h;
+
+ // procedures
+ procedure SetSelect(Value: boolean);
+ property Selected: Boolean read SelectBool write SetSelect;
+ procedure SetSelectOpt(Value: integer);
+ property SelectedOption: integer read SelectOptInt write SetSelectOpt;
+ procedure Draw(ButtonAlpha: real);
+ constructor Create;
+ end;
+
+implementation
+uses UDrawTexture;
+
+// ------------ Select
+constructor TSelect.Create;
+begin
+ inherited Create;
+ Text := TText.Create;
+end;
+
+procedure TSelect.SetSelect(Value: boolean);
+var
+ SO: integer;
+begin // default 1, 0.4
+ SelectBool := Value;
+ if Value then begin
+ Texture.ColR := ColR;
+ Texture.ColG := ColG;
+ Texture.ColB := ColB;
+ Texture.Int := Int;
+
+ Text.ColR := TColR;
+ Text.ColG := TColG;
+ Text.ColB := TColB;
+ Text.Int := TInt;
+
+ TextureSBG.ColR := SBGColR;
+ TextureSBG.ColG := SBGColG;
+ TextureSBG.ColB := SBGColB;
+ TextureSBG.Int := SBGInt;
+
+{ for SO := 0 to High(TextOpt) do begin
+ if SelectOptInt = SO then begin
+ TextOpt[SO].ColR := STColR;
+ TextOpt[SO].ColG := STColG;
+ TextOpt[SO].ColB := STColB;
+ TextOpt[SO].Int := STInt;
+ end else begin
+ TextOpt[SO].ColR := STDColR;
+ TextOpt[SO].ColG := STDColG;
+ TextOpt[SO].ColB := STDColB;
+ TextOpt[SO].Int := STDInt;
+ end;
+ end;}
+
+ end else begin
+ Texture.ColR := DColR;
+ Texture.ColG := DColG;
+ Texture.ColB := DColB;
+ Texture.Int := DInt;
+
+ Text.ColR := TDColR;
+ Text.ColG := TDColG;
+ Text.ColB := TDColB;
+ Text.Int := TDInt;
+
+ TextureSBG.ColR := SBGDColR;
+ TextureSBG.ColG := SBGDColG;
+ TextureSBG.ColB := SBGDColB;
+ TextureSBG.Int := SBGDInt;
+
+{ for SO := 0 to High(TextOpt) do begin
+ TextOpt[SO].ColR := STDColR;
+ TextOpt[SO].ColG := STDColG;
+ TextOpt[SO].ColB := STDColB;
+ TextOpt[SO].Int := STDInt;
+ end;}
+ end;
+end;
+
+procedure TSelect.SetSelectOpt(Value: integer);
+var
+ SO: integer;
+begin
+ SelectOptInt := Value;
+ PData^ := Value;
+// SetSelect(true); // reset all colors
+
+ for SO := 0 to High(TextOpt) do begin
+ if SelectOptInt = SO then begin
+ TextOpt[SO].ColR := STColR;
+ TextOpt[SO].ColG := STColG;
+ TextOpt[SO].ColB := STColB;
+ TextOpt[SO].Int := STInt;
+ end else begin
+ TextOpt[SO].ColR := STDColR;
+ TextOpt[SO].ColG := STDColG;
+ TextOpt[SO].ColB := STDColB;
+ TextOpt[SO].Int := STDInt;
+ end;
+ end;
+end;
+
+procedure TSelect.Draw(ButtonAlpha: real);
+var
+ SO: integer;
+begin
+ DrawTexture(Texture);
+ DrawTexture(TextureSBG);
+
+ Text.Draw;
+
+ for SO := 0 to High(TextOpt) do begin
+ TextOpt[SO].Draw;
+ end;
+end;
+
+end.
diff --git a/Game/Code/Menu/UMenuSelectSlide.dcu b/Game/Code/Menu/UMenuSelectSlide.dcu
new file mode 100644
index 00000000..1475c1ac
--- /dev/null
+++ b/Game/Code/Menu/UMenuSelectSlide.dcu
Binary files differ
diff --git a/Game/Code/Menu/UMenuSelectSlide.pas b/Game/Code/Menu/UMenuSelectSlide.pas
new file mode 100644
index 00000000..7850cdf6
--- /dev/null
+++ b/Game/Code/Menu/UMenuSelectSlide.pas
@@ -0,0 +1,335 @@
+unit UMenuSelectSlide;
+
+interface
+uses TextGL, UTexture, OpenGL12, UMenuText;
+
+type
+ PSelectSlide = ^TSelectSlide;
+ TSelectSlide = class
+ private
+ SelectBool: boolean;
+ public
+ // objects
+ Text: TText; // Main text describing option
+ TextOpt: array of TText; // 3 texts in the position of possible options
+ TextOptT: array of string; // array of names for possible options
+
+ Texture: TTexture; // Select Texture
+ TextureSBG: TTexture; // Background Selections Texture
+// TextureS: array of TTexture; // Selections Texture (not used)
+
+// TextureArrowL: TTexture; // Texture for left arrow (not used yet)
+// TextureArrowR: TTexture; // Texture for right arrow (not used yet)
+
+ SelectOptInt: integer;
+ PData: ^integer;
+
+ //For automatically Setting LineCount
+ Lines: Byte;
+
+ //Visibility
+ Visible: Boolean;
+
+ // for selection and deselection
+ // main static
+ ColR: real;
+ ColG: real;
+ ColB: real;
+ Int: real;
+ DColR: real;
+ DColG: real;
+ DColB: real;
+ DInt: real;
+
+ // main text
+ TColR: real;
+ TColG: real;
+ TColB: real;
+ TInt: real;
+ TDColR: real;
+ TDColG: real;
+ TDColB: real;
+ TDInt: real;
+
+ // selection background static
+ SBGColR: real;
+ SBGColG: real;
+ SBGColB: real;
+ SBGInt: real;
+ SBGDColR: real;
+ SBGDColG: real;
+ SBGDColB: real;
+ SBGDInt: real;
+
+ // selection text
+ STColR: real;
+ STColG: real;
+ STColB: real;
+ STInt: real;
+ STDColR: real;
+ STDColG: real;
+ STDColB: real;
+ STDInt: real;
+
+ // position and size
+ property X: real read Texture.x write Texture.x;
+ property Y: real read Texture.y write Texture.y;
+ property W: real read Texture.w write Texture.w;
+ property H: real read Texture.h write Texture.h;
+// property X2: real read Texture2.x write Texture2.x;
+// property Y2: real read Texture2.y write Texture2.y;
+// property W2: real read Texture2.w write Texture2.w;
+// property H2: real read Texture2.h write Texture2.h;
+
+ // procedures
+ procedure SetSelect(Value: boolean);
+ property Selected: Boolean read SelectBool write SetSelect;
+ procedure SetSelectOpt(Value: integer);
+ property SelectedOption: integer read SelectOptInt write SetSelectOpt;
+ procedure Draw;
+ constructor Create;
+
+ //Automatically Generate Lines (Texts)
+ procedure genLines;
+ end;
+
+implementation
+uses UDrawTexture, math, ULog, SysUtils;
+
+// ------------ Select
+constructor TSelectSlide.Create;
+begin
+ inherited Create;
+ Text := TText.Create;
+ SetLength(TextOpt, 1);
+ TextOpt[0] := TText.Create;
+
+ Visible := True;
+ {SetLength(TextOpt, 3);
+ TextOpt[0] := TText.Create;
+ TextOpt[1] := TText.Create;
+ TextOpt[2] := TText.Create;}
+end;
+
+procedure TSelectSlide.SetSelect(Value: boolean);
+var
+ SO: integer;
+ I: integer;
+begin
+ SelectBool := Value;
+ if Value then begin
+ Texture.ColR := ColR;
+ Texture.ColG := ColG;
+ Texture.ColB := ColB;
+ Texture.Int := Int;
+
+ Text.ColR := TColR;
+ Text.ColG := TColG;
+ Text.ColB := TColB;
+ Text.Int := TInt;
+
+ TextureSBG.ColR := SBGColR;
+ TextureSBG.ColG := SBGColG;
+ TextureSBG.ColB := SBGColB;
+ TextureSBG.Int := SBGInt;
+
+{ for I := 0 to High(TextOpt) do begin
+ TextOpt[I].ColR := STColR;
+ TextOpt[I].ColG := STColG;
+ TextOpt[I].ColB := STColB;
+ TextOpt[I].Int := STInt;
+ end;}
+
+ end else begin
+ Texture.ColR := DColR;
+ Texture.ColG := DColG;
+ Texture.ColB := DColB;
+ Texture.Int := DInt;
+
+ Text.ColR := TDColR;
+ Text.ColG := TDColG;
+ Text.ColB := TDColB;
+ Text.Int := TDInt;
+
+ TextureSBG.ColR := SBGDColR;
+ TextureSBG.ColG := SBGDColG;
+ TextureSBG.ColB := SBGDColB;
+ TextureSBG.Int := SBGDInt;
+
+{ for I := 0 to High(TextOpt) do begin
+ TextOpt[I].ColR := STDColR;
+ TextOpt[I].ColG := STDColG;
+ TextOpt[I].ColB := STDColB;
+ TextOpt[I].Int := STDInt;
+ end;}
+ end;
+end;
+
+procedure TSelectSlide.SetSelectOpt(Value: integer);
+var
+ SO: integer;
+ Sel: integer;
+ HalfL: integer;
+ HalfR: integer;
+
+procedure DoSelection(Sel: Cardinal);
+ var I: Integer;
+ begin
+ for I := low(TextOpt) to high(TextOpt) do
+ begin
+ TextOpt[I].ColR := STDColR;
+ TextOpt[I].ColG := STDColG;
+ TextOpt[I].ColB := STDColB;
+ TextOpt[I].Int := STDInt;
+ end;
+ if (Sel <= high(TextOpt)) then
+ begin
+ TextOpt[Sel].ColR := STColR;
+ TextOpt[Sel].ColG := STColG;
+ TextOpt[Sel].ColB := STColB;
+ TextOpt[Sel].Int := STInt;
+ end;
+ end;
+begin
+ SelectOptInt := Value;
+ PData^ := Value;
+// SetSelect(true); // reset all colors
+
+ if (Length(TextOpt)>0) AND (Length(TextOptT)>0) then
+ begin
+
+ if (Value <= 0) then
+ begin //First Option Selected
+ Value := 0;
+
+ for SO := low (TextOpt) to high(TextOpt) do
+ begin
+ TextOpt[SO].Text := TextOptT[SO];
+ end;
+
+ DoSelection(0);
+ end
+ else if (Value >= high(TextOptT)) then
+ begin //Last Option Selected
+ Value := high(TextOptT);
+
+ for SO := high(TextOpt) downto low (TextOpt) do
+ begin
+ TextOpt[SO].Text := TextOptT[high(TextOptT)-(Lines-SO-1)];
+ end;
+ DoSelection(Lines-1);
+ end
+ else
+ begin
+ HalfL := Ceil((Lines-1)/2);
+ HalfR := Lines-1-HalfL;
+
+ if (Value <= HalfL) then
+ begin //Selected Option is near to the left side
+ {HalfL := Value;
+ HalfR := Lines-1-HalfL;}
+ //Change Texts
+ for SO := low (TextOpt) to high(TextOpt) do
+ begin
+ TextOpt[SO].Text := TextOptT[SO];
+ end;
+
+ DoSelection(Value);
+ end
+ else if (Value > High(TextOptT)-HalfR) then
+ begin //Selected is too near to the right border
+ HalfR := high(TextOptT) - Value;
+ HalfL := Lines-1-HalfR;
+ //Change Texts
+ for SO := high(TextOpt) downto low (TextOpt) do
+ begin
+ TextOpt[SO].Text := TextOptT[high(TextOptT)-(Lines-SO-1)];
+ end;
+
+ DoSelection (HalfL);
+ end
+ else
+ begin
+ //Change Texts
+ for SO := low (TextOpt) to high(TextOpt) do
+ begin
+ TextOpt[SO].Text := TextOptT[Value - HalfL + SO];
+ end;
+
+ DoSelection(HalfL);
+ end;
+
+ end;
+
+ end;
+
+end;
+
+procedure TSelectSlide.Draw;
+var
+ SO: integer;
+begin
+ if Visible then
+ begin
+ DrawTexture(Texture);
+ DrawTexture(TextureSBG);
+
+ Text.Draw;
+
+ for SO := low(TextOpt) to high(TextOpt) do
+ TextOpt[SO].Draw;
+ end;
+end;
+
+procedure TSelectSlide.GenLines;
+var
+maxlength: Real;
+I: Integer;
+begin
+ SetFontStyle(TextOpt[0].Style);
+ SetFontSize(TextOpt[0].Size);
+ maxlength := 0;
+
+ for I := low(TextOptT) to high (TextOptT) do
+ begin
+ if (glTextWidth(PChar(TextOptT[I])) > maxlength) then
+ maxlength := glTextWidth(PChar(TextOptT[I]));
+ end;
+
+ Lines := floor((TextureSBG.W-40) / (maxlength+7));
+ if (Lines > Length(TextOptT)) then
+ Lines := Length(TextOptT);
+
+ if (Lines <= 0) then
+ Lines := 1;
+
+ setLength (TextOpt, Lines);
+
+ for I := low(TextOpt) to high(TextOpt) do
+ begin
+
+ //TextOpt[I] := TextOpt[0];
+ TextOpt[I] := TText.Create;
+ TextOpt[I].Size := 10;
+ //TextOpt[I].Align := 1;
+ TextOpt[I].Align := 0;
+ TextOpt[I].Visible := True;
+
+ TextOpt[I].ColR := STDColR;
+ TextOpt[I].ColG := STDColG;
+ TextOpt[I].ColB := STDColB;
+ TextOpt[I].Int := STDInt;
+
+ //Generate Positions
+ //TextOpt[I].X := TextureSBG.X + 20 + (TextureSBG.W / Lines) * (I + 0.5);
+ TextOpt[I].X := TextureSBG.X + 20 + (TextureSBG.W / Lines) * I;
+ TextOpt[I].Y := TextureSBG.Y + 20;
+
+ //Better Look with 2 Options
+ if (Lines=2) then
+ TextOpt[I].X := TextureSBG.X + 20 + (TextureSBG.W -40 - glTextWidth(PChar(TextOptT[1]))) * I;
+ end;
+ //TextOpt[I] := TextOpt[0];
+end;
+
+end.
diff --git a/Game/Code/Menu/UMenuStatic.dcu b/Game/Code/Menu/UMenuStatic.dcu
new file mode 100644
index 00000000..901fa2c7
--- /dev/null
+++ b/Game/Code/Menu/UMenuStatic.dcu
Binary files differ
diff --git a/Game/Code/Menu/UMenuStatic.pas b/Game/Code/Menu/UMenuStatic.pas
new file mode 100644
index 00000000..4b10e54c
--- /dev/null
+++ b/Game/Code/Menu/UMenuStatic.pas
@@ -0,0 +1,32 @@
+unit UMenuStatic;
+
+interface
+uses UTexture, OpenGL12;
+
+type
+ TStatic = class
+ public
+ Texture: TTexture; // Button Screen position and size
+ Visible: boolean;
+ procedure Draw;
+ constructor Create(Textura: TTexture); overload;
+ end;
+
+implementation
+uses UDrawTexture;
+
+procedure TStatic.Draw;
+var
+ Pet: integer;
+begin
+ if Visible then
+ DrawTexture(Texture);
+end;
+
+constructor TStatic.Create(Textura: TTexture);
+begin
+ inherited Create;
+ Texture := Textura;
+end;
+
+end.
diff --git a/Game/Code/Menu/UMenuText.dcu b/Game/Code/Menu/UMenuText.dcu
new file mode 100644
index 00000000..7cfe0316
--- /dev/null
+++ b/Game/Code/Menu/UMenuText.dcu
Binary files differ
diff --git a/Game/Code/Menu/UMenuText.pas b/Game/Code/Menu/UMenuText.pas
new file mode 100644
index 00000000..5c435a18
--- /dev/null
+++ b/Game/Code/Menu/UMenuText.pas
@@ -0,0 +1,96 @@
+unit UMenuText;
+
+interface
+uses TextGL, UTexture, OpenGL12, SysUtils;
+
+type
+ TText = class
+ private
+ SelectBool: boolean;
+ public
+ X: real;
+ Y: real;
+// W: real; // if text is wider than W then it is streched (not yet implemented)
+// H: real;
+ Size: real;
+ Text: string;
+ ColR: real;
+ ColG: real;
+ ColB: 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 Draw;
+ constructor Create; overload;
+ constructor Create(X, Y: real; Tekst: string); overload;
+ constructor Create(ParX, ParY: real; ParStyle: integer; ParSize, ParColR, ParColG, ParColB: real; ParAlign: integer; ParTekst: string); overload;
+ end;
+
+implementation
+uses UGraphic;
+
+procedure TText.SetSelect(Value: Boolean);
+begin
+ SelectBool := Value;
+end;
+
+procedure TText.Draw;
+var
+ X2: real;
+ Text2: string;
+begin
+ if Visible then begin
+ SetFontStyle(Style);
+ SetFontSize(Size);
+ glColor3f(ColR*Int, ColG*Int, ColB*Int);
+ if not SelectBool 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;
+end;
+
+constructor TText.Create;
+begin
+ Create(0, 0, '');
+end;
+
+constructor TText.Create(X, Y: real; Tekst: string);
+begin
+ Create(X, Y, 0, 10, 0, 0, 0, 0, Tekst);
+end;
+
+constructor TText.Create(ParX, ParY: real; ParStyle: integer; ParSize, ParColR, ParColG, ParColB: real; ParAlign: integer; ParTekst: string);
+begin
+ inherited Create;
+ X := ParX;
+ Y := ParY;
+ 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/SMpeg/USmpeg.alt.pas b/Game/Code/SMpeg/USmpeg.alt.pas
new file mode 100644
index 00000000..94ad69c8
--- /dev/null
+++ b/Game/Code/SMpeg/USmpeg.alt.pas
@@ -0,0 +1,292 @@
+unit USmpeg;
+
+interface
+uses SDL, smpeg, OpenGL12, SysUtils, UIni;
+
+procedure OpenSmpeg(FileName: string);
+procedure SkipSmpeg(Time: single);
+procedure PlaySmpeg;
+procedure UpdateSmpeg;
+procedure CloseSmpeg;
+function glmovie_init(Width : GLuint; Height : TGLuint ) : TGLenum;
+procedure glmpeg_update(surface: PSDL_Surface; x: Sint32; y: Sint32; w: Uint32; h: Uint32); cdecl;
+procedure DrawSmpeg(frame: PGLubyte);
+procedure glmovie_resize( width : GLuint; height : GLuint );
+procedure glmovie_quit;
+
+var
+ mpeg: PSMPEG;
+ mpeg_info: TSMPEG_Info;
+ surface: PSDL_Surface;
+
+type
+ { Some data is redundant at this stage. }
+ PGLMovieTexture = ^TGLMovieTexture;
+ TGLMovieTexture = record
+ id : TGLuint; (* OpenGL texture id. *)
+ poly_width : TGLuint; (* Quad width for tile. *)
+ poly_height : TGLuint; (* Quad height for tile. *)
+ movie_width : TGLuint; (* Width of movie inside tile. *)
+ movie_height : TGLuint; (* Height of movie inside tile. *)
+ skip_rows : TGLuint; (* Number of rows of movie to skip *)
+ skip_pixels : TGLuint; (* Number of columns of movie to skip *)
+ row : TGLuint; (* Row number of tile in scheme. *)
+ col : TGLuint; (* Column number of tile in scheme. *)
+ end;
+
+type
+ TGLuintArray = array of TGLuint;
+ PGLuintArray = ^TGLuintArray;
+ TGLMovieTextureArray = array of TGLMovieTexture;
+ PGLMovieTextureArray = ^TGLMovieTextureArray;
+
+var
+ (* Our evil maximum texture size. Boo 3Dfxnot *)
+ texture_size : TGLuint = 1024;//512;
+ texture_ids : TGLuint;
+ textures: TGLMovieTexture;
+ tiled_width : TGLuint = 0;
+ tiled_height : TGLuint = 0;
+ movie_width : TGLuint = 0;
+ movie_height : TGLuint = 0;
+
+implementation
+
+procedure OpenSmpeg(FileName: string);
+begin
+ mpeg := SMPEG_new(PChar(FileName), @mpeg_info, 0); // audio
+ if ( mpeg = nil ) then begin
+ SDL_Quit;
+ Exit;
+ end;
+
+// SMPEG_setvolume(mpeg, 50);
+ SMPEG_enableaudio(mpeg, 0);
+
+ (* Everything needs to be in RGB for GL, but needs to be 32-bit for SMPEG. *)
+ surface := SDL_AllocSurface( SDL_SWSURFACE,
+ mpeg_info.width,
+ mpeg_info.height,
+ 32,
+ $000000FF,
+ $0000FF00,
+ $00FF0000,
+ $FF000000 );
+
+ if ( surface = nil ) then begin
+ SDL_Quit;
+ Exit;
+ end;
+
+ (* *Initialize* with mpeg size. *)
+ if (glmovie_init( mpeg_info.width, mpeg_info.height ) <> GL_NO_ERROR ) then begin
+ SDL_Quit;
+ Exit;
+ end;
+
+ SMPEG_setdisplay(mpeg, surface, nil, @glmpeg_update);
+end;
+
+procedure SkipSmpeg(Time: single);
+begin
+ SMPEG_skip(mpeg, Time);
+end;
+
+procedure PlaySmpeg;
+begin
+ SMPEG_play(mpeg);
+end;
+
+procedure UpdateSmpeg;
+begin
+// glmpeg_update(surface,0,0,0,0);
+ DrawSmpeg( PGLubyte( surface.pixels ) );
+end;
+
+procedure CloseSmpeg;
+begin
+// glmovie_quit;
+ SMPEG_delete(mpeg);
+end;
+
+function glmovie_init( Width : GLuint; Height : TGLuint ) : TGLenum;
+type
+ PGLubyteArray = ^TGLubyteArray;
+ TGLubyteArray = array of TGLubyte;
+var
+ (* Initial black texels. *)
+ pixels : TGLubyteArray;
+ (* Absolute offsets from within tiled frame. *)
+ //offset_x: GLuint;
+ //offset_y: GLuint;
+ skip_rows : GLuint;
+ skip_pixels : GLuint;
+ i, j, current : GLuint;
+begin
+ skip_rows := 0;
+ current := 0;
+ (* Save original movie dimensions. *)
+ movie_width := width;
+ movie_height := height;
+
+ (* Get the power of 2 dimensions. *)
+ tiled_width := 1024{512};
+ tiled_height := 1024{512};
+
+ texture_size := 1024{512};
+
+ (* Time for fun with data type = record *)
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_DITHER);
+
+ glGenTextures(1, @texture_ids);
+
+ current := 0;
+ (* Setup texture. *)
+ textures.id := texture_ids;
+ textures.poly_width := texture_size;
+ textures.poly_height := texture_size;
+ textures.movie_width := movie_width - 2;
+ textures.movie_height := movie_height - 2;
+ textures.row := i;
+ textures.col := j;
+ textures.skip_pixels := skip_pixels;
+ textures.skip_rows := skip_rows;
+
+ SetLength( pixels, textures.poly_width * textures.poly_height * 4 );
+ if ( pixels = nil ) then
+ begin
+ glDeleteTextures(1, @texture_ids);
+ result := GL_OUT_OF_MEMORY;
+ exit;
+ end;
+ //FillChar( pixels^, textures[ current ].poly_width * textures[ current ].poly_height * 4, 0 );
+
+ (* Do all of our useful binding. *)
+ glBindTexture(GL_TEXTURE_2D, texture_ids);
+// glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ (* Specify our 256x256 black texture. *)
+ glTexImage2D( GL_TEXTURE_2D,
+ 0,
+ GL_RGB,
+ 1024{512},//textures.poly_width,
+ 1024{512},//textures.poly_height,
+ 0,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ @pixels[0] );
+ SetLength( pixels, 0 );
+
+
+ (* Simple state setup at the end. *)
+ result := glGetError( );
+end;
+
+procedure glmpeg_update( surface : PSDL_Surface; x : Sint32; y : Sint32; w : Uint32;
+ h : Uint32 ); cdecl;
+var
+ error : TGLenum;
+begin
+ glClear( GL_COLOR_BUFFER_BIT );
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity;
+ DrawSmpeg( PGLubyte( surface.pixels ) );
+ error := glGetError( );
+ if ( error <> GL_NO_ERROR ) then Exit;
+ SDL_GL_SwapBuffers;
+end;
+
+procedure DrawSmpeg(frame: PGLubyte);
+var
+ Shift: TGLdouble;
+ CropT: real;
+ CropB: real;
+ TexT: real;
+ TexB: real;
+ TexL: real;
+ TexR: real;
+ Wide: boolean;
+begin
+ (* full screen mpeg *)
+{ CropT := 0;
+ CropB := 600;
+ TexT := 0;
+ TexB := 1;
+ TexL := 0;
+ TexW := 1;}
+
+ // set movie texture crop
+ Wide := false;
+ if (textures.movie_width = 720-2) and (textures.movie_height = 344-2) then begin
+ TexT := 0;
+ TexB := 342/1024;
+ Wide := true;
+ end;
+ if textures.movie_height = 304-2 then begin
+ TexT := 0;
+ TexB := 304/1024;
+ Wide := true;
+ end;
+ if textures.movie_height = 152-2 then begin
+ TexT := 0;
+ TexB := 152/1024;
+ Wide := true;
+ end;
+
+ CropT := 110; // (110/800 = 13,75% max crop)
+ CropB := 490; // (110/800 = 13,75% max crop)
+
+ if (textures.movie_height <> 304-2) and (textures.movie_height <> 152-2) and (textures.movie_height <> 344-2) then begin
+ TexT := 110 / 600 * (textures.movie_height / 1024{512});
+ TexB := 490 / 600 * (textures.movie_height / 1024{512});
+
+ if Ini.MovieSize = 1 then begin
+ // full screen size
+ CropT := 0;
+ CropB := 600;
+ TexT := 0;
+ TexB := textures.movie_height / 1024{512};
+ end;
+ end;
+
+ TexL := {10}0/600 * (textures.movie_width / 1024{512});
+ TexR := {590}600/600 * (textures.movie_width / 1024{512});
+
+ glEnable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+ glColor3f(1, 1, 1);
+ glBindTexture( GL_TEXTURE_2D, texture_ids );
+// glPixelStorei( GL_UNPACK_ROW_LENGTH, movie_width );
+ glPixelStorei( GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0);
+ glTexSubImage2D( GL_TEXTURE_2D, 0, 0, (* offset_x *) 0, (* offset_y *) textures.movie_width + 2, textures.movie_height + 2, GL_RGBA, GL_UNSIGNED_BYTE, frame );
+
+ // draw
+ glBegin( GL_QUADS );
+ glTexCoord2f(TexL, TexT); glVertex2f(0, CropT);
+ glTexCoord2f(TexL, TexB); glVertex2f(0, CropB);
+ glTexCoord2f(TexR, TexB); glVertex2f(800, CropB);
+ glTexCoord2f(TexR, TexT); glVertex2f(800, CropT);
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+end;
+
+procedure glmovie_resize( width : GLuint; height : GLuint );
+begin
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity;
+ gluOrtho2D(0, 800, 600, 0);
+end;
+
+procedure glmovie_quit;
+begin
+ glDeleteTextures(1, @texture_ids);
+end;
+
+end.
diff --git a/Game/Code/SMpeg/USmpeg.dcu b/Game/Code/SMpeg/USmpeg.dcu
new file mode 100644
index 00000000..d31948ea
--- /dev/null
+++ b/Game/Code/SMpeg/USmpeg.dcu
Binary files differ
diff --git a/Game/Code/SMpeg/USmpeg.pas b/Game/Code/SMpeg/USmpeg.pas
new file mode 100644
index 00000000..c7f756db
--- /dev/null
+++ b/Game/Code/SMpeg/USmpeg.pas
@@ -0,0 +1,299 @@
+unit USmpeg;
+
+interface
+uses SDL, smpeg, OpenGL12, SysUtils, UIni;
+
+procedure OpenSmpeg(FileName: string);
+procedure SkipSmpeg(Time: single);
+procedure PlaySmpeg;
+procedure PauseSmpeg; //PauseMod
+procedure UpdateSmpeg;
+procedure CloseSmpeg;
+function glmovie_init(Width : GLuint; Height : TGLuint ) : TGLenum;
+procedure glmpeg_update(surface: PSDL_Surface; x: Sint32; y: Sint32; w: Uint32; h: Uint32); cdecl;
+procedure DrawSmpeg(frame: PGLubyte);
+procedure glmovie_resize( width : GLuint; height : GLuint );
+procedure glmovie_quit;
+
+var
+ mpeg: PSMPEG;
+ mpeg_info: TSMPEG_Info;
+ surface: PSDL_Surface;
+
+type
+ { Some data is redundant at this stage. }
+ PGLMovieTexture = ^TGLMovieTexture;
+ TGLMovieTexture = record
+ id : TGLuint; (* OpenGL texture id. *)
+ poly_width : TGLuint; (* Quad width for tile. *)
+ poly_height : TGLuint; (* Quad height for tile. *)
+ movie_width : TGLuint; (* Width of movie inside tile. *)
+ movie_height : TGLuint; (* Height of movie inside tile. *)
+ skip_rows : TGLuint; (* Number of rows of movie to skip *)
+ skip_pixels : TGLuint; (* Number of columns of movie to skip *)
+ row : TGLuint; (* Row number of tile in scheme. *)
+ col : TGLuint; (* Column number of tile in scheme. *)
+ end;
+
+type
+ TGLuintArray = array of TGLuint;
+ PGLuintArray = ^TGLuintArray;
+ TGLMovieTextureArray = array of TGLMovieTexture;
+ PGLMovieTextureArray = ^TGLMovieTextureArray;
+
+var
+ (* Our evil maximum texture size. Boo 3Dfxnot *)
+ texture_size : TGLuint = 1024;//512;
+ texture_ids : TGLuint;
+ textures: TGLMovieTexture;
+ tiled_width : TGLuint = 0;
+ tiled_height : TGLuint = 0;
+ movie_width : TGLuint = 0;
+ movie_height : TGLuint = 0;
+
+implementation
+
+procedure OpenSmpeg(FileName: string);
+begin
+ mpeg := SMPEG_new(PChar(FileName), @mpeg_info, 0); // audio
+ if ( mpeg = nil ) then begin
+ SDL_Quit;
+ Exit;
+ end;
+
+// SMPEG_setvolume(mpeg, 50);
+ SMPEG_enableaudio(mpeg, 0);
+
+ (* Everything needs to be in RGB for GL, but needs to be 32-bit for SMPEG. *)
+ surface := SDL_AllocSurface( SDL_SWSURFACE,
+ mpeg_info.width,
+ mpeg_info.height,
+ 32,
+ $000000FF,
+ $0000FF00,
+ $00FF0000,
+ $FF000000 );
+
+ if ( surface = nil ) then begin
+ SDL_Quit;
+ Exit;
+ end;
+
+ (* *Initialize* with mpeg size. *)
+ if (glmovie_init( mpeg_info.width, mpeg_info.height ) <> GL_NO_ERROR ) then begin
+ SDL_Quit;
+ Exit;
+ end;
+
+ SMPEG_setdisplay(mpeg, surface, nil, @glmpeg_update);
+end;
+
+procedure SkipSmpeg(Time: single);
+begin
+ SMPEG_skip(mpeg, Time);
+end;
+
+procedure PlaySmpeg;
+begin
+ SMPEG_play(mpeg);
+end;
+
+//Pause Mod
+procedure PauseSmpeg;
+begin
+ SMPEG_pause(mpeg);
+end;
+
+procedure UpdateSmpeg;
+begin
+// glmpeg_update(surface,0,0,0,0);
+ DrawSmpeg( PGLubyte( surface.pixels ) );
+end;
+
+procedure CloseSmpeg;
+begin
+// glmovie_quit;
+ SMPEG_delete(mpeg);
+end;
+
+function glmovie_init( Width : GLuint; Height : TGLuint ) : TGLenum;
+type
+ PGLubyteArray = ^TGLubyteArray;
+ TGLubyteArray = array of TGLubyte;
+var
+ (* Initial black texels. *)
+ pixels : TGLubyteArray;
+ (* Absolute offsets from within tiled frame. *)
+ //offset_x: GLuint;
+ //offset_y: GLuint;
+ skip_rows : GLuint;
+ skip_pixels : GLuint;
+ i, j, current : GLuint;
+begin
+ skip_rows := 0;
+ current := 0;
+ (* Save original movie dimensions. *)
+ movie_width := width;
+ movie_height := height;
+
+ (* Get the power of 2 dimensions. *)
+ tiled_width := 1024{512};
+ tiled_height := 1024{512};
+
+ texture_size := 1024{512};
+
+ (* Time for fun with data type = record *)
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_DITHER);
+
+ glGenTextures(1, @texture_ids);
+
+ current := 0;
+ (* Setup texture. *)
+ textures.id := texture_ids;
+ textures.poly_width := texture_size;
+ textures.poly_height := texture_size;
+ textures.movie_width := movie_width - 2;
+ textures.movie_height := movie_height - 2;
+ textures.row := i;
+ textures.col := j;
+ textures.skip_pixels := skip_pixels;
+ textures.skip_rows := skip_rows;
+
+ SetLength( pixels, textures.poly_width * textures.poly_height * 4 );
+ if ( pixels = nil ) then
+ begin
+ glDeleteTextures(1, @texture_ids);
+ result := GL_OUT_OF_MEMORY;
+ exit;
+ end;
+ //FillChar( pixels^, textures[ current ].poly_width * textures[ current ].poly_height * 4, 0 );
+
+ (* Do all of our useful binding. *)
+ glBindTexture(GL_TEXTURE_2D, texture_ids);
+// glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ (* Specify our 256x256 black texture. *)
+ glTexImage2D( GL_TEXTURE_2D,
+ 0,
+ GL_RGB,
+ 1024{512},//textures.poly_width,
+ 1024{512},//textures.poly_height,
+ 0,
+ GL_RGBA,
+ GL_UNSIGNED_BYTE,
+ @pixels[0] );
+ SetLength( pixels, 0 );
+
+
+ (* Simple state setup at the end. *)
+ result := glGetError( );
+end;
+
+procedure glmpeg_update( surface : PSDL_Surface; x : Sint32; y : Sint32; w : Uint32;
+ h : Uint32 ); cdecl;
+var
+ error : TGLenum;
+begin
+ glClear( GL_COLOR_BUFFER_BIT );
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity;
+ DrawSmpeg( PGLubyte( surface.pixels ) );
+ error := glGetError( );
+ if ( error <> GL_NO_ERROR ) then Exit;
+ SDL_GL_SwapBuffers;
+end;
+
+procedure DrawSmpeg(frame: PGLubyte);
+var
+ Shift: TGLdouble;
+ CropT: real;
+ CropB: real;
+ TexT: real;
+ TexB: real;
+ TexL: real;
+ TexR: real;
+ Wide: boolean;
+begin
+ (* full screen mpeg *)
+{ CropT := 0;
+ CropB := 600;
+ TexT := 0;
+ TexB := 1;
+ TexL := 0;
+ TexW := 1;}
+
+ // set movie texture crop
+ Wide := false;
+ if (textures.movie_width = 720-2) and (textures.movie_height = 344-2) then begin
+ TexT := 0;
+ TexB := 342/1024;
+ Wide := true;
+ end;
+ if textures.movie_height = 304-2 then begin
+ TexT := 0;
+ TexB := 304/1024;
+ Wide := true;
+ end;
+ if textures.movie_height = 152-2 then begin
+ TexT := 0;
+ TexB := 152/1024;
+ Wide := true;
+ end;
+
+ CropT := 110; // (110/800 = 13,75% max crop)
+ CropB := 490; // (110/800 = 13,75% max crop)
+
+ if (textures.movie_height <> 304-2) and (textures.movie_height <> 152-2) and (textures.movie_height <> 344-2) then begin
+ TexT := 110 / 600 * (textures.movie_height / 1024{512});
+ TexB := 490 / 600 * (textures.movie_height / 1024{512});
+
+ if Ini.MovieSize = 1 then begin
+ // full screen size
+ CropT := 0;
+ CropB := 600;
+ TexT := 0;
+ TexB := textures.movie_height / 1024{512};
+ end;
+ end;
+
+ TexL := {10}0/600 * (textures.movie_width / 1024{512});
+ TexR := {590}600/600 * (textures.movie_width / 1024{512});
+
+ glEnable(GL_TEXTURE_2D);
+ glDisable(GL_BLEND);
+ glColor3f(1, 1, 1);
+ glBindTexture( GL_TEXTURE_2D, texture_ids );
+// glPixelStorei( GL_UNPACK_ROW_LENGTH, movie_width );
+ glPixelStorei( GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0);
+ glTexSubImage2D( GL_TEXTURE_2D, 0, 0, (* offset_x *) 0, (* offset_y *) textures.movie_width + 2, textures.movie_height + 2, GL_RGBA, GL_UNSIGNED_BYTE, frame );
+
+ // draw
+ glBegin( GL_QUADS );
+ glTexCoord2f(TexL, TexT); glVertex2f(0, CropT);
+ glTexCoord2f(TexL, TexB); glVertex2f(0, CropB);
+ glTexCoord2f(TexR, TexB); glVertex2f(800, CropB);
+ glTexCoord2f(TexR, TexT); glVertex2f(800, CropT);
+ glEnd;
+ glDisable(GL_TEXTURE_2D);
+end;
+
+procedure glmovie_resize( width : GLuint; height : GLuint );
+begin
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity;
+ gluOrtho2D(0, 800, 600, 0);
+end;
+
+procedure glmovie_quit;
+begin
+ glDeleteTextures(1, @texture_ids);
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenEdit.dcu b/Game/Code/Screens/UScreenEdit.dcu
new file mode 100644
index 00000000..1b9c7bb9
--- /dev/null
+++ b/Game/Code/Screens/UScreenEdit.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenEdit.pas b/Game/Code/Screens/UScreenEdit.pas
new file mode 100644
index 00000000..aa3301a7
--- /dev/null
+++ b/Game/Code/Screens/UScreenEdit.pas
@@ -0,0 +1,104 @@
+unit UScreenEdit;
+
+interface
+
+uses UMenu, SDL, UThemes;
+
+type
+ TScreenEdit = class(TMenu)
+ public
+{ Tex_Background: TTexture;
+ FadeOut: boolean;
+ Path: string;
+ FileName: string;}
+ constructor Create(Back: String); override;
+ procedure onShow; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+{ function Draw: boolean; override;
+ procedure Finish;}
+ end;
+
+implementation
+
+uses UGraphic, UMusic, USkins;
+
+function TScreenEdit.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_ESCAPE :
+ begin
+ Music.PlayBack;
+ FadeTo(@ScreenMain);
+// Result := false;
+ end;
+ SDLK_RETURN:
+ begin
+ if Interaction = 0 then begin
+ Music.PlayStart;
+ FadeTo(@ScreenEditConvert);
+ end;
+// if Interaction = 1 then begin
+// Music.PlayStart;
+// FadeTo(@ScreenEditHeader);
+// end;
+
+ if Interaction = 1 then begin
+ Music.PlayBack;
+ FadeTo(@ScreenMain);
+ end;
+ end;
+
+ SDLK_DOWN:
+ begin
+ InteractNext;
+ end;
+ SDLK_UP:
+ begin
+ InteractPrev;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenEdit.Create(Back: String);
+begin
+ inherited Create(Back);
+ AddButton(400-200, 100 + 0*70, 400, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(10, 5, 0, 0, 0, 'Convert Midi to Txt');
+// Button[High(Button)].Text[0].Size := 11;
+
+// AddButton(400-200, 100 + 1*60, 400, 40, 'ButtonF');
+// AddButtonText(10, 5, 0, 0, 0, 'Edit Headers');
+
+// AddButton(400-200, 100 + 2*60, 400, 40, 'ButtonF');
+// AddButtonText(10, 5, 0, 0, 0, 'Set GAP');
+
+ AddButton(400-200, 100 + 3*60, 400, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(10, 5, 0, 0, 0, 'Exit');
+
+end;
+
+procedure TScreenEdit.onShow;
+begin
+// Interaction := 0;
+end;
+
+(*function TScreenEdit.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ Pet: integer;
+ AktBeat: integer;
+begin
+end;
+
+procedure TScreenEdit.Finish;
+begin
+//
+end;*)
+
+end.
diff --git a/Game/Code/Screens/UScreenEditConvert.dcu b/Game/Code/Screens/UScreenEditConvert.dcu
new file mode 100644
index 00000000..1839ad6b
--- /dev/null
+++ b/Game/Code/Screens/UScreenEditConvert.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenEditConvert.pas b/Game/Code/Screens/UScreenEditConvert.pas
new file mode 100644
index 00000000..68742535
--- /dev/null
+++ b/Game/Code/Screens/UScreenEditConvert.pas
@@ -0,0 +1,500 @@
+unit UScreenEditConvert;
+
+interface
+
+uses UMenu, SDL, MidiFile, MidiOut, ULog, USongs, UMusic, UThemes;
+
+type
+ TNote = record
+ Event: integer;
+ EventType: integer;
+ Channel: integer;
+ Start: real;
+ Len: real;
+ Data1: integer;
+ Data2: integer;
+ Str: string;
+ end;
+
+ TTrack = record
+ Note: array of TNote;
+ Name: string;
+ Hear: boolean;
+ Status: byte; // 0 - none, 1 - notes, 2 - lyrics, 3 - notes + lyrics
+ end;
+
+ TNuta = record
+ Start: integer;
+ Len: integer;
+ Tone: integer;
+ Lyric: string;
+ NewSentence: boolean;
+ end;
+
+ TArrayTrack = array of TTrack;
+
+ TScreenEditConvert = class(TMenu)
+ public
+ ATrack: TArrayTrack; // actual track
+// Track: TArrayTrack;
+ Channel: TArrayTrack;
+ ColR: array[0..100] of real;
+ ColG: array[0..100] of real;
+ ColB: array[0..100] of real;
+ Len: real;
+ Sel: integer;
+ Selected: boolean;
+// FileName: string;
+ MidiFile: TMidiFile;
+ MidiTrack: TMidiTrack;
+ MidiEvent: pMidiEvent;
+ MidiOut: TMidiOutput;
+ Song: TSong;
+ Czesc: TCzesci;
+ BPM: real;
+ Ticks: real;
+ Nuta: array of TNuta;
+ procedure AddLyric(Start: integer; Tekst: string);
+ procedure Extract;
+ procedure MidiFile1MidiEvent(event: PMidiEvent);
+ function SelectedNumber: integer;
+ constructor Create(Back: String); override;
+ procedure onShow; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+ procedure onHide; override;
+ end;
+
+implementation
+uses UGraphic, SysUtils, UDrawTexture, TextGL, UPliki, UMain, UIni, OpenGL, USkins;
+
+function TScreenEditConvert.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+var
+ T: integer;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+
+ SDLK_ESCAPE:
+ begin
+ MidiFile.StopPlaying;
+ Music.PlayBack;
+ FadeTo(@ScreenEdit);
+ end;
+
+ SDLK_RETURN:
+ begin
+ if Interaction = 0 then begin
+ Music.PlayStart;
+ ScreenOpen.BackScreen := @ScreenEditConvert;
+ FadeTo(@ScreenOpen);
+ end;
+
+ if Interaction = 1 then begin
+ Selected := false;
+ MidiFile.OnMidiEvent := MidiFile1MidiEvent;
+// MidiFile.GoToTime(MidiFile.GetTrackLength div 2);
+ MidiFile.StartPlaying;
+ end;
+
+ if Interaction = 2 then begin
+ Selected := true;
+ MidiFile.OnMidiEvent := nil;
+ {for T := 0 to High(ATrack) do begin
+ if ATrack[T].Hear then begin
+ MidiTrack := MidiFile.GetTrack(T);
+ MidiTrack.OnMidiEvent := MidiFile1MidiEvent;
+ end;
+ end;
+ MidiFile.StartPlaying;//}
+ end;
+
+ if Interaction = 3 then begin
+ if SelectedNumber > 0 then begin
+ Extract;
+ SaveSong(Song, Czesc, ChangeFileExt(FileName, '.txt'), false);
+ end;
+ end;
+
+ end;
+
+ SDLK_SPACE:
+ begin
+// ATrack[Sel].Hear := not ATrack[Sel].Hear;
+ ATrack[Sel].Status := (ATrack[Sel].Status + 1) mod 4;
+
+{ if Selected then begin
+ MidiTrack := MidiFile.GetTrack(Sel);
+ if Track[Sel].Hear then
+ MidiTrack.OnMidiEvent := MidiFile1MidiEvent
+ else
+ MidiTrack.OnMidiEvent := nil;
+ end;}
+ end;
+
+ SDLK_RIGHT:
+ begin
+ InteractNext;
+ end;
+
+ SDLK_LEFT:
+ begin
+ InteractPrev;
+ end;
+
+ SDLK_DOWN:
+ begin
+ Inc(Sel);
+ if Sel > High(ATrack) then Sel := 0;
+ end;
+ SDLK_UP:
+ begin
+ Dec(Sel);
+ if Sel < 0 then Sel := High(ATrack);
+ end;
+ end;
+ end;
+end;
+
+procedure TScreenEditConvert.AddLyric(Start: integer; Tekst: string);
+var
+ N: integer;
+begin
+ for N := 0 to High(Nuta) do begin
+ if Nuta[N].Start = Start then begin
+ // check for new sentece
+ if Copy(Tekst, 1, 1) = '\' then Delete(Tekst, 1, 1);
+ if Copy(Tekst, 1, 1) = '/' then begin
+ Delete(Tekst, 1, 1);
+ Nuta[N].NewSentence := true;
+ end;
+
+ // overwrite lyric od append
+ if Nuta[N].Lyric = '-' then
+ Nuta[N].Lyric := Tekst
+ else
+ Nuta[N].Lyric := Nuta[N].Lyric + Tekst;
+ end;
+ end;
+end;
+
+procedure TScreenEditConvert.Extract;
+var
+ T: integer;
+ C: integer;
+ N: integer;
+ Nu: integer;
+ NutaTemp: TNuta;
+ Move: integer;
+begin
+ // song info
+ Song.Title := '';
+ Song.Artist := '';
+ Song.Mp3 := '';
+ Song.Resolution := 4;
+ SetLength(Song.BPM, 1);
+ Song.BPM[0].BPM := BPM*4;
+
+ // extract notes
+ for T := 0 to High(ATrack) do begin
+// if ATrack[T].Hear then begin
+ if ((ATrack[T].Status div 1) and 1) = 1 then begin
+ for N := 0 to High(ATrack[T].Note) do begin
+ if (ATrack[T].Note[N].EventType = 9) and (ATrack[T].Note[N].Data2 > 0) then begin
+ Nu := Length(Nuta);
+ SetLength(Nuta, Nu + 1);
+ Nuta[Nu].Start := Round(ATrack[T].Note[N].Start / Ticks);
+ Nuta[Nu].Len := Round(ATrack[T].Note[N].Len / Ticks);
+ Nuta[Nu].Tone := ATrack[T].Note[N].Data1 - 12*5;
+ Nuta[Nu].Lyric := '-';
+ end;
+ end;
+ end;
+ end;
+
+ // extract lyrics
+ for T := 0 to High(ATrack) do begin
+// if ATrack[T].Hear then begin
+ if ((ATrack[T].Status div 2) and 1) = 1 then begin
+ for N := 0 to High(ATrack[T].Note) do begin
+ if (ATrack[T].Note[N].EventType = 15) then begin
+// Log.LogStatus('<' + Track[T].Note[N].Str + '>', 'MIDI');
+ AddLyric(Round(ATrack[T].Note[N].Start / Ticks), ATrack[T].Note[N].Str);
+ end;
+ end;
+ end;
+ end;
+
+ // sort notes
+ for N := 0 to High(Nuta) do
+ for Nu := 0 to High(Nuta)-1 do
+ if Nuta[Nu].Start > Nuta[Nu+1].Start then begin
+ NutaTemp := Nuta[Nu];
+ Nuta[Nu] := Nuta[Nu+1];
+ Nuta[Nu+1] := NutaTemp;
+ end;
+
+ // move to 0 at beginning
+ Move := Nuta[0].Start;
+ for N := 0 to High(Nuta) do
+ Nuta[N].Start := Nuta[N].Start - Move;
+
+ // copy notes
+ SetLength(Czesc.Czesc, 1);
+ Czesc.Ilosc := 1;
+ Czesc.High := 0;
+
+ C := 0;
+ N := 0;
+ Czesc.Czesc[C].IlNut := 0;
+ Czesc.Czesc[C].HighNut := -1;
+
+ for Nu := 0 to High(Nuta) do begin
+ if Nuta[Nu].NewSentence then begin // nowa linijka
+ SetLength(Czesc.Czesc, Length(Czesc.Czesc)+1);
+ Czesc.Ilosc := Czesc.Ilosc + 1;
+ Czesc.High := Czesc.High + 1;
+ C := C + 1;
+ N := 0;
+ SetLength(Czesc.Czesc[C].Nuta, 0);
+ Czesc.Czesc[C].IlNut := 0;
+ Czesc.Czesc[C].HighNut := -1;
+ end;
+
+ // tworzy miejsce na nowa nute
+ SetLength(Czesc.Czesc[C].Nuta, Length(Czesc.Czesc[C].Nuta)+1);
+ Czesc.Czesc[C].IlNut := Czesc.Czesc[C].IlNut + 1;
+ Czesc.Czesc[C].HighNut := Czesc.Czesc[C].HighNut + 1;
+
+ // dopisuje
+ Czesc.Czesc[C].Nuta[N].Start := Nuta[Nu].Start;
+ Czesc.Czesc[C].Nuta[N].Dlugosc := Nuta[Nu].Len;
+ Czesc.Czesc[C].Nuta[N].Ton := Nuta[Nu].Tone;
+ Czesc.Czesc[C].Nuta[N].Tekst := Nuta[Nu].Lyric;
+ //All Notes are Freestyle when Converted Fix:
+ Czesc.Czesc[C].Nuta[N].Wartosc := 1;
+ Inc(N);
+ end;
+end;
+
+function TScreenEditConvert.SelectedNumber: integer;
+var
+ T: integer; // track
+begin
+ Result := 0;
+ for T := 0 to High(ATrack) do
+// if ATrack[T].Hear then Inc(Result);
+ if ((ATrack[T].Status div 1) and 1) = 1 then Inc(Result);
+end;
+
+procedure TScreenEditConvert.MidiFile1MidiEvent(event: PMidiEvent);
+begin
+// Log.LogStatus(IntToStr(event.event), 'MIDI');
+ MidiOut.PutShort(event.event, event.data1, event.data2);
+end;
+
+constructor TScreenEditConvert.Create(Back: String);
+var
+ P: integer;
+begin
+ inherited Create(Back);
+ AddButton(40, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(15, 5, 0, 0, 0, 'Open');
+// Button[High(Button)].Text[0].Size := 11;
+
+ AddButton(160, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(25, 5, 0, 0, 0, 'Play');
+
+ AddButton(280, 20, 200, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(25, 5, 0, 0, 0, 'Play Selected');
+
+ AddButton(500, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(20, 5, 0, 0, 0, 'Save');
+
+
+{ MidiOut := TMidiOutput.Create(nil);
+// MidiOut.Close;
+// MidiOut.DeviceID := 0;
+ if Ini.Debug = 1 then
+ MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table
+ Log.LogStatus(MidiOut.ProductName, 'MIDI');
+ MidiOut.Open;
+// MidiOut.SetVolume(100, 100); // temporary}
+
+ FileName := GamePath + 'file.mid';
+ MidiFile := TMidiFile.Create(nil);
+
+ for P := 0 to 100 do begin
+ ColR[P] := Random(10)/10;
+ ColG[P] := Random(10)/10;
+ ColB[P] := Random(10)/10;
+ end;
+
+end;
+
+procedure TScreenEditConvert.onShow;
+var
+ T: integer; // track
+ N: integer; // note
+ C: integer; // channel
+ CN: integer; // channel note
+begin
+ MidiOut := TMidiOutput.Create(nil);
+ if Ini.Debug = 1 then
+ MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table
+ Log.LogStatus(MidiOut.ProductName, 'MIDI');
+ MidiOut.Open;
+
+
+ if FileExists(FileName) then begin
+ MidiFile.Filename := FileName;
+ MidiFile.ReadFile;
+
+
+ Len := 0;
+ Sel := 0;
+ BPM := MidiFile.Bpm;
+ Ticks := MidiFile.TicksPerQuarter / 4;
+
+{ for T := 0 to MidiFile.NumberOfTracks-1 do begin
+ SetLength(Track, Length(Track)+1);
+ MidiTrack := MidiFile.GetTrack(T);
+ MidiTrack.OnMidiEvent := MidiFile1MidiEvent;
+ Track[T].Name := MidiTrack.getName;
+
+ for N := 0 to MidiTrack.getEventCount-1 do begin
+ SetLength(Track[T].Note, Length(Track[T].Note)+1);
+ MidiEvent := MidiTrack.GetEvent(N);
+ Track[T].Note[N].Start := MidiEvent.time;
+ Track[T].Note[N].Len := MidiEvent.len;
+ Track[T].Note[N].Event := MidiEvent.event;
+ Track[T].Note[N].EventType := MidiEvent.event div 16;
+ Track[T].Note[N].Channel := MidiEvent.event and 15;
+ Track[T].Note[N].Data1 := MidiEvent.data1;
+ Track[T].Note[N].Data2 := MidiEvent.data2;
+ Track[T].Note[N].Str := MidiEvent.str;
+
+ if Track[T].Note[N].Start + Track[T].Note[N].Len > Len then
+ Len := Track[T].Note[N].Start + Track[T].Note[N].Len;
+ end;
+ end;}
+
+
+ SetLength(Channel, 16);
+ for T := 0 to 15 do
+ Channel[T].Name := IntToStr(T+1);
+
+ for T := 0 to MidiFile.NumberOfTracks-1 do begin
+ MidiTrack := MidiFile.GetTrack(T);
+ MidiTrack.OnMidiEvent := MidiFile1MidiEvent;
+
+ for N := 0 to MidiTrack.getEventCount-1 do begin
+ MidiEvent := MidiTrack.GetEvent(N);
+ C := MidiEvent.event and 15;
+
+ CN := Length(Channel[C].Note);
+ SetLength(Channel[C].Note, CN+1);
+
+ Channel[C].Note[CN].Start := MidiEvent.time;
+ Channel[C].Note[CN].Len := MidiEvent.len;
+ Channel[C].Note[CN].Event := MidiEvent.event;
+ Channel[C].Note[CN].EventType := MidiEvent.event div 16;
+ Channel[C].Note[CN].Channel := MidiEvent.event and 15;
+ Channel[C].Note[CN].Data1 := MidiEvent.data1;
+ Channel[C].Note[CN].Data2 := MidiEvent.data2;
+ Channel[C].Note[CN].Str := MidiEvent.str;
+
+ if Channel[C].Note[CN].Start + Channel[C].Note[CN].Len > Len then
+ Len := Channel[C].Note[CN].Start + Channel[C].Note[CN].Len;
+ end;
+ end;
+ ATrack := Channel;
+
+ end;
+
+ Interaction := 0;
+end;
+
+function TScreenEditConvert.Draw: boolean;
+var
+ Pet: integer;
+ Pet2: integer;
+ Bottom: real;
+ X: real;
+ Y: real;
+ H: real;
+ YSkip: real;
+begin
+ // draw static menu
+ inherited Draw;
+
+ Y := 100;
+
+ H := Length(ATrack)*40;
+ if H > 480 then H := 480;
+ Bottom := Y + H;
+
+ YSkip := H / Length(ATrack);
+
+ // select
+ DrawQuad(10, Y+Sel*YSkip, 780, YSkip, 0.8, 0.8, 0.8);
+
+ // selected - now me use Status System
+ for Pet := 0 to High(ATrack) do
+ if ATrack[Pet].Hear then
+ DrawQuad(10, Y+Pet*YSkip, 50, YSkip, 0.8, 0.3, 0.3);
+ glColor3f(0, 0, 0);
+ for Pet := 0 to High(ATrack) do begin
+ if ((ATrack[Pet].Status div 1) and 1) = 1 then begin
+ SetFontPos(25, Y + Pet*YSkip + 10);
+ SetFontSize(5);
+ glPrint('N');
+ end;
+ if ((ATrack[Pet].Status div 2) and 1) = 1 then begin
+ SetFontPos(40, Y + Pet*YSkip + 10);
+ SetFontSize(5);
+ glPrint('L');
+ end;
+ end;
+
+ DrawLine(10, Y, 10, Bottom, 0, 0, 0);
+ DrawLine(60, Y, 60, Bottom, 0, 0, 0);
+ DrawLine(790, Y, 790, Bottom, 0, 0, 0);
+
+ for Pet := 0 to Length(ATrack) do
+ DrawLine(10, Y+Pet*YSkip, 790, Y+Pet*YSkip, 0, 0, 0);
+
+ for Pet := 0 to High(ATrack) do begin
+ SetFontPos(11, Y + 10 + Pet*YSkip);
+ SetFontSize(5);
+ glPrint(pchar(ATrack[Pet].Name));
+ end;
+
+ for Pet := 0 to High(ATrack) do
+ for Pet2 := 0 to High(ATrack[Pet].Note) do begin
+ if ATrack[Pet].Note[Pet2].EventType = 9 then
+ DrawQuad(60 + ATrack[Pet].Note[Pet2].Start/Len * 725, Y + (Pet+1)*YSkip - ATrack[Pet].Note[Pet2].Data1*35/127, 3, 3, ColR[Pet], ColG[Pet], ColB[Pet]);
+ if ATrack[Pet].Note[Pet2].EventType = 15 then
+ DrawLine(60 + ATrack[Pet].Note[Pet2].Start/Len * 725, Y + 0.75 * YSkip + Pet*YSkip, 60 + ATrack[Pet].Note[Pet2].Start/Len * 725, Y + YSkip + Pet*YSkip, ColR[Pet], ColG[Pet], ColB[Pet]);
+ end;
+
+ // playing line
+ X := 60+MidiFile.GetCurrentTime/MidiFile.GetTrackLength*730;
+ DrawLine(X, Y, X, Bottom, 0.3, 0.3, 0.3);
+
+
+end;
+
+procedure TScreenEditConvert.onHide;
+begin
+ MidiOut.Close;
+ MidiOut.Free;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenEditHeader.dcu b/Game/Code/Screens/UScreenEditHeader.dcu
new file mode 100644
index 00000000..9508e841
--- /dev/null
+++ b/Game/Code/Screens/UScreenEditHeader.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenEditHeader.pas b/Game/Code/Screens/UScreenEditHeader.pas
new file mode 100644
index 00000000..65f39e44
--- /dev/null
+++ b/Game/Code/Screens/UScreenEditHeader.pas
@@ -0,0 +1,362 @@
+unit UScreenEditHeader;
+
+interface
+
+uses UMenu, SDL, USongs, UThemes;
+
+type
+ TScreenEditHeader = class(TMenu)
+ public
+ AktSong: TSong;
+ TextTitle: integer;
+ TextArtist: integer;
+ TextMp3: integer;
+ TextBackground: integer;
+ TextVideo: integer;
+ TextVideoGAP: integer;
+ TextRelative: integer;
+ TextResolution: integer;
+ TextNotesGAP: integer;
+ TextStart: integer;
+ TextGAP: integer;
+ TextBPM: integer;
+ StaticTitle: integer;
+ StaticArtist: integer;
+ StaticMp3: integer;
+ StaticBackground: integer;
+ StaticVideo: integer;
+ StaticVideoGAP: integer;
+ StaticRelative: integer;
+ StaticResolution: integer;
+ StaticNotesGAP: integer;
+ StaticStart: integer;
+ StaticGAP: integer;
+ StaticBPM: integer;
+ Sel: array[0..11] of boolean;
+ procedure SetRoundButtons;
+
+ constructor Create(Back: String); override;
+ procedure onShow; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+{ function Draw: boolean; override;
+ procedure Finish;}
+ end;
+
+implementation
+
+uses UGraphic, UMusic, SysUtils, UPliki, USkins;
+
+function TScreenEditHeader.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+var
+ T: integer;
+begin
+ Result := true;
+ If (PressedDown) Then begin // Key Down
+ case PressedKey of
+ SDLK_ESCAPE :
+ begin
+// Music.PlayBack;
+// FadeTo(@MainScreen);
+ Result := false;
+ end;
+
+ SDLK_RETURN:
+ begin
+ if Interaction = 1 then begin
+// Save;
+ end;
+ end;
+
+ SDLK_RIGHT:
+ begin
+ case Interaction of
+ 0..0: InteractNext;
+ 1: Interaction := 0;
+ end;
+ end;
+
+ SDLK_LEFT:
+ begin
+ case Interaction of
+ 0: Interaction := 1;
+ 1..1: InteractPrev;
+ end;
+ end;
+
+ SDLK_DOWN:
+ begin
+ case Interaction of
+ 0..1: Interaction := 2;
+ 2..12: InteractNext;
+ 13: Interaction := 0;
+ end;
+ end;
+
+ SDLK_UP:
+ begin
+ case Interaction of
+ 0..1: Interaction := 13;
+ 2: Interaction := 0;
+ 3..13: InteractPrev;
+ end;
+ end;
+
+ SDLK_BACKSPACE:
+ begin
+ T := Interaction - 2 + TextTitle;
+ if (Interaction >= 2) and (Interaction <= 13) and (Length(Text[T].Text) >= 1) then begin
+ Delete(Text[T].Text, Length(Text[T].Text), 1);
+ SetRoundButtons;
+ end;
+ end;
+
+ end;
+ case ScanCode of
+ 32..255:
+ begin
+ if (Interaction >= 2) and (Interaction <= 13) then begin
+ Text[Interaction - 2 + TextTitle].Text :=
+ Text[Interaction - 2 + TextTitle].Text + chr(ScanCode);
+ SetRoundButtons;
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenEditHeader.Create(Back: String);
+begin
+ inherited Create(Back);
+
+ AddButton(40, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(15, 5, 'Open');
+
+ AddButton(160, 20, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(20, 5, 'Save');
+
+ AddBox(80, 60, 640, 550);
+
+ AddText(160, 110 + 0*30, 0, 10, 0, 0, 0, 'Title:');
+ AddText(160, 110 + 1*30, 0, 10, 0, 0, 0, 'Artist:');
+ AddText(160, 110 + 2*30, 0, 10, 0, 0, 0, 'MP3:');
+
+ AddText(160, 110 + 4*30, 0, 10, 0, 0, 0, 'Background:');
+ AddText(160, 110 + 5*30, 0, 10, 0, 0, 0, 'Video:');
+ AddText(160, 110 + 6*30, 0, 10, 0, 0, 0, 'VideoGAP:');
+
+ AddText(160, 110 + 8*30, 0, 10, 0, 0, 0, 'Relative:');
+ AddText(160, 110 + 9*30, 0, 10, 0, 0, 0, 'Resolution:');
+ AddText(160, 110 + 10*30, 0, 10, 0, 0, 0, 'NotesGAP:');
+
+ AddText(160, 110 + 12*30, 0, 10, 0, 0, 0, 'Start:');
+ AddText(160, 110 + 13*30, 0, 10, 0, 0, 0, 'GAP:');
+ AddText(160, 110 + 14*30, 0, 10, 0, 0, 0, 'BPM:');
+
+ TextTitle := AddText(340, 110 + 0*30, 0, 10, 0, 0, 0, '');
+ TextArtist := AddText(340, 110 + 1*30, 0, 10, 0, 0, 0, '');
+ TextMp3 := AddText(340, 110 + 2*30, 0, 10, 0, 0, 0, '');
+
+ TextBackground := AddText(340, 110 + 4*30, 0, 10, 0, 0, 0, '');
+ TextVideo := AddText(340, 110 + 5*30, 0, 10, 0, 0, 0, '');
+ TextVideoGAP := AddText(340, 110 + 6*30, 0, 10, 0, 0, 0, '');
+
+ TextRelative := AddText(340, 110 + 8*30, 0, 10, 0, 0, 0, '');
+ TextResolution := AddText(340, 110 + 9*30, 0, 10, 0, 0, 0, '');
+ TextNotesGAP := AddText(340, 110 + 10*30, 0, 10, 0, 0, 0, '');
+
+ TextStart := AddText(340, 110 + 12*30, 0, 10, 0, 0, 0, '');
+ TextGAP := AddText(340, 110 + 13*30, 0, 10, 0, 0, 0, '');
+ TextBPM := AddText(340, 110 + 14*30, 0, 10, 0, 0, 0, '');
+
+ StaticTitle := AddStatic(130, 115 + 0*30, 20, 20, 1, 1, 1, 'RoundButton', 'BMP', 'Transparent', $FF00FF);
+ StaticArtist := AddStatic(130, 115 + 1*30, 20, 20, 1, 1, 1, 'RoundButton', 'BMP', 'Transparent', $FF00FF);
+ StaticMp3 := AddStatic(130, 115 + 2*30, 20, 20, 1, 1, 1, 'RoundButton', 'BMP', 'Transparent', $FF00FF);
+ StaticBackground := AddStatic(130, 115 + 4*30, 20, 20, 1, 1, 1, 'RoundButton', 'BMP', 'Transparent', $FF00FF);
+ StaticVideo := AddStatic(130, 115 + 5*30, 20, 20, 1, 1, 1, 'RoundButton', 'BMP', 'Transparent', $FF00FF);
+ StaticVideoGAP := AddStatic(130, 115 + 6*30, 20, 20, 1, 1, 1, 'RoundButton', 'BMP', 'Transparent', $FF00FF);
+ StaticRelative := AddStatic(130, 115 + 8*30, 20, 20, 1, 1, 1, 'RoundButton', 'BMP', 'Transparent', $FF00FF);
+ StaticResolution := AddStatic(130, 115 + 9*30, 20, 20, 1, 1, 1, 'RoundButton', 'BMP', 'Transparent', $FF00FF);
+ StaticNotesGAP := AddStatic(130, 115 + 10*30, 20, 20, 1, 1, 1, 'RoundButton', 'BMP', 'Transparent', $FF00FF);
+ StaticStart := AddStatic(130, 115 + 12*30, 20, 20, 1, 1, 1, 'RoundButton', 'BMP', 'Transparent', $FF00FF);
+ StaticGAP := AddStatic(130, 115 + 13*30, 20, 20, 1, 1, 1, 'RoundButton', 'BMP', 'Transparent', $FF00FF);
+ StaticBPM := AddStatic(130, 115 + 14*30, 20, 20, 1, 1, 1, 'RoundButton', 'BMP', 'Transparent', $FF00FF);
+
+ AddInteraction(iText, TextTitle);
+ AddInteraction(iText, TextArtist);
+ AddInteraction(iText, TextMp3);
+ AddInteraction(iText, TextBackground);
+ AddInteraction(iText, TextVideo);
+ AddInteraction(iText, TextVideoGAP);
+ AddInteraction(iText, TextRelative);
+ AddInteraction(iText, TextResolution);
+ AddInteraction(iText, TextNotesGAP);
+ AddInteraction(iText, TextStart);
+ AddInteraction(iText, TextGAP);
+ AddInteraction(iText, TextBPM);
+end;
+
+procedure TScreenEditHeader.onShow;
+begin
+{ if FileExists(FileName) then begin // load file
+ AktSong.FileName := FileName;
+ SkanujPlik(AktSong);
+
+ SetLength(TrueBoolStrs, 1);
+ TrueBoolStrs[0] := 'yes';
+ SetLength(FalseBoolStrs, 1);
+ FalseBoolStrs[0] := 'no';
+
+ Text[TextTitle].Text := AktSong.Title;
+ Text[TextArtist].Text := AktSong.Artist;
+ Text[TextMP3].Text := AktSong.Mp3;
+ Text[TextBackground].Text := AktSong.Background;
+ Text[TextVideo].Text := AktSong.Video;
+ Text[TextVideoGAP].Text := FloatToStr(AktSong.VideoGAP);
+ Text[TextRelative].Text := BoolToStr(AktSong.Relative, true);
+ Text[TextResolution].Text := IntToStr(AktSong.Resolution);
+ Text[TextNotesGAP].Text := IntToStr(AktSong.NotesGAP);
+ Text[TextStart].Text := FloatToStr(AktSong.Start);
+ Text[TextGAP].Text := FloatToStr(AktSong.GAP);
+ Text[TextBPM].Text := FloatToStr(AktSong.BPM[0].BPM);
+ SetRoundButtons;
+ end;}
+
+ Interaction := 0;
+end;
+
+(*function TScreenEdit.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ Pet: integer;
+ AktBeat: integer;
+begin
+{ glClearColor(1,1,1,1);
+
+ // control music
+ if PlaySentence then begin
+ // stop the music
+ if (Music.Position > PlayStopTime) then begin
+ Music.Stop;
+ PlaySentence := false;
+ end;
+
+ // click
+ if (Click) and (PlaySentence) then begin
+ AktBeat := Floor(AktSong.BPM[0].BPM * (Music.Position - AktSong.GAP / 1000) / 60);
+ Text[TextDebug].Text := IntToStr(AktBeat);
+ if AktBeat <> LastClick then begin
+ for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
+ if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then begin
+ Music.PlayClick;
+ LastClick := AktBeat;
+ end;
+ end;
+ end; // click
+ end; // if PlaySentence
+
+ Text[TextSentence].Text := IntToStr(Czesci[0].Akt + 1) + ' / ' + IntToStr(Czesci[0].Ilosc);
+ Text[TextNote].Text := IntToStr(AktNuta + 1) + ' / ' + IntToStr(Czesci[0].Czesc[Czesci[0].Akt].IlNut);
+
+ // Song info
+ Text[TextBPM].Text := FloatToStr(AktSong.BPM[0].BPM / 4);
+ Text[TextGAP].Text := FloatToStr(AktSong.GAP);
+
+ // Note info
+ Text[TextNStart].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
+ Text[TextNDlugosc].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
+ Text[TextNTon].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton);
+ Text[TextNText].Text := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
+
+ // draw static menu
+ inherited Draw;
+
+ // draw notes
+ SingDrawNoteLines(20, 300, 780, 15);
+ SingDrawBeatDelimeters(40, 300, 760, 0);
+ SingDrawCzesc(40, 405, 760, 0);
+
+ // draw text
+ Lyric.Draw;}
+
+end;*)
+
+procedure TScreenEditHeader.SetRoundButtons;
+begin
+ if Length(Text[TextTitle].Text) > 0 then Static[StaticTitle].Visible := true
+ else Static[StaticTitle].Visible := false;
+
+ if Length(Text[TextArtist].Text) > 0 then Static[StaticArtist].Visible := true
+ else Static[StaticArtist].Visible := false;
+
+ if Length(Text[TextMp3].Text) > 0 then Static[StaticMp3].Visible := true
+ else Static[StaticMp3].Visible := false;
+
+ if Length(Text[TextBackground].Text) > 0 then Static[StaticBackground].Visible := true
+ else Static[StaticBackground].Visible := false;
+
+ if Length(Text[TextVideo].Text) > 0 then Static[StaticVideo].Visible := true
+ else Static[StaticVideo].Visible := false;
+
+ try
+ StrToFloat(Text[TextVideoGAP].Text);
+ if StrToFloat(Text[TextVideoGAP].Text)<> 0 then Static[StaticVideoGAP].Visible := true
+ else Static[StaticVideoGAP].Visible := false;
+ except
+ Static[StaticVideoGAP].Visible := false;
+ end;
+
+ if LowerCase(Text[TextRelative].Text) = 'yes' then Static[StaticRelative].Visible := true
+ else Static[StaticRelative].Visible := false;
+
+ try
+ StrToInt(Text[TextResolution].Text);
+ if (StrToInt(Text[TextResolution].Text) <> 0) and (StrToInt(Text[TextResolution].Text) >= 1)
+ then Static[StaticResolution].Visible := true
+ else Static[StaticResolution].Visible := false;
+ except
+ Static[StaticResolution].Visible := false;
+ end;
+
+ try
+ StrToInt(Text[TextNotesGAP].Text);
+ Static[StaticNotesGAP].Visible := true;
+ except
+ Static[StaticNotesGAP].Visible := false;
+ end;
+
+ // start
+ try
+ StrToFloat(Text[TextStart].Text);
+ if (StrToFloat(Text[TextStart].Text) > 0) then Static[StaticStart].Visible := true
+ else Static[StaticStart].Visible := false;
+ except
+ Static[StaticStart].Visible := false;
+ end;
+
+ // GAP
+ try
+ StrToFloat(Text[TextGAP].Text);
+ Static[StaticGAP].Visible := true;
+ except
+ Static[StaticGAP].Visible := false;
+ end;
+
+ // BPM
+ try
+ StrToFloat(Text[TextBPM].Text);
+ if (StrToFloat(Text[TextBPM].Text) > 0) then Static[StaticBPM].Visible := true
+ else Static[StaticBPM].Visible := false;
+ except
+ Static[StaticBPM].Visible := false;
+ end;
+
+end;
+
+(*procedure TScreenEdit.Finish;
+begin
+//
+end;*)
+
+end.
diff --git a/Game/Code/Screens/UScreenEditSub.dcu b/Game/Code/Screens/UScreenEditSub.dcu
new file mode 100644
index 00000000..6b6b6e35
--- /dev/null
+++ b/Game/Code/Screens/UScreenEditSub.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenEditSub.pas b/Game/Code/Screens/UScreenEditSub.pas
new file mode 100644
index 00000000..7bdbac0d
--- /dev/null
+++ b/Game/Code/Screens/UScreenEditSub.pas
@@ -0,0 +1,1236 @@
+unit UScreenEditSub;
+
+interface
+
+uses UMenu, UMusic, SDL, SysUtils, UPliki, UTime, USongs, UIni, ULog, USmpeg, UTexture, UMenuText,
+ ULyrics, Math, OpenGL12, UThemes, MidiOut;
+
+type
+ TScreenEditSub = class(TMenu)
+ private
+ TextNote: integer;
+ TextSentence: integer;
+ TextTitle: integer;
+ TextArtist: integer;
+ TextMp3: integer;
+ TextBPM: integer;
+ TextGAP: integer;
+ TextDebug: integer;
+ TextNStart: integer;
+ TextNDlugosc: integer;
+ TextNTon: integer;
+ TextNText: integer;
+ AktNuta: integer;
+ PlaySentence: boolean;
+ PlaySentenceMidi: boolean;
+ PlayStopTime: real;
+ LastClick: integer;
+ Click: boolean;
+ CopySrc: integer;
+
+ MidiOut: TMidiOutput;
+ MidiStart: real;
+ MidiStop: real;
+ MidiTime: real;
+ MidiPos: real;
+ MidiLastNote: integer;
+
+ TextEditMode: boolean;
+
+ procedure NewBeat;
+ procedure CzesciDivide;
+ procedure CzesciMultiply;
+ procedure LyricsCapitalize;
+ procedure LyricsCorrectSpaces;
+ procedure FixTimings;
+ procedure DivideSentence;
+ procedure JoinSentence;
+ procedure DivideNote;
+ procedure DeleteNote;
+ procedure TransposeNote(Transpose: integer);
+ procedure ChangeWholeTone(Tone: integer);
+ procedure MoveAllToEnd(Move: integer);
+ procedure MoveTextToRight;
+ procedure MarkSrc;
+ procedure PasteText;
+ procedure CopySentence(Src, Dst: integer);
+ procedure CopySentences(Src, Dst, Num: integer);
+ public
+ Tex_Background: TTexture;
+ FadeOut: boolean;
+ Path: string;
+ FileName: string;
+ constructor Create(Back: String); override;
+ procedure onShow; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ function ParseInputEditText(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+ function Draw: boolean; override;
+ procedure onHide; override;
+ end;
+
+implementation
+uses UGraphic, UDraw, UMain, USkins;
+
+// Method for input parsing. If False is returned, GetNextWindow
+// should be checked to know the next window to load;
+function TScreenEditSub.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+var
+ SDL_ModState: Word;
+ R: real;
+begin
+ Result := true;
+
+ if TextEditMode then begin
+ Result := ParseInputEditText(PressedKey, ScanCode, PressedDown);
+ end else begin
+
+ SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS});
+
+ If (PressedDown) then begin // Key Down
+ case PressedKey of
+ SDLK_ESCAPE:
+ begin
+ FadeTo(@ScreenSong);
+ end;
+
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+
+ SDLK_BACKQUOTE:
+ begin
+ // Increase Note Length (same as Alt + Right)
+ Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
+ if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
+ Inc(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+ end;
+
+ SDLK_EQUALS:
+ begin
+ // Increase BPM
+ if SDL_ModState = 0 then
+ AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 5) + 1) / 5; // (1/20)
+ if SDL_ModState = KMOD_LSHIFT then
+ AktSong.BPM[0].BPM := AktSong.BPM[0].BPM + 4; // (1/1)
+ if SDL_ModState = KMOD_LCTRL then
+ AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 25) + 1) / 25; // (1/100)
+ end;
+
+ SDLK_MINUS:
+ begin
+ // Decrease BPM
+ if SDL_ModState = 0 then
+ AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 5) - 1) / 5;
+ if SDL_ModState = KMOD_LSHIFT then
+ AktSong.BPM[0].BPM := AktSong.BPM[0].BPM - 4;
+ if SDL_ModState = KMOD_LCTRL then
+ AktSong.BPM[0].BPM := Round((AktSong.BPM[0].BPM * 25) - 1) / 25;
+ end;
+
+ SDLK_0:
+ begin
+ // Increase GAP
+ if SDL_ModState = 0 then
+ AktSong.GAP := AktSong.GAP + 10;
+ if SDL_ModState = KMOD_LSHIFT then
+ AktSong.GAP := AktSong.GAP + 1000;
+ end;
+
+ SDLK_9:
+ begin
+ // Decrease GAP
+ if SDL_ModState = 0 then
+ AktSong.GAP := AktSong.GAP - 10;
+ if SDL_ModState = KMOD_LSHIFT then
+ AktSong.GAP := AktSong.GAP - 1000;
+ end;
+
+ SDLK_KP_PLUS:
+ begin
+ // Increase tone of all notes
+ if SDL_ModState = 0 then
+ ChangeWholeTone(1);
+ if SDL_ModState = KMOD_LSHIFT then
+ ChangeWholeTone(12);
+ end;
+
+ SDLK_KP_MINUS:
+ begin
+ // Decrease tone of all notes
+ if SDL_ModState = 0 then
+ ChangeWholeTone(-1);
+ if SDL_ModState = KMOD_LSHIFT then
+ ChangeWholeTone(-12);
+ end;
+
+ SDLK_SLASH:
+ begin
+ if SDL_ModState = 0 then begin
+ // Insert start of sentece
+ if AktNuta > 0 then
+ DivideSentence;
+ end;
+
+ if SDL_ModState = KMOD_LSHIFT then begin
+ // Join next sentence with current
+ if Czesci[0].Akt < Czesci[0].High then
+ JoinSentence;
+ end;
+
+ if SDL_ModState = KMOD_LCTRL then begin
+ // divide note
+ DivideNote;
+ end;
+
+ end;
+
+ SDLK_S:
+ begin
+ if SDL_ModState = 0 then
+ // Save Song
+ SaveSong(AktSong, Czesci[0], Path + FileName, false);
+
+ if SDL_ModState = KMOD_LSHIFT then
+ // Save Song
+ SaveSong(AktSong, Czesci[0], Path + FileName, true);
+
+ if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL + KMOD_LALT then
+ // Save Song
+ SaveSongDebug(AktSong, Czesci[0], 'C:\song.asm', false);
+
+ end;
+
+ SDLK_D:
+ begin
+ // Divide lengths by 2
+ CzesciDivide;
+ end;
+
+ SDLK_M:
+ begin
+ // Multiply lengths by 2
+ CzesciMultiply;
+ end;
+
+ SDLK_C:
+ begin
+ // Capitalize letter at the beginning of line
+ if SDL_ModState = 0 then
+ LyricsCapitalize;
+
+ // Correct spaces
+ if SDL_ModState = KMOD_LSHIFT then
+ LyricsCorrectSpaces;
+
+ // Copy sentence
+ if SDL_ModState = KMOD_LCTRL then
+ MarkSrc;
+ end;
+
+ SDLK_V:
+ begin
+ // Paste text
+ if SDL_ModState = KMOD_LCTRL then begin
+ if Czesci[0].Czesc[Czesci[0].Akt].IlNut >= Czesci[0].Czesc[CopySrc].IlNut then
+ PasteText
+ else
+ beep;
+ end;
+
+ if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
+ CopySentence(CopySrc, Czesci[0].Akt);
+ end;
+ end;
+
+ SDLK_4:
+ begin
+ if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
+ CopySentence(CopySrc, Czesci[0].Akt);
+ CopySentence(CopySrc+1, Czesci[0].Akt+1);
+ CopySentence(CopySrc+2, Czesci[0].Akt+2);
+ CopySentence(CopySrc+3, Czesci[0].Akt+3);
+ end;
+
+ if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then begin
+ CopySentences(CopySrc, Czesci[0].Akt, 4);
+ end;
+ end;
+ SDLK_5:
+ begin
+ if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT then begin
+ CopySentence(CopySrc, Czesci[0].Akt);
+ CopySentence(CopySrc+1, Czesci[0].Akt+1);
+ CopySentence(CopySrc+2, Czesci[0].Akt+2);
+ CopySentence(CopySrc+3, Czesci[0].Akt+3);
+ CopySentence(CopySrc+4, Czesci[0].Akt+4);
+ end;
+
+ if SDL_ModState = KMOD_LCTRL + KMOD_LSHIFT + KMOD_LALT then begin
+ CopySentences(CopySrc, Czesci[0].Akt, 5);
+ end;
+ end;
+
+ SDLK_T:
+ begin
+ // Fixes timings between sentences
+ FixTimings;
+ end;
+
+ SDLK_F4:
+ begin
+ // Enter Text Edit Mode
+ TextEditMode := true;
+ end;
+
+ SDLK_P:
+ begin
+ if SDL_ModState = 0 then begin
+ // Play Sentence
+ Click := true;
+ Music.Stop;
+ R := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
+ if R <= Music.Length then begin
+ Music.MoveTo(R);
+ PlayStopTime := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+ PlaySentence := true;
+ Music.Play;
+ LastClick := -100;
+ end;
+ end;
+
+ if SDL_ModState = KMOD_LSHIFT then begin
+ PlaySentenceMidi := true;
+
+ MidiTime := USTime.GetTime;
+ MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
+ MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+
+ LastClick := -100;
+ end;
+ if SDL_ModState = KMOD_LSHIFT or KMOD_LCTRL then begin
+ PlaySentenceMidi := true;
+ MidiTime := USTime.GetTime;
+ MidiStart := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
+ MidiStop := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+ LastClick := -100;
+
+ PlaySentence := true;
+ Click := true;
+ Music.Stop;
+ Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].StartNote)+0{-0.10});
+ PlayStopTime := GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Koniec)+0;
+ Music.Play;
+ LastClick := -100;
+ end;
+ end;
+
+ SDLK_SPACE:
+ begin
+ // Play Sentence
+ PlaySentenceMidi := false; // stop midi
+ PlaySentence := true;
+ Click := false;
+ Music.Stop;
+ Music.MoveTo(GetTimeFromBeat(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start));
+ PlayStopTime := (GetTimeFromBeat(
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start +
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc));
+ Music.Play;
+ LastClick := -100;
+ end;
+
+ SDLK_RETURN:
+ begin
+ end;
+
+ SDLK_LCTRL:
+ begin
+ end;
+
+ SDLK_DELETE:
+ begin
+ if SDL_ModState = KMOD_LCTRL then begin
+ // moves text to right in current sentence
+ DeleteNote;
+ end;
+ end;
+
+ SDLK_PERIOD:
+ begin
+ // moves text to right in current sentence
+ MoveTextToRight;
+ end;
+
+ SDLK_RIGHT:
+ begin
+ // right
+ if SDL_ModState = 0 then begin
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
+ Inc(AktNuta);
+ if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].IlNut then AktNuta := 0;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
+ Lyric.Selected := AktNuta;
+ end;
+
+ // ctrl + right
+ if SDL_ModState = KMOD_LCTRL then begin
+ if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc > 1 then begin
+ Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
+ Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
+ if AktNuta = 0 then begin
+ Inc(Czesci[0].Czesc[Czesci[0].Akt].Start);
+ Inc(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
+ end;
+ end;
+ end;
+
+ // shift + right
+ if SDL_ModState = KMOD_LSHIFT then begin
+ Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
+ if AktNuta = 0 then begin
+ Inc(Czesci[0].Czesc[Czesci[0].Akt].Start);
+ Inc(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
+ end;
+ if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
+ Inc(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+ end;
+
+ // alt + right
+ if SDL_ModState = KMOD_LALT then begin
+ Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
+ if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
+ Inc(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+ end;
+
+ // alt + ctrl + shift + right = move all from cursor to right
+ if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then begin
+ MoveAllToEnd(1);
+ end;
+
+ end;
+
+ SDLK_LEFT:
+ begin
+ // left
+ if SDL_ModState = 0 then begin
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
+ Dec(AktNuta);
+ if AktNuta = -1 then AktNuta := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
+ Lyric.Selected := AktNuta;
+ end;
+
+ // ctrl + left
+ if SDL_ModState = KMOD_LCTRL then begin
+ Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
+ Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
+ if AktNuta = 0 then begin
+ Dec(Czesci[0].Czesc[Czesci[0].Akt].Start);
+ Dec(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
+ end;
+ end;
+
+ // shift + left
+ if SDL_ModState = KMOD_LSHIFT then begin
+ Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
+
+ // resizing sentences
+ if AktNuta = 0 then begin
+ Dec(Czesci[0].Czesc[Czesci[0].Akt].Start);
+ Dec(Czesci[0].Czesc[Czesci[0].Akt].StartNote);
+ end;
+
+ if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
+ Dec(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+
+ end;
+
+ // alt + left
+ if SDL_ModState = KMOD_LALT then begin
+ if Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc > 1 then begin
+ Dec(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
+ if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].HighNut then
+ Dec(Czesci[0].Czesc[Czesci[0].Akt].Koniec);
+ end;
+ end;
+
+ // alt + ctrl + shift + right = move all from cursor to left
+ if SDL_ModState = KMOD_LALT + KMOD_LCTRL + KMOD_LSHIFT then begin
+ MoveAllToEnd(-1);
+ end;
+
+ end;
+
+ SDLK_DOWN:
+ begin
+ // skip to next sentence
+ if SDL_ModState = 0 then begin
+ MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ PlaySentenceMidi := false;
+
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
+ Inc(Czesci[0].Akt);
+ AktNuta := 0;
+ if Czesci[0].Akt > Czesci[0].High then Czesci[0].Akt := 0;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
+
+ Lyric.AddCzesc(Czesci[0].Akt);
+ Lyric.Selected := 0;
+ Music.Stop;
+ PlaySentence := false;
+ end;
+
+ // decrease tone
+ if SDL_ModState = KMOD_LCTRL then begin
+ TransposeNote(-1);
+ end;
+
+ end;
+
+ SDLK_UP:
+ begin
+ // skip to previous sentence
+ if SDL_ModState = 0 then begin
+ MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ PlaySentenceMidi := false;
+
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
+ Dec(Czesci[0].Akt);
+ AktNuta := 0;
+ if Czesci[0].Akt = -1 then Czesci[0].Akt := Czesci[0].High;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
+
+ Lyric.AddCzesc(Czesci[0].Akt);
+ Lyric.Selected := 0;
+ Music.Stop;
+ PlaySentence := false;
+ end;
+
+ // increase tone
+ if SDL_ModState = KMOD_LCTRL then begin
+ TransposeNote(1);
+ end;
+ end;
+
+ // Golden Note Patch
+ SDLK_G:
+ begin
+ case Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc of
+ 0: Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 2;
+ 1: Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 2;
+ 2: Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 1;
+ end; // case
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Freestyle := False;
+ end;
+
+ // Freestyle Note Patch
+ SDLK_F:
+ begin
+ case Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc of
+ 0:
+ begin;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 1;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Freestyle := False;
+ end;
+ 1,2:
+ begin;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Wartosc := 0;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Freestyle := True;
+ end;
+ end; // case
+
+ end;
+
+
+ end;
+ end;
+ end; // if
+end;
+
+function TScreenEditSub.ParseInputEditText(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+var
+ SDL_ModState: Word;
+begin
+ // used when in Text Edit Mode
+ Result := true;
+
+ SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT {+ KMOD_CAPS});
+
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_ESCAPE:
+ begin
+ FadeTo(@ScreenSong);
+ end;
+ SDLK_F4, SDLK_RETURN:
+ begin
+ // Exit Text Edit Mode
+ TextEditMode := false;
+ end;
+ 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
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst :=
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst + chr(ScanCode);
+ end;
+ SDLK_BACKSPACE:
+ begin
+ Delete(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst,
+ Length(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst), 1);
+ end;
+ SDLK_RIGHT:
+ begin
+ // right
+ if SDL_ModState = 0 then begin
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
+ Inc(AktNuta);
+ if AktNuta = Czesci[0].Czesc[Czesci[0].Akt].IlNut then AktNuta := 0;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
+ Lyric.Selected := AktNuta;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ // left
+ if SDL_ModState = 0 then begin
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 0;
+ Dec(AktNuta);
+ if AktNuta = -1 then AktNuta := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
+ Lyric.Selected := AktNuta;
+ end;
+ end;
+ end;
+ end;
+end;
+
+procedure TScreenEditSub.NewBeat;
+begin
+ // click
+{ 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
+ // old}
+// Music.PlayClick;
+end;
+
+procedure TScreenEditSub.CzesciDivide;
+var
+ C: integer;
+ N: integer;
+begin
+ AktSong.BPM[0].BPM := AktSong.BPM[0].BPM / 2;
+ for C := 0 to Czesci[0].High do begin
+ Czesci[0].Czesc[C].Start := Czesci[0].Czesc[C].Start div 2;
+ Czesci[0].Czesc[C].StartNote := Czesci[0].Czesc[C].StartNote div 2;
+ Czesci[0].Czesc[C].Koniec := Czesci[0].Czesc[C].Koniec div 2;
+ for N := 0 to Czesci[0].Czesc[C].HighNut do begin
+ Czesci[0].Czesc[C].Nuta[N].Start := Czesci[0].Czesc[C].Nuta[N].Start div 2;
+ Czesci[0].Czesc[C].Nuta[N].Dlugosc := Round(Czesci[0].Czesc[C].Nuta[N].Dlugosc / 2);
+ end; // N
+ end; // C
+end;
+
+procedure TScreenEditSub.CzesciMultiply;
+var
+ C: integer;
+ N: integer;
+begin
+ AktSong.BPM[0].BPM := AktSong.BPM[0].BPM * 2;
+ for C := 0 to Czesci[0].High do begin
+ Czesci[0].Czesc[C].Start := Czesci[0].Czesc[C].Start * 2;
+ Czesci[0].Czesc[C].StartNote := Czesci[0].Czesc[C].StartNote * 2;
+ Czesci[0].Czesc[C].Koniec := Czesci[0].Czesc[C].Koniec * 2;
+ for N := 0 to Czesci[0].Czesc[C].HighNut do begin
+ Czesci[0].Czesc[C].Nuta[N].Start := Czesci[0].Czesc[C].Nuta[N].Start * 2;
+ Czesci[0].Czesc[C].Nuta[N].Dlugosc := Czesci[0].Czesc[C].Nuta[N].Dlugosc * 2;
+ end; // N
+ end; // C
+end;
+
+procedure TScreenEditSub.LyricsCapitalize;
+var
+ C: integer;
+ N: integer; // temporary
+ S: string;
+begin
+ // temporary
+{ for C := 0 to Czesci[0].High do
+ for N := 0 to Czesci[0].Czesc[C].HighNut do
+ Czesci[0].Czesc[C].Nuta[N].Tekst := AnsiLowerCase(Czesci[0].Czesc[C].Nuta[N].Tekst);}
+
+ for C := 0 to Czesci[0].High do begin
+ S := AnsiUpperCase(Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 1, 1));
+ S := S + Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 2, Length(Czesci[0].Czesc[C].Nuta[0].Tekst)-1);
+ Czesci[0].Czesc[C].Nuta[0].Tekst := S;
+ end; // C
+end;
+
+procedure TScreenEditSub.LyricsCorrectSpaces;
+var
+ C: integer;
+ N: integer;
+begin
+ for C := 0 to Czesci[0].High do begin
+ // correct starting spaces in the first word
+ while Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 1, 1) = ' ' do
+ Czesci[0].Czesc[C].Nuta[0].Tekst := Copy(Czesci[0].Czesc[C].Nuta[0].Tekst, 2, 100);
+
+ // move spaces on the start to the end of the previous note
+ for N := 1 to Czesci[0].Czesc[C].HighNut do begin
+ while (Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, 1, 1) = ' ') do begin
+ Czesci[0].Czesc[C].Nuta[N].Tekst := Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, 2, 100);
+ Czesci[0].Czesc[C].Nuta[N-1].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst + ' ';
+ end;
+ end; // N
+
+ // correct '-' to '- '
+ for N := 0 to Czesci[0].Czesc[C].HighNut do begin
+ if Czesci[0].Czesc[C].Nuta[N].Tekst = '-' then
+ Czesci[0].Czesc[C].Nuta[N].Tekst := '- ';
+ end; // N
+
+ // add space to the previous note when the current word is '- '
+ for N := 1 to Czesci[0].Czesc[C].HighNut do begin
+ if Czesci[0].Czesc[C].Nuta[N].Tekst = '- ' then
+ Czesci[0].Czesc[C].Nuta[N-1].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst + ' ';
+ end; // N
+
+ // correct too many spaces at the end of note
+ for N := 0 to Czesci[0].Czesc[C].HighNut do begin
+ while Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, Length(Czesci[0].Czesc[C].Nuta[N].Tekst)-1, 2) = ' ' do
+ Czesci[0].Czesc[C].Nuta[N].Tekst := Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, 1, Length(Czesci[0].Czesc[C].Nuta[N].Tekst)-1);
+ end; // N
+
+ // and correct if there is no space at the end of sentence
+ N := Czesci[0].Czesc[C].HighNut;
+ if Copy(Czesci[0].Czesc[C].Nuta[N].Tekst, Length(Czesci[0].Czesc[C].Nuta[N].Tekst), 1) <> ' ' then
+ Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[C].Nuta[N].Tekst + ' ';
+
+ end; // C
+end;
+
+procedure TScreenEditSub.FixTimings;
+var
+ C: integer;
+ S: integer;
+ Min: integer;
+ Max: integer;
+begin
+ for C := 1 to Czesci[0].High do begin
+ with Czesci[0].Czesc[C-1] do begin
+ Min := Nuta[HighNut].Start + Nuta[HighNut].Dlugosc;
+ Max := Czesci[0].Czesc[C].StartNote;
+ case (Max - Min) of
+ 0: S := Max;
+ 1: S := Max;
+ 2: S := Max - 1;
+ 3..3: S := Max - 2;
+ 4..10000: S := Min + 2; // poczatek + 2
+ end; // case
+
+ Czesci[0].Czesc[C].Start := S;
+ end; // with
+ end; // for
+end;
+
+procedure TScreenEditSub.DivideSentence;
+var
+ C: integer;
+ CStart: integer;
+ CNew: integer;
+ CLen: integer;
+ N: integer;
+ NStart: integer;
+ NHigh: integer;
+ NNewL: integer;
+begin
+ // increase sentence length by 1
+ CLen := Length(Czesci[0].Czesc);
+ SetLength(Czesci[0].Czesc, CLen + 1);
+ Inc(Czesci[0].Ilosc);
+ Inc(Czesci[0].High);
+
+ // move needed sentences to one forward. newly has the copy of divided sentence
+ CStart := Czesci[0].Akt;
+ for C := CLen-1 downto CStart do
+ Czesci[0].Czesc[C+1] := Czesci[0].Czesc[C];
+
+ // clear and set new sentence
+ CNew := CStart + 1;
+ NStart := AktNuta;
+ Czesci[0].Czesc[CNew].Start := Czesci[0].Czesc[CStart].Nuta[NStart].Start;
+ Czesci[0].Czesc[CNew].StartNote := Czesci[0].Czesc[CStart].Nuta[NStart].Start;
+ Czesci[0].Czesc[CNew].Lyric := '';
+ Czesci[0].Czesc[CNew].LyricWidth := 0;
+ Czesci[0].Czesc[CNew].Koniec := 0;
+ Czesci[0].Czesc[CNew].BaseNote := 0; // 0.5.0: we modify it later in this procedure
+ Czesci[0].Czesc[CNew].IlNut := 0;
+ Czesci[0].Czesc[CNew].HighNut := -1;
+ SetLength(Czesci[0].Czesc[CNew].Nuta, 0);
+
+ // move right notes to new sentences
+ NHigh := Czesci[0].Czesc[CStart].HighNut;
+ for N := NStart to NHigh do begin
+ NNewL := Czesci[0].Czesc[CNew].IlNut;
+ SetLength(Czesci[0].Czesc[CNew].Nuta, NNewL + 1);
+ Czesci[0].Czesc[CNew].Nuta[NNewL] := Czesci[0].Czesc[CStart].Nuta[N];
+
+ // increase sentence counters
+ Inc(Czesci[0].Czesc[CNew].IlNut);
+ Inc(Czesci[0].Czesc[CNew].HighNut);
+ Czesci[0].Czesc[CNew].Koniec := Czesci[0].Czesc[CNew].Nuta[NNewL].Start +
+ Czesci[0].Czesc[CNew].Nuta[NNewL].Dlugosc;
+ end;
+
+ // clear old notes and set sentence counters
+ Czesci[0].Czesc[CStart].HighNut := NStart - 1;
+ Czesci[0].Czesc[CStart].IlNut := Czesci[0].Czesc[CStart].HighNut + 1;
+ Czesci[0].Czesc[CStart].Koniec := Czesci[0].Czesc[CStart].Nuta[NStart-1].Start +
+ Czesci[0].Czesc[CStart].Nuta[NStart-1].Dlugosc;
+ SetLength(Czesci[0].Czesc[CStart].Nuta, Czesci[0].Czesc[CStart].IlNut);
+
+ // 0.5.0: modify BaseNote
+ Czesci[0].Czesc[CNew].BaseNote := 120;
+ for N := 0 to Czesci[0].Czesc[CNew].IlNut do
+ if Czesci[0].Czesc[CNew].Nuta[N].Ton < Czesci[0].Czesc[CNew].BaseNote then
+ Czesci[0].Czesc[CNew].BaseNote := Czesci[0].Czesc[CNew].Nuta[N].Ton;
+
+ Czesci[0].Akt := Czesci[0].Akt + 1;
+ AktNuta := 0;
+ Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Color := 1;
+ Lyric.AddCzesc(Czesci[0].Akt);
+
+end;
+
+procedure TScreenEditSub.JoinSentence;
+var
+ C: integer;
+ N: integer;
+ NStart: integer;
+ NDst: integer;
+begin
+ C := Czesci[0].Akt;
+
+ // set new sentence
+ NStart := Czesci[0].Czesc[C].IlNut;
+ Czesci[0].Czesc[C].IlNut := Czesci[0].Czesc[C].IlNut + Czesci[0].Czesc[C+1].IlNut;
+ Czesci[0].Czesc[C].HighNut := Czesci[0].Czesc[C].HighNut + Czesci[0].Czesc[C+1].IlNut;
+ SetLength(Czesci[0].Czesc[C].Nuta, Czesci[0].Czesc[C].IlNut);
+
+ // move right notes to new sentences
+ for N := 0 to Czesci[0].Czesc[C+1].HighNut do begin
+ NDst := NStart + N;
+ Czesci[0].Czesc[C].Nuta[NDst] := Czesci[0].Czesc[C+1].Nuta[N];
+ end;
+
+ // increase sentence counters
+ NDst := Czesci[0].Czesc[C].HighNut;
+ Czesci[0].Czesc[C].Koniec := Czesci[0].Czesc[C].Nuta[NDst].Start +
+ Czesci[0].Czesc[C].Nuta[NDst].Dlugosc;
+
+ // move needed sentences to one backward.
+ for C := Czesci[0].Akt + 1 to Czesci[0].High - 1 do
+ Czesci[0].Czesc[C] := Czesci[0].Czesc[C+1];
+
+ // increase sentence length by 1
+ SetLength(Czesci[0].Czesc, Length(Czesci[0].Czesc) - 1);
+ Dec(Czesci[0].Ilosc);
+ Dec(Czesci[0].High);
+end;
+
+procedure TScreenEditSub.DivideNote;
+var
+ C: integer;
+ N: integer;
+ NLen: integer;
+begin
+ C := Czesci[0].Akt;
+
+ NLen := Czesci[0].Czesc[C].IlNut + 1;
+ SetLength(Czesci[0].Czesc[C].Nuta, NLen);
+ Inc(Czesci[0].Czesc[C].HighNut);
+ Inc(Czesci[0].Czesc[C].IlNut);
+
+ // we copy all notes including selected one
+ for N := Czesci[0].Czesc[C].HighNut downto AktNuta+1 do begin
+ Czesci[0].Czesc[C].Nuta[N] := Czesci[0].Czesc[C].Nuta[N-1];
+ end;
+
+ // me slightly modify new note
+ Czesci[0].Czesc[C].Nuta[AktNuta].Dlugosc := 1;
+ Inc(Czesci[0].Czesc[C].Nuta[AktNuta+1].Start);
+ Dec(Czesci[0].Czesc[C].Nuta[AktNuta+1].Dlugosc);
+ Czesci[0].Czesc[C].Nuta[AktNuta+1].Tekst := '- ';
+ Czesci[0].Czesc[C].Nuta[AktNuta+1].Color := 0;
+end;
+
+procedure TScreenEditSub.DeleteNote;
+var
+ C: integer;
+ N: integer;
+ NLen: integer;
+begin
+ C := Czesci[0].Akt;
+
+ // we copy all notes from the next to the selected one
+ for N := AktNuta+1 to Czesci[0].Czesc[C].HighNut do begin
+ Czesci[0].Czesc[C].Nuta[N-1] := Czesci[0].Czesc[C].Nuta[N];
+ end;
+
+ NLen := Czesci[0].Czesc[C].IlNut - 1;
+ SetLength(Czesci[0].Czesc[C].Nuta, NLen);
+ Dec(Czesci[0].Czesc[C].HighNut);
+ Dec(Czesci[0].Czesc[C].IlNut);
+
+
+ // me slightly modify new note
+ if AktNuta > Czesci[0].Czesc[C].HighNut then Dec(AktNuta);
+ Czesci[0].Czesc[C].Nuta[AktNuta].Color := 1;
+end;
+
+procedure TScreenEditSub.TransposeNote(Transpose: integer);
+begin
+ Inc(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton, Transpose);
+end;
+
+procedure TScreenEditSub.ChangeWholeTone(Tone: integer);
+var
+ C: integer;
+ N: integer;
+begin
+ for C := 0 to Czesci[0].High do begin
+ Czesci[0].Czesc[C].BaseNote := Czesci[0].Czesc[C].BaseNote + Tone;
+ for N := 0 to Czesci[0].Czesc[C].HighNut do
+ Czesci[0].Czesc[C].Nuta[N].Ton := Czesci[0].Czesc[C].Nuta[N].Ton + Tone;
+ end;
+end;
+
+procedure TScreenEditSub.MoveAllToEnd(Move: integer);
+var
+ C: integer;
+ N: integer;
+ NStart: integer;
+begin
+ for C := Czesci[0].Akt to Czesci[0].High do begin
+ NStart := 0;
+ if C = Czesci[0].Akt then NStart := AktNuta;
+ for N := NStart to Czesci[0].Czesc[C].HighNut do begin
+ Inc(Czesci[0].Czesc[C].Nuta[N].Start, Move); // move note start
+
+ if N = 0 then begin // fix beginning
+ Inc(Czesci[0].Czesc[C].Start, Move);
+ Inc(Czesci[0].Czesc[C].StartNote, Move);
+ end;
+
+ if N = Czesci[0].Czesc[C].HighNut then // fix ending
+ Inc(Czesci[0].Czesc[C].Koniec, Move);
+
+ end; // for
+ end; // for
+end;
+
+procedure TScreenEditSub.MoveTextToRight;
+var
+ C: integer;
+ N: integer;
+ NHigh: integer;
+begin
+{ C := Czesci[0].Akt;
+
+ for N := Czesci[0].Czesc[C].HighNut downto 1 do begin
+ Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst;
+ end; // for
+
+ Czesci[0].Czesc[C].Nuta[0].Tekst := '- ';}
+
+ C := Czesci[0].Akt;
+ NHigh := Czesci[0].Czesc[C].HighNut;
+
+ // last word
+ Czesci[0].Czesc[C].Nuta[NHigh].Tekst := Czesci[0].Czesc[C].Nuta[NHigh-1].Tekst + Czesci[0].Czesc[C].Nuta[NHigh].Tekst;
+
+ // other words
+ for N := NHigh - 1 downto AktNuta + 1 do begin
+ Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[C].Nuta[N-1].Tekst;
+ end; // for
+ Czesci[0].Czesc[C].Nuta[AktNuta].Tekst := '- ';
+end;
+
+procedure TScreenEditSub.MarkSrc;
+begin
+ CopySrc := Czesci[0].Akt;
+end;
+
+procedure TScreenEditSub.PasteText;
+var
+ C: integer;
+ N: integer;
+begin
+ C := Czesci[0].Akt;
+
+ for N := 0 to Czesci[0].Czesc[CopySrc].HighNut do
+ Czesci[0].Czesc[C].Nuta[N].Tekst := Czesci[0].Czesc[CopySrc].Nuta[N].Tekst;
+end;
+
+procedure TScreenEditSub.CopySentence(Src, Dst: integer);
+var
+ N: integer;
+ Time1: integer;
+ Time2: integer;
+ TD: integer;
+begin
+ Time1 := Czesci[0].Czesc[Src].Nuta[0].Start;
+ Time2 := Czesci[0].Czesc[Dst].Nuta[0].Start;
+ TD := Time2-Time1;
+
+ SetLength(Czesci[0].Czesc[Dst].Nuta, Czesci[0].Czesc[Src].IlNut);
+ Czesci[0].Czesc[Dst].IlNut := Czesci[0].Czesc[Src].IlNut;
+ Czesci[0].Czesc[Dst].HighNut := Czesci[0].Czesc[Src].HighNut;
+ for N := 0 to Czesci[0].Czesc[Src].HighNut do begin
+ Czesci[0].Czesc[Dst].Nuta[N].Tekst := Czesci[0].Czesc[Src].Nuta[N].Tekst;
+ Czesci[0].Czesc[Dst].Nuta[N].Dlugosc := Czesci[0].Czesc[Src].Nuta[N].Dlugosc;
+ Czesci[0].Czesc[Dst].Nuta[N].Ton := Czesci[0].Czesc[Src].Nuta[N].Ton;
+ Czesci[0].Czesc[Dst].Nuta[N].Start := Czesci[0].Czesc[Src].Nuta[N].Start + TD;
+ end;
+ N := Czesci[0].Czesc[Src].HighNut;
+ Czesci[0].Czesc[Dst].Koniec := Czesci[0].Czesc[Dst].Nuta[N].Start + Czesci[0].Czesc[Dst].Nuta[N].Dlugosc;
+end;
+
+procedure TScreenEditSub.CopySentences(Src, Dst, Num: integer);
+var
+ C: integer;
+begin
+ // create place for new sentences
+ SetLength(Czesci[0].Czesc, Czesci[0].Ilosc + Num - 1);
+
+ // moves sentences next to the destination
+ for C := Czesci[0].High downto Dst + 1 do begin
+ Czesci[0].Czesc[C + Num - 1] := Czesci[0].Czesc[C];
+ end;
+
+ // prepares new sentences: sets sentence start and create first note
+ for C := 1 to Num-1 do begin
+ Czesci[0].Czesc[Dst + C].Start := Czesci[0].Czesc[Dst + C - 1].StartNote +
+ (Czesci[0].Czesc[Src + C].StartNote - Czesci[0].Czesc[Src + C - 1].StartNote);
+ SetLength(Czesci[0].Czesc[Dst + C].Nuta, 1);
+ Czesci[0].Czesc[Dst + C].IlNut := 1;
+ Czesci[0].Czesc[Dst + C].HighNut := 0;
+ Czesci[0].Czesc[Dst + C].Nuta[0].Start := Czesci[0].Czesc[Dst + C].Start;
+ Czesci[0].Czesc[Dst + C].Nuta[0].Dlugosc := 1;
+ Czesci[0].Czesc[Dst + C].StartNote := Czesci[0].Czesc[Dst + C].Start;
+ Czesci[0].Czesc[Dst + C].Koniec := Czesci[0].Czesc[Dst + C].Start + 1;
+ end;
+
+ // increase counters
+ Czesci[0].Ilosc := Czesci[0].Ilosc + Num - 1;
+ Czesci[0].High := Czesci[0].High + Num - 1;
+
+ for C := 0 to Num-1 do
+ CopySentence(Src + C, Dst + C);
+end;
+
+
+constructor TScreenEditSub.Create(Back: String);
+begin
+ inherited Create(Back);
+ SetLength(Player, 1);
+
+ // linijka
+ AddStatic(20, 10, 80, 30, 0, 0, 0, Skin.GetTextureFileName('ButtonF'), 'JPG', 'Font Black');
+ AddText(40, 17, 1, 6, 1, 1, 1, 'Line');
+ TextSentence := AddText(120, 14, 1, 8, 0, 0, 0, '0 / 0');
+
+ // nuta
+ AddStatic(220, 10, 80, 30, 0, 0, 0, Skin.GetTextureFileName('ButtonF'), 'JPG', 'Font Black');
+ AddText(242, 17, 1, 6, 1, 1, 1, 'Note');
+ TextNote := AddText(320, 14, 1, 8, 0, 0, 0, '0 / 0');
+
+ // file info
+ AddStatic(150, 50, 500, 150, 0, 0, 0, Skin.GetTextureFileName('Bar'), 'JPG', 'Font Black');
+ AddStatic(151, 52, 498, 146, 1, 1, 1, Skin.GetTextureFileName('Bar'), 'JPG', 'Font Black');
+ AddText(180, 65, 0, 8, 0, 0, 0, 'Title:');
+ AddText(180, 90, 0, 8, 0, 0, 0, 'Artist:');
+ AddText(180, 115, 0, 8, 0, 0, 0, 'Mp3:');
+ AddText(180, 140, 0, 8, 0, 0, 0, 'BPM:');
+ AddText(180, 165, 0, 8, 0, 0, 0, 'GAP:');
+
+ TextTitle := AddText(250, 65, 0, 8, 0, 0, 0, 'a');
+ TextArtist := AddText(250, 90, 0, 8, 0, 0, 0, 'b');
+ TextMp3 := AddText(250, 115, 0, 8, 0, 0, 0, 'c');
+ TextBPM := AddText(250, 140, 0, 8, 0, 0, 0, 'd');
+ TextGAP := AddText(250, 165, 0, 8, 0, 0, 0, 'e');
+
+{ AddInteraction(2, TextTitle);
+ AddInteraction(2, TextArtist);
+ AddInteraction(2, TextMp3);
+ AddInteraction(2, TextBPM);
+ AddInteraction(2, TextGAP);}
+
+ // note info
+ AddText(20, 190, 0, 8, 0, 0, 0, 'Start:');
+ AddText(20, 215, 0, 8, 0, 0, 0, 'Duration:');
+ AddText(20, 240, 0, 8, 0, 0, 0, 'Tone:');
+ AddText(20, 265, 0, 8, 0, 0, 0, 'Text:');
+
+ TextNStart := AddText(120, 190, 0, 8, 0, 0, 0, 'a');
+ TextNDlugosc := AddText(120, 215, 0, 8, 0, 0, 0, 'b');
+ TextNTon := AddText(120, 240, 0, 8, 0, 0, 0, 'c');
+ TextNText := AddText(120, 265, 0, 8, 0, 0, 0, 'd');
+
+ // debug
+ TextDebug := AddText(30, 550, 0, 8, 0, 0, 0, '');
+
+end;
+
+procedure TScreenEditSub.onShow;
+begin
+ Log.LogStatus('Initializing', 'TEditScreen.onShow');
+
+ MidiOut := TMidiOutput.Create(nil);
+ if Ini.Debug = 1 then
+ MidiOut.ProductName := 'Microsoft GS Wavetable SW Synth'; // for my kxproject without midi table
+ MidiOut.Open;
+
+
+
+ CzyscNuty;
+ if WczytajCzesci(Path + FileName) = false then
+// if WczytajCzesci(SongPath + 'Zapis.txt') = false then
+ Text[TextTitle].Text := 'Error loading file'
+ else begin
+ Text[TextTitle].Text := AktSong.Title;
+ Text[TextArtist].Text := AktSong.Artist;
+ Text[TextMp3].Text := AktSong.Mp3;
+
+ Czesci[0].Akt := 0;
+ AktNuta := 0;
+ Czesci[0].Czesc[0].Nuta[0].Color := 1;
+
+ Music.Open(Path + AktSong.Mp3);
+
+ Lyric.Clear;
+ Lyric.X := 400;
+ Lyric.Y := 500;
+ Lyric.Align := 1;
+ Lyric.Size := 14;
+ Lyric.ColR := 0;
+ Lyric.ColG := 0;
+ Lyric.ColB := 0;
+ Lyric.ColSR := Skin_FontHighlightR;
+ Lyric.ColSG := Skin_FontHighlightG;
+ Lyric.ColSB := Skin_FontHighlightB;
+ Lyric.Style := 0;
+ Lyric.AddCzesc(0);
+ Lyric.Selected := 0;
+
+ NotesH := 7;
+ NotesW := 4;
+
+ end;
+
+// Interaction := 0;
+ TextEditMode := false;
+end;
+
+function TScreenEditSub.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ Pet: integer;
+ AktBeat: integer;
+begin
+ glClearColor(1,1,1,1);
+
+ // midi music
+ if PlaySentenceMidi then begin
+ MidiPos := USTime.GetTime - MidiTime + MidiStart;
+
+ // stop the music
+ if (MidiPos > MidiStop) then begin
+ MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[MidiLastNote].Ton + 60, 127);
+ PlaySentenceMidi := false;
+ end;
+
+ // click
+ AktBeat := Floor(GetMidBeat(MidiPos - AktSong.GAP / 1000));
+ Text[TextDebug].Text := IntToStr(AktBeat);
+
+ if AktBeat <> LastClick then begin
+ for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
+ if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then begin
+
+ LastClick := AktBeat;
+ if Pet > 0 then
+ MidiOut.PutShort($81, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet-1].Ton + 60, 127);
+ MidiOut.PutShort($91, Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Ton + 60, 127);
+ MidiLastNote := Pet;
+
+ end;
+ end;
+ end; // if PlaySentenceMidi
+
+ // mp3 music
+ if PlaySentence then begin
+ // stop the music
+ if (Music.Position > PlayStopTime) then begin
+ Music.Stop;
+ PlaySentence := false;
+ end;
+
+ // click
+ if (Click) and (PlaySentence) then begin
+// AktBeat := Floor(AktSong.BPM[0].BPM * (Music.Position - AktSong.GAP / 1000) / 60);
+ AktBeat := Floor(GetMidBeat(Music.Position - AktSong.GAP / 1000));
+ Text[TextDebug].Text := IntToStr(AktBeat);
+ if AktBeat <> LastClick then begin
+ for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
+ if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = AktBeat) then begin
+ Music.PlayClick;
+ LastClick := AktBeat;
+ end;
+ end;
+ end; // click
+ end; // if PlaySentence
+
+
+ Text[TextSentence].Text := IntToStr(Czesci[0].Akt + 1) + ' / ' + IntToStr(Czesci[0].Ilosc);
+ Text[TextNote].Text := IntToStr(AktNuta + 1) + ' / ' + IntToStr(Czesci[0].Czesc[Czesci[0].Akt].IlNut);
+
+ // Song info
+ Text[TextBPM].Text := FloatToStr(AktSong.BPM[0].BPM / 4);
+ Text[TextGAP].Text := FloatToStr(AktSong.GAP);
+
+ // Note info
+ Text[TextNStart].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Start);
+ Text[TextNDlugosc].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Dlugosc);
+ Text[TextNTon].Text := IntToStr(Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Ton);
+ Text[TextNText].Text := Czesci[0].Czesc[Czesci[0].Akt].Nuta[AktNuta].Tekst;
+
+ // Text Edit Mode
+ if TextEditMode then
+ Text[TextNText].Text := Text[TextNText].Text + '|';
+
+ // draw static menu
+ inherited Draw;
+
+ // draw notes
+ SingDrawNoteLines(20, 300, 780, 15);
+ SingDrawBeatDelimeters(40, 300, 760, 0);
+ EditDrawCzesc(40, 405, 760, 0, 15);
+
+ // draw text
+ Lyric.Draw;
+
+end;
+
+procedure TScreenEditSub.onHide;
+begin
+ MidiOut.Close;
+ MidiOut.Free;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenLevel.dcu b/Game/Code/Screens/UScreenLevel.dcu
new file mode 100644
index 00000000..95cb3267
--- /dev/null
+++ b/Game/Code/Screens/UScreenLevel.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenLevel.pas b/Game/Code/Screens/UScreenLevel.pas
new file mode 100644
index 00000000..28aa40ea
--- /dev/null
+++ b/Game/Code/Screens/UScreenLevel.pas
@@ -0,0 +1,101 @@
+unit UScreenLevel;
+
+interface
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UPliki, SysUtils, UThemes;
+
+type
+ TScreenLevel = class(TMenu)
+ public
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic, UMain, UIni, UTexture;
+
+function TScreenLevel.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 :
+ begin
+ Music.PlayBack;
+ FadeTo(@ScreenName);
+ end;
+
+ SDLK_RETURN:
+ begin
+ Ini.Difficulty := Interaction;
+ Ini.SaveLevel;
+ Music.PlayStart;
+ //Set Standard Mode
+ ScreenSong.Mode := 0;
+ FadeTo(@ScreenSong);
+ 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: InteractNext;
+ SDLK_UP: InteractPrev;
+ SDLK_RIGHT: InteractNext;
+ SDLK_LEFT: InteractPrev;
+ end;
+ end
+ else // Key Up
+ case PressedKey of
+ SDLK_RETURN :
+ begin
+ end;
+ end;
+end;
+
+constructor TScreenLevel.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ AddBackground(Theme.Level.Background.Tex);
+
+ AddButton(Theme.Level.ButtonEasy);
+ AddButton(Theme.Level.ButtonMedium);
+ AddButton(Theme.Level.ButtonHard);
+
+ for I := 0 to High(Theme.Level.Static) do
+ AddStatic(Theme.Level.Static[I]);
+
+ for I := 0 to High(Theme.Level.Text) do
+ AddText(Theme.Level.Text[I]);
+
+ Interaction := 0;
+end;
+
+procedure TScreenLevel.onShow;
+begin
+ Interaction := Ini.Difficulty;
+
+// LCD.WriteText(1, ' Choose mode: ');
+// UpdateLCD;
+end;
+
+procedure TScreenLevel.SetAnimationProgress(Progress: real);
+begin
+ Button[0].Texture.ScaleW := Progress;
+ Button[1].Texture.ScaleW := Progress;
+ Button[2].Texture.ScaleW := Progress;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenLoading.dcu b/Game/Code/Screens/UScreenLoading.dcu
new file mode 100644
index 00000000..e0eb1cfe
--- /dev/null
+++ b/Game/Code/Screens/UScreenLoading.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenLoading.pas b/Game/Code/Screens/UScreenLoading.pas
new file mode 100644
index 00000000..05b308ac
--- /dev/null
+++ b/Game/Code/Screens/UScreenLoading.pas
@@ -0,0 +1,48 @@
+unit UScreenLoading;
+
+interface
+
+uses
+ UMenu, SDL, SysUtils, UThemes;
+
+type
+ TScreenLoading = class(TMenu)
+ public
+ Fadeout: boolean;
+ constructor Create(Back: String); override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ end;
+
+implementation
+
+uses UGraphic, UTime;
+
+function TScreenLoading.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+end;
+
+constructor TScreenLoading.Create(Back: String);
+var
+ I: integer;
+begin
+ inherited Create(Back);
+
+ AddBackground(Theme.Loading.Background.Tex);
+
+ for I := 0 to High(Theme.Loading.Static) do
+ AddStatic(Theme.Loading.Static[I]);
+
+ for I := 0 to High(Theme.Loading.Text) do
+ AddText(Theme.Loading.Text[I]);
+
+ Fadeout := false;
+end;
+
+procedure TScreenLoading.onShow;
+begin
+// nothing
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenMain.dcu b/Game/Code/Screens/UScreenMain.dcu
new file mode 100644
index 00000000..22bb4883
--- /dev/null
+++ b/Game/Code/Screens/UScreenMain.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenMain.pas b/Game/Code/Screens/UScreenMain.pas
new file mode 100644
index 00000000..dcd7db26
--- /dev/null
+++ b/Game/Code/Screens/UScreenMain.pas
@@ -0,0 +1,384 @@
+unit UScreenMain;
+
+interface
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UPliki, SysUtils, UThemes, ULCD, ULight;
+
+type
+ TScreenMain = class(TMenu)
+ public
+ TextDescription: integer;
+ TextDescriptionLong: integer;
+
+ //Credits Mod
+ Credits_Visible: Boolean;
+ Credits_Y: Real;
+ Credits_Time: Cardinal;
+ Credits_Alpha: Cardinal;
+ procedure DrawCredits;
+ //Credits Mod End
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure InteractNext; override;
+ procedure InteractPrev; override;
+ procedure UpdateLCD;
+ procedure SetAnimationProgress(Progress: real); override;
+ function Draw: boolean; override;
+ end;
+
+const Credits_Text: Array[0..46] of PChar = (
+ ':SPACE:',
+ 'Main Idea: Corvus 5',
+ 'Thank you very much for this great Game',
+ ':SPACE:',
+ 'The Ultrastar Deluxe Team:',
+ ':SPACE:',
+ 'commandi00:',
+ 'Beta Testing',
+ ':SPACE:',
+ 'Crazy Joker:',
+ 'Graphics',
+ ':SPACE:',
+ 'DennistheMenace:',
+ 'Beta Testing and great Support in "the Board"',
+ ':SPACE:',
+ 'Moq/Moguhguh:',
+ 'Programming',
+ ':SPACE:',
+ 'Mota:',
+ 'Programming, Idea of creating this Mod, Team Leading',
+ ':SPACE:',
+ 'Sawyer:',
+ 'Web Master, Programming',
+ ':SPACE:',
+ 'Whiteshark:',
+ 'Programming, Creating Release',
+ ':SPACE:',
+ ':SPACE:',
+ 'Thanks to',
+ ':SPACE:',
+ 'Blind Guard',
+ 'for supporting us and administrate this great Board',
+ ':SPACE:',
+ 'The whole Community from www.ultra-star.dl.am',
+ 'for supporting us, supporting the newbies',
+ 'and remembering us to continue work',
+ ':SPACE:',
+ 'You',
+ 'for using Ultrastar Deluxe',
+ ':SPACE:',
+ ':SPACE:',
+ 'Visit us at:',
+ 'http://www.UltraStar-Deluxe.de.vu',
+ 'http://www.USD.de.vu',
+ 'http://www.Ultra-Star.dl.am ("The Board" by Blind Guard)',
+ 'Please write Bug Reports and Feature Requests',
+ 'to help making this a better Game');
+
+
+implementation
+
+uses Windows, UGraphic, UMain, UIni, UTexture, USongs, Textgl, opengl, ULanguage, UParty;
+
+
+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 :
+ begin
+ Result := False;
+ end;
+
+ SDLK_C:
+ begin
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ Credits_Y := 600;
+ Credits_Alpha := 0;
+ Credits_Visible := True;
+ end;
+ end;
+ SDLK_M:
+ begin
+ if (SDL_ModState = KMOD_LALT) then
+ begin
+ //Create Teams:
+ PartySession.Teams.NumTeams := 3;
+ //Team 1
+ PartySession.Teams.Teaminfo[0].Name := 'Team 1';
+ PartySession.Teams.Teaminfo[0].Score:= 0;
+ PartySession.Teams.Teaminfo[0].Joker := 3;
+ PartySession.Teams.Teaminfo[0].CurPlayer := 0;
+ PartySession.Teams.Teaminfo[0].NumPlayers := 2;
+ PartySession.Teams.Teaminfo[0].Playerinfo[0].Name := 'Player 1';
+ PartySession.Teams.Teaminfo[0].Playerinfo[0].TimesPlayed := 0;
+ PartySession.Teams.Teaminfo[0].Playerinfo[1].Name := 'Player 2';
+ PartySession.Teams.Teaminfo[0].Playerinfo[1].TimesPlayed := 0;
+
+ //Team 2
+ PartySession.Teams.Teaminfo[1].Name := 'Team 2';
+ PartySession.Teams.Teaminfo[1].Score:= 0;
+ PartySession.Teams.Teaminfo[1].Joker := 3;
+ PartySession.Teams.Teaminfo[1].CurPlayer := 0;
+ PartySession.Teams.Teaminfo[1].NumPlayers := 2;
+ PartySession.Teams.Teaminfo[1].Playerinfo[0].Name := 'Player 3';
+ PartySession.Teams.Teaminfo[1].Playerinfo[0].TimesPlayed := 0;
+ PartySession.Teams.Teaminfo[1].Playerinfo[1].Name := 'Player 4';
+ PartySession.Teams.Teaminfo[1].Playerinfo[1].TimesPlayed := 0;
+
+ //Team 3
+ PartySession.Teams.Teaminfo[2].Name := 'Team 3';
+ PartySession.Teams.Teaminfo[2].Score:= 0;
+ PartySession.Teams.Teaminfo[2].Joker := 3;
+ PartySession.Teams.Teaminfo[2].CurPlayer := 0;
+ PartySession.Teams.Teaminfo[2].NumPlayers := 2;
+ PartySession.Teams.Teaminfo[2].Playerinfo[0].Name := 'Player 5';
+ PartySession.Teams.Teaminfo[2].Playerinfo[0].TimesPlayed := 0;
+ PartySession.Teams.Teaminfo[2].Playerinfo[1].Name := 'Player 6';
+ PartySession.Teams.Teaminfo[2].Playerinfo[1].TimesPlayed := 0;
+
+ //Rounds:
+ SetLength (PartySession.Rounds, 3);
+ PartySession.Rounds[0].Plugin := 1;
+ PartySession.Rounds[0].Winner := 0;
+ PartySession.Rounds[1].Plugin := 0;
+ PartySession.Rounds[1].Winner := 0;
+ PartySession.Rounds[2].Plugin := 0;
+ PartySession.Rounds[2].Winner := 0;
+
+ //Start Party
+ PartySession.StartNewParty;
+ //Change Screen
+ Music.PlayStart;
+ FadeTo(@ScreenPartyNewRound);
+
+ end
+ else
+ begin
+ Music.PlayStart;
+ FadeTo(@ScreenPartyOptions);
+ end;
+
+ end;
+
+ SDLK_RETURN:
+ begin
+ if (Interaction = 0) and (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;
+ FadeTo(@ScreenName);
+ end;
+ if Interaction = 1 then begin
+ Music.PlayStart;
+ FadeTo(@ScreenEdit);
+ end;
+ if Interaction = 2 then begin
+ Music.PlayStart;
+ FadeTo(@ScreenOptions);
+// SDL_SetVideoMode(800, 600, 32, SDL_OPENGL);// or SDL_FULLSCREEN);
+// LoadTextures;
+ end;
+ if Interaction = 3 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: InteractNext;
+ SDLK_UP: InteractPrev;
+ 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;
+
+// AddButton(400-200, 320, 400, 60, Skin.GameStart);
+// AddButton(400-200, 390, 400, 60, Skin.Editor);
+// AddButton(400-200, 460, 400, 60, Skin.Options);
+// AddButton(400-200, 530, 400, 60, Skin.Exit);
+
+ AddBackground(Theme.Main.Background.Tex);
+
+ AddButton(Theme.Main.ButtonSolo);
+ AddButton(Theme.Main.ButtonEditor);
+ AddButton(Theme.Main.ButtonOptions);
+ AddButton(Theme.Main.ButtonExit);
+
+ for I := 0 to High(Theme.Main.Static) do
+ AddStatic(Theme.Main.Static[I]);
+
+ for I := 0 to High(Theme.Main.Text) do
+ AddText(Theme.Main.Text[I]);
+
+ TextDescription := AddText(Theme.Main.TextDescription);
+ TextDescriptionLong := AddText(Theme.Main.TextDescriptionLong);
+
+ 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.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;
+
+function TScreenMain.Draw: boolean;
+begin
+Result := True;
+if Credits_Visible then
+ DrawCredits
+else
+ Result := inherited Draw;
+end;
+
+procedure TScreenMain.DrawCredits;
+var
+ T, I: Cardinal;
+ Y: Real;
+ Ver: PChar;
+begin
+ T := GetTickCount div 33;
+ if T <> Credits_Time then
+ begin
+ Credits_Time := T;
+ //Change Position
+ Credits_Y := Credits_Y - 1;
+ //Change Alpha
+ Inc (Credits_Alpha, 3);
+ end;
+
+ //Draw BackGround
+ DrawBG;
+
+
+ //Draw pulsing Credits Text
+ //Set Font
+ SetFontStyle (2);
+ SetFontItalic(False);
+ SetFontSize(9);
+ SetFontPos (460, 570);
+ glColor4f(1, 0, 0, 0.2 + Abs((Credits_Alpha mod 150)/100 - 0.75));
+ glPrint ('Credits! Press any Key to Continue');
+
+ //Set Font Size for Credits
+ SetFontSize(12);
+ //Draw Version
+ if (Credits_Y>-35) then
+ begin
+ Ver := PChar(Language.Translate('US_VERSION'));
+ glColor4f(1, 0.6, 0.08, 0.8);
+ SetFontPos (400 - glTextWidth(Ver)/2, Credits_Y);
+ glprint(Ver);
+ end;
+
+ //Set Color + Start Pos
+ glColor4f(0.8, 0.8, 1, 0.8);
+ Y := Credits_Y + 50;
+
+ //Search upper Position
+ For I := 0 to high(Credits_Text) do
+ begin
+ if (Credits_Text[I]=':SPACE:') then //Spacer
+ Y := Y + 55
+ else
+ Y := Y + 30;
+
+ if Y > -35 then
+ break;
+ end;
+
+ //Draw Text
+ For T := I+1 to high(Credits_Text) do
+ begin
+ if (Credits_Text[T]=':SPACE:') then //Spacer
+ Y := Y + 55
+ else
+ begin
+ SetFontPos (400 - glTextWidth(Credits_Text[T])/2, Y);
+ glprint(Credits_Text[T]);
+ Y := Y + 30;
+ end;
+
+ if Y > 600 then
+ break;
+ end;
+
+ //If lower Position is outside the Screen-> Show MainMenu
+ if (Y <= 0) then
+ Credits_Visible := False;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenName.dcu b/Game/Code/Screens/UScreenName.dcu
new file mode 100644
index 00000000..d14b4296
--- /dev/null
+++ b/Game/Code/Screens/UScreenName.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenName.pas b/Game/Code/Screens/UScreenName.pas
new file mode 100644
index 00000000..99f5d40a
--- /dev/null
+++ b/Game/Code/Screens/UScreenName.pas
@@ -0,0 +1,114 @@
+unit UScreenName;
+
+interface
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UPliki, SysUtils, UThemes;
+
+type
+ TScreenName = class(TMenu)
+ public
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic, UMain, UIni, UTexture;
+
+function TScreenName.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+var
+ I: integer;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_0..SDLK_9, SDLK_A..SDLK_Z, SDLK_SPACE, SDLK_MINUS, SDLK_EXCLAIM, SDLK_COMMA, SDLK_SLASH, SDLK_ASTERISK, SDLK_QUESTION, SDLK_QUOTE, SDLK_QUOTEDBL:
+ begin
+ Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + chr(ScanCode);
+ end;
+
+ SDLK_BACKSPACE:
+ begin
+ Delete(Button[Interaction].Text[0].Text,
+ Length(Button[Interaction].Text[0].Text), 1);
+ end;
+
+ SDLK_ESCAPE :
+ begin
+ Ini.SaveNames;
+ Music.PlayBack;
+ FadeTo(@ScreenMain);
+ end;
+
+ SDLK_RETURN:
+ begin
+ for I := 1 to 6 do
+ Ini.Name[I-1] := Button[I-1].Text[0].Text;
+ Ini.SaveNames;
+ Music.PlayStart;
+ FadeTo(@ScreenLevel);
+ 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: InteractNext;
+ SDLK_UP: InteractPrev;
+ SDLK_RIGHT: InteractNext;
+ SDLK_LEFT: InteractPrev;
+ end;
+ end;
+end;
+
+constructor TScreenName.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ AddBackground(Theme.Name.Background.Tex);
+
+ for I := 1 to 6 do
+ AddButton(Theme.Name.ButtonPlayer[I]);
+
+ for I := 0 to High(Theme.Name.Static) do
+ AddStatic(Theme.Name.Static[I]);
+
+ for I := 0 to High(Theme.Name.Text) do
+ AddText(Theme.Name.Text[I]);
+
+ Interaction := 0;
+end;
+
+procedure TScreenName.onShow;
+var
+ I: integer;
+begin
+ for I := 1 to 6 do
+ Button[I-1].Text[0].Text := Ini.Name[I-1];
+
+ for I := 1 to PlayersPlay do begin
+ Button[I-1].Visible := true;
+ Button[I-1].Selectable := true;
+ end;
+
+ for I := PlayersPlay+1 to 6 do begin
+ Button[I-1].Visible := false;
+ Button[I-1].Selectable := false;
+ end;
+
+end;
+
+procedure TScreenName.SetAnimationProgress(Progress: real);
+var
+ I: integer;
+begin
+ for I := 1 to 6 do
+ Button[I-1].Texture.ScaleW := Progress;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenOpen.dcu b/Game/Code/Screens/UScreenOpen.dcu
new file mode 100644
index 00000000..c59986f9
--- /dev/null
+++ b/Game/Code/Screens/UScreenOpen.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenOpen.pas b/Game/Code/Screens/UScreenOpen.pas
new file mode 100644
index 00000000..723f299f
--- /dev/null
+++ b/Game/Code/Screens/UScreenOpen.pas
@@ -0,0 +1,151 @@
+unit UScreenOpen;
+
+interface
+
+uses UMenu, UMusic, SDL, SysUtils, UPliki, UTime, USongs, UIni, ULog, USmpeg, UTexture, UMenuText,
+ ULyrics, Math, OpenGL12, UThemes;
+
+type
+ TScreenOpen = class(TMenu)
+ private
+ TextF: array[0..1] of integer;
+ TextN: integer;
+ public
+ Tex_Background: TTexture;
+ FadeOut: boolean;
+ Path: string;
+ BackScreen: pointer;
+ procedure AddBox(X, Y, W, H: real);
+ constructor Create(Back: String); override;
+ procedure onShow; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+// function Draw: boolean; override;
+// procedure Finish;
+ end;
+
+implementation
+uses UGraphic, UDraw, UMain, USkins;
+
+function TScreenOpen.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ if (PressedDown) then begin // Key Down
+ case ScanCode of
+ ord('a')..ord('z'), ord('A')..ord('Z'), ord('0')..ord('9'), 32, ord('-'), ord('.'), ord(':'), ord('\'):
+ begin
+ if Interaction = 0 then begin
+ Text[TextN].Text := Text[TextN].Text + chr(ScanCode);
+ FileName := Text[TextN].Text;
+ end;
+ end;
+ end;
+
+ case PressedKey of
+ 8: // del
+ begin
+ if Interaction = 0 then
+ if Length(Text[TextN].Text) >= 1 then begin
+ Delete(Text[TextN].Text, Length(Text[TextN].Text), 1);
+ FileName := Text[TextN].Text;
+ end;
+ end;
+
+ SDLK_ESCAPE:
+ begin
+ result := false;
+ end;
+
+ SDLK_RETURN:
+ begin
+ if Interaction = 2 then begin
+ Music.PlayBack;
+ FadeTo(BackScreen);
+ end;
+ end;
+
+ SDLK_LEFT:
+ begin
+ InteractPrev;
+ end;
+
+ SDLK_RIGHT:
+ begin
+ InteractNext;
+ end;
+
+ SDLK_DOWN:
+ begin
+ end;
+
+ SDLK_UP:
+ begin
+ end;
+ end;
+ end;
+end;
+
+procedure TScreenOpen.AddBox(X, Y, W, H: real);
+begin
+ AddStatic(X, Y, W, H, 0, 0, 0, Skin.GetTextureFileName('Bar'), 'JPG', 'Font Black');
+ AddStatic(X+2, Y+2, W-4, H-4, 1, 1, 1, Skin.GetTextureFileName('Bar'), 'JPG', 'Font Black');
+end;
+
+constructor TScreenOpen.Create(Back: String);
+begin
+ inherited Create(Back);
+
+ // linijka
+{ AddStatic(20, 10, 80, 30, 0, 0, 0, 'Bar', 'JPG', 'Font Black');
+ AddText(35, 17, 1, 6, 1, 1, 1, 'Linijka');
+ TextSentence := AddText(120, 14, 1, 8, 0, 0, 0, '0 / 0');}
+
+ // file list
+// AddBox(400, 100, 350, 450);
+
+// TextF[0] := AddText(430, 155, 0, 8, 0, 0, 0, 'a');
+// TextF[1] := AddText(430, 180, 0, 8, 0, 0, 0, 'a');
+
+ // file name
+ AddBox(20, 540, 500, 40);
+ TextN := AddText(50, 548, 0, 8, 0, 0, 0, FileName);
+ AddInteraction(iText, TextN);
+
+ // buttons
+ {AddButton(540, 540, 100, 40, Skin.SkinPath + Skin.ButtonF);
+ AddButtonText(10, 5, 0, 0, 0, 'Cancel');
+
+ AddButton(670, 540, 100, 40, Skin.SkinPath + Skin.ButtonF);
+ AddButtonText(30, 5, 0, 0, 0, 'OK');}
+ // buttons
+ AddButton(540, 540, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(10, 5, 0, 0, 0, 'Cancel');
+
+ AddButton(670, 540, 100, 40, Skin.GetTextureFileName('ButtonF'));
+ AddButtonText(30, 5, 0, 0, 0, 'OK');
+
+
+end;
+
+procedure TScreenOpen.onShow;
+begin
+ Interaction := 0;
+end;
+
+(*function TScreenEditSub.Draw: boolean;
+var
+ Min: integer;
+ Sec: integer;
+ Tekst: string;
+ Pet: integer;
+ AktBeat: integer;
+begin
+
+end;
+
+procedure TScreenEditSub.Finish;
+begin
+//
+end;*)
+
+end.
+
diff --git a/Game/Code/Screens/UScreenOptions.dcu b/Game/Code/Screens/UScreenOptions.dcu
new file mode 100644
index 00000000..e5d17c3b
--- /dev/null
+++ b/Game/Code/Screens/UScreenOptions.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenOptions.pas b/Game/Code/Screens/UScreenOptions.pas
new file mode 100644
index 00000000..76ff2adc
--- /dev/null
+++ b/Game/Code/Screens/UScreenOptions.pas
@@ -0,0 +1,221 @@
+unit UScreenOptions;
+
+interface
+
+uses
+ UMenu, SDL, SysUtils, UDisplay, UMusic, UPliki, UIni, UThemes;
+
+type
+ TScreenOptions = class(TMenu)
+ public
+ TextDescription: integer;
+ constructor Create(Back: String); override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure InteractNext; override;
+ procedure InteractPrev; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic;
+
+function TScreenOptions.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:
+ begin
+ Ini.Save;
+ Music.PlayBack;
+ FadeTo(@ScreenMain);
+ end;
+ SDLK_RETURN:
+ begin
+ if SelInteraction = 0 then begin
+ Music.PlayStart;
+ FadeTo(@ScreenOptionsGame);
+ end;
+
+ if SelInteraction = 1 then begin
+ Music.PlayStart;
+ FadeTo(@ScreenOptionsGraphics);
+ end;
+
+ if SelInteraction = 2 then begin
+ Music.PlayStart;
+ FadeTo(@ScreenOptionsSound);
+ end;
+
+ if SelInteraction = 3 then begin
+ Music.PlayStart;
+ FadeTo(@ScreenOptionsLyrics);
+ end;
+
+ if SelInteraction = 4 then begin
+ Music.PlayStart;
+ FadeTo(@ScreenOptionsThemes);
+ end;
+
+ if SelInteraction = 5 then begin
+ Music.PlayStart;
+ FadeTo(@ScreenOptionsRecord);
+ end;
+
+ if SelInteraction = 6 then begin
+ Ini.Save;
+ Music.PlayBack;
+ FadeTo(@ScreenMain);
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ {case SelInteraction of
+ 0: InteractCustom(+2);
+ 1: InteractCustom(-1);
+ 2: InteractCustom(-1);
+ 3: InteractCustom(+2);
+ 4: InteractCustom(-1);
+ 5: InteractCustom(-1);
+ end;}
+ InteractPrev;
+ end;
+ SDLK_RIGHT:
+ begin
+ {case SelInteraction of
+ 0: InteractCustom(+1);
+ 1: InteractCustom(+1);
+ 2: InteractCustom(-2);
+ 3: InteractCustom(+1);
+ 4: InteractCustom(+1);
+ 5: InteractCustom(-2);
+ end;}
+ InteractNext;
+ end;
+ SDLK_UP:
+ begin
+ InteractPrev;
+ {case SelInteraction of
+ 0: InteractCustom(+3);
+ 1: InteractCustom(+3);
+ 2: InteractCustom(+3);
+ 3: InteractCustom(-3);
+ 4: InteractCustom(-3);
+ 5: InteractCustom(-3);
+ end; }
+ end;
+ SDLK_DOWN:
+ begin
+ {case SelInteraction of
+ 0: InteractCustom(+3);
+ 1: InteractCustom(+3);
+ 2: InteractCustom(+3);
+ 3: InteractCustom(-3);
+ 4: InteractCustom(-3);
+ 5: InteractCustom(-3);
+ end; }
+ InteractNext;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenOptions.Create(Back: String);
+var
+ I: integer;
+begin
+ inherited Create(Back);
+
+ // Game
+{ AddButton(225, 100 + 0*60, 350, 50, Skin.Button, 'JPG', 'Transparent Range');
+ AddButtonText(11, 10, 'Game');}
+
+ // Graphics
+{ AddButton(225, 100 + 1*60, 350, 50, Skin.Button, 'JPG', 'Transparent Range');
+ AddButtonText(11, 10, 'Graphics');
+
+ // Sound
+ AddButton(225, 100 + 2*60, 350, 50, Skin.Button, 'JPG', 'Transparent Range');
+ AddButtonText(11, 10, 'Sound');
+
+ // Lyrics
+ AddButton(225, 100 + 3*60, 350, 50, Skin.Button, 'JPG', 'Transparent Range');
+ AddButtonText(11, 10, 'Lyrics');
+
+ // Themes
+ AddButton(225, 100 + 4*60, 350, 50, Skin.Button, 'JPG', 'Transparent Range');
+ AddButtonText(11, 10, 'Themes');
+
+ // Exit
+ AddButton(225, 100 + 6*60, 350, 50, Skin.Exit);}
+
+ AddBackground(Theme.Options.Background.Tex);
+
+ AddButton(Theme.Options.ButtonGame);
+ AddButtonText(14, 20, Theme.Options.Description[0]);
+
+ AddButton(Theme.Options.ButtonGraphics);
+ AddButtonText(14, 20, Theme.Options.Description[1]);
+
+ AddButton(Theme.Options.ButtonSound);
+ AddButtonText(14, 20, Theme.Options.Description[2]);
+
+ AddButton(Theme.Options.ButtonLyrics);
+ AddButtonText(14, 20, Theme.Options.Description[3]);
+
+ AddButton(Theme.Options.ButtonThemes);
+ AddButtonText(14, 20, Theme.Options.Description[4]);
+
+ AddButton(Theme.Options.ButtonRecord);
+ AddButtonText(14, 20, Theme.Options.Description[5]);
+
+ AddButton(Theme.Options.ButtonExit);
+ AddButtonText(14, 20, Theme.Options.Description[6]);
+
+ for I := 0 to High(Theme.Options.Static) do
+ AddStatic(Theme.Options.Static[I]);
+
+ for I := 0 to High(Theme.Options.Text) do
+ AddText(Theme.Options.Text[I]);
+
+ TextDescription := AddText(Theme.Options.TextDescription);
+
+ Interaction := 0;
+end;
+
+procedure TScreenOptions.onShow;
+begin
+//
+end;
+
+procedure TScreenOptions.InteractNext;
+begin
+ inherited InteractNext;
+ Text[TextDescription].Text := Theme.Options.Description[Interaction];
+end;
+
+procedure TScreenOptions.InteractPrev;
+begin
+ inherited InteractPrev;
+ Text[TextDescription].Text := Theme.Options.Description[Interaction];
+end;
+
+
+procedure TScreenOptions.SetAnimationProgress(Progress: real);
+begin
+ Button[0].Texture.ScaleW := Progress;
+ Button[1].Texture.ScaleW := Progress;
+ Button[2].Texture.ScaleW := Progress;
+ Button[3].Texture.ScaleW := Progress;
+ Button[4].Texture.ScaleW := Progress;
+ Button[5].Texture.ScaleW := Progress;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenOptionsGame.dcu b/Game/Code/Screens/UScreenOptionsGame.dcu
new file mode 100644
index 00000000..3fd70913
--- /dev/null
+++ b/Game/Code/Screens/UScreenOptionsGame.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenOptionsGame.pas b/Game/Code/Screens/UScreenOptionsGame.pas
new file mode 100644
index 00000000..6f49bd19
--- /dev/null
+++ b/Game/Code/Screens/UScreenOptionsGame.pas
@@ -0,0 +1,107 @@
+unit UScreenOptionsGame;
+
+interface
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UPliki, UIni, UThemes, USongs;
+
+type
+ TScreenOptionsGame = class(TMenu)
+ public
+ old_Tabs, old_Sorting: integer;
+ constructor Create(Back: String); override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure RefreshSongs;
+ end;
+
+implementation
+
+uses UGraphic;
+
+function TScreenOptionsGame.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_ESCAPE :
+ begin
+ Music.PlayBack;
+ RefreshSongs;
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+ if SelInteraction = 6 then begin
+ Music.PlayBack;
+ RefreshSongs;
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 5) then begin
+ Music.PlayOption;
+ InteractInc;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 5) then begin
+ Music.PlayOption;
+ InteractDec;
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenOptionsGame.Create(Back: String);
+var
+ I: integer;
+begin
+ inherited Create(Back);
+
+ AddBackground(Theme.OptionsGame.Background.Tex);
+
+ for I := 0 to High(Theme.OptionsGame.Static) do
+ AddStatic(Theme.OptionsGame.Static[I]);
+
+ for I := 0 to High(Theme.OptionsGame.Text) do
+ AddText(Theme.OptionsGame.Text[I]);
+
+ //Refresh Songs Patch
+ old_Sorting := Ini.Sorting;
+ old_Tabs := Ini.Tabs;
+
+ AddSelect(Theme.OptionsGame.SelectPlayers, Ini.Players, IPlayers);
+ AddSelect(Theme.OptionsGame.SelectDifficulty, Ini.Difficulty, IDifficulty);
+ AddSelectSlide(Theme.OptionsGame.SelectLanguage, Ini.Language, ILanguage);
+ AddSelect(Theme.OptionsGame.SelectTabs, Ini.Tabs, ITabs);
+ AddSelectSlide(Theme.OptionsGame.SelectSorting, Ini.Sorting, ISorting);
+ AddSelect(Theme.OptionsGame.SelectDebug, Ini.Debug, IDebug);
+
+
+ AddButton(Theme.OptionsGame.ButtonExit);
+ AddButtonText(14, 20, 'Exit');
+
+end;
+
+//Refresh Songs Patch
+procedure TScreenOptionsGame.RefreshSongs;
+begin
+if (ini.Sorting <> old_Sorting) or (ini.Tabs <> old_Tabs) then
+ ScreenSong.Refresh;
+end;
+
+procedure TScreenOptionsGame.onShow;
+begin
+// Interaction := 0;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenOptionsGraphics.dcu b/Game/Code/Screens/UScreenOptionsGraphics.dcu
new file mode 100644
index 00000000..3eddc010
--- /dev/null
+++ b/Game/Code/Screens/UScreenOptionsGraphics.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenOptionsGraphics.pas b/Game/Code/Screens/UScreenOptionsGraphics.pas
new file mode 100644
index 00000000..1f30f9b5
--- /dev/null
+++ b/Game/Code/Screens/UScreenOptionsGraphics.pas
@@ -0,0 +1,101 @@
+unit UScreenOptionsGraphics;
+
+interface
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UPliki, UIni, UThemes;
+
+type
+ TScreenOptionsGraphics = class(TMenu)
+ public
+ constructor Create(Back: String); override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ end;
+
+implementation
+
+uses UGraphic, UMain;
+
+function TScreenOptionsGraphics.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:
+ begin
+ Ini.Save;
+ Music.PlayBack;
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+{ if SelInteraction <= 1 then begin
+ Restart := true;
+ end;}
+ if SelInteraction = 6 then begin
+ Ini.Save;
+ Music.PlayBack;
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 5) then begin
+ Music.PlayOption;
+ InteractInc;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 5) then begin
+ Music.PlayOption;
+ InteractDec;
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenOptionsGraphics.Create(Back: String);
+var
+ I: integer;
+begin
+ inherited Create(Back);
+
+ AddBackground(Theme.OptionsGraphics.Background.Tex);
+
+ for I := 0 to High(Theme.OptionsGraphics.Static) do
+ AddStatic(Theme.OptionsGraphics.Static[I]);
+
+ for I := 0 to High(Theme.OptionsGraphics.Text) do
+ AddText(Theme.OptionsGraphics.Text[I]);
+
+ AddSelectSlide(Theme.OptionsGraphics.SelectSlideResolution, Ini.Resolution, IResolution);
+ AddSelect(Theme.OptionsGraphics.SelectFullscreen, Ini.Fullscreen, IFullscreen);
+ AddSelect(Theme.OptionsGraphics.SelectDepth, Ini.Depth, IDepth);
+ AddSelect(Theme.OptionsGraphics.SelectOscilloscope, Ini.Oscilloscope, IOscilloscope);
+ AddSelect(Theme.OptionsGraphics.SelectLineBonus, Ini.LineBonus, ILineBonus);
+ AddSelect(Theme.OptionsGraphics.SelectMovieSize, Ini.MovieSize, IMovieSize);
+
+
+ AddButton(Theme.OptionsGraphics.ButtonExit);
+ AddButtonText(14, 20, 'Exit');
+
+end;
+
+procedure TScreenOptionsGraphics.onShow;
+begin
+ Interaction := 0;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenOptionsLyrics.dcu b/Game/Code/Screens/UScreenOptionsLyrics.dcu
new file mode 100644
index 00000000..1fcfca9d
--- /dev/null
+++ b/Game/Code/Screens/UScreenOptionsLyrics.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenOptionsLyrics.pas b/Game/Code/Screens/UScreenOptionsLyrics.pas
new file mode 100644
index 00000000..21a33998
--- /dev/null
+++ b/Game/Code/Screens/UScreenOptionsLyrics.pas
@@ -0,0 +1,91 @@
+unit UScreenOptionsLyrics;
+
+interface
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UPliki, UIni, UThemes;
+
+type
+ TScreenOptionsLyrics = class(TMenu)
+ public
+ constructor Create(Back: String); override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ end;
+
+implementation
+
+uses UGraphic;
+
+function TScreenOptionsLyrics.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_ESCAPE :
+ begin
+ Ini.Save;
+ Music.PlayBack;
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+ if SelInteraction = 3 then begin
+ Ini.Save;
+ Music.PlayBack;
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 2) then begin
+ Music.PlayOption;
+ InteractInc;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 2) then begin
+ Music.PlayOption;
+ InteractDec;
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenOptionsLyrics.Create(Back: String);
+var
+ I: integer;
+begin
+ inherited Create(Back);
+
+ AddBackground(Theme.OptionsLyrics.Background.Tex);
+
+ for I := 0 to High(Theme.OptionsLyrics.Static) do
+ AddStatic(Theme.OptionsLyrics.Static[I]);
+
+ for I := 0 to High(Theme.OptionsLyrics.Text) do
+ AddText(Theme.OptionsLyrics.Text[I]);
+
+ AddSelect(Theme.OptionsLyrics.SelectLyricsFont, Ini.LyricsFont, ILyricsFont);
+ AddSelect(Theme.OptionsLyrics.SelectLyricsEffect, Ini.LyricsEffect, ILyricsEffect);
+ AddSelect(Theme.OptionsLyrics.SelectSolmization, Ini.Solmization, ISolmization);
+
+
+ AddButton(Theme.OptionsLyrics.ButtonExit);
+ AddButtonText(14, 20, 'Exit');
+
+end;
+
+procedure TScreenOptionsLyrics.onShow;
+begin
+ Interaction := 0;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenOptionsRecord.dcu b/Game/Code/Screens/UScreenOptionsRecord.dcu
new file mode 100644
index 00000000..36a04d50
--- /dev/null
+++ b/Game/Code/Screens/UScreenOptionsRecord.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenOptionsRecord.pas b/Game/Code/Screens/UScreenOptionsRecord.pas
new file mode 100644
index 00000000..c27ec02a
--- /dev/null
+++ b/Game/Code/Screens/UScreenOptionsRecord.pas
@@ -0,0 +1,136 @@
+unit UScreenOptionsRecord;
+
+interface
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UPliki, UIni, UThemes;
+
+type
+ TScreenOptionsRecord = class(TMenu)
+ private
+ SelectSlideInput: integer;
+ SelectSlideChannelL: integer;
+ SelectSlideChannelR: integer;
+ public
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure UpdateCard;
+ end;
+
+implementation
+
+uses SysUtils, UGraphic, URecord, ULog;
+
+function TScreenOptionsRecord.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
+ Ini.Save;
+ Music.PlayBack;
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+ if SelInteraction = 4 then begin
+ Ini.Save;
+ Music.PlayBack;
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 3) then begin
+ Music.PlayOption;
+ InteractInc;
+ end;
+ if SelInteraction = 0 then UpdateCard;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 3) then begin
+ Music.PlayOption;
+ InteractDec;
+ end;
+ if SelInteraction = 0 then UpdateCard;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenOptionsRecord.Create;
+var
+ I: integer;
+ SC: integer;
+ SCI: integer;
+begin
+ AddBackground(Theme.OptionsRecord.Background.Tex);
+ for I := 0 to High(Theme.OptionsRecord.Static) do
+ AddStatic(Theme.OptionsRecord.Static[I]);
+
+ for I := 0 to High(Theme.OptionsRecord.Text) do
+ AddText(Theme.OptionsRecord.Text[I]);
+
+// SetLength(ICard, 0);
+// ICard[0] := 'karta';
+
+// SetLength(IInput, 0);
+// IInput[0] := 'wejscie';
+
+// if Length(Recording.SoundCard) > 0 then begin
+ SetLength(ICard, Length(Recording.SoundCard));
+ for SC := 0 to High(Recording.SoundCard) do
+ ICard[SC] := Recording.SoundCard[SC].Description;
+// end;
+
+// if Length(Recording.SoundCard[Ini.Card].Input) > 0 then begin
+ SetLength(IInput, Length(Recording.SoundCard[Ini.Card].Input));
+ for SCI := 0 to High(Recording.SoundCard[Ini.Card].Input) do
+ IInput[SCI] := Recording.SoundCard[Ini.Card].Input[SCI].Name;
+// end;
+
+
+ AddSelectSlide(Theme.OptionsRecord.SelectSlideCard, Ini.Card, ICard);
+ SelectSlideInput := AddSelectSlide(Theme.OptionsRecord.SelectSlideInput, Ini.CardList[0].Input, IInput);
+ SelectSlideChannelL := AddSelectSlide(Theme.OptionsRecord.SelectSlideChannelL, Ini.CardList[0].ChannelL, IChannel);
+ SelectSlideChannelR := AddSelectSlide(Theme.OptionsRecord.SelectSlideChannelR, Ini.CardList[0].ChannelR, IChannel);
+
+ AddButton(Theme.OptionsRecord.ButtonExit);
+ AddButtonText(14, 20, 'Exit');
+
+ Interaction := 0;
+end;
+
+procedure TScreenOptionsRecord.onShow;
+begin
+ Interaction := 0;
+end;
+
+procedure TScreenOptionsRecord.UpdateCard;
+var
+ SC: integer;
+ SCI: integer;
+begin
+ SC := Ini.Card;
+// if SC = 1 then beep;
+
+ SetLength(IInput, Length(Recording.SoundCard[SC].Input));
+ for SCI := 0 to High(Recording.SoundCard[SC].Input) do begin
+ IInput[SCI] := Recording.SoundCard[SC].Input[SCI].Name;
+// Log.LogError(IInput[SCI]);
+ end;
+
+ UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideInput, SelectSlideInput, IInput, Ini.CardList[SC].Input);
+ UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideChannelL, SelectSlideChannelL, IChannel, Ini.CardList[SC].ChannelL);
+ UpdateSelectSlideOptions(Theme.OptionsRecord.SelectSlideChannelR, SelectSlideChannelR, IChannel, Ini.CardList[SC].ChannelR);
+end;
+
+end. \ No newline at end of file
diff --git a/Game/Code/Screens/UScreenOptionsSound.dcu b/Game/Code/Screens/UScreenOptionsSound.dcu
new file mode 100644
index 00000000..26c07fe1
--- /dev/null
+++ b/Game/Code/Screens/UScreenOptionsSound.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenOptionsSound.pas b/Game/Code/Screens/UScreenOptionsSound.pas
new file mode 100644
index 00000000..a99ae86d
--- /dev/null
+++ b/Game/Code/Screens/UScreenOptionsSound.pas
@@ -0,0 +1,93 @@
+unit UScreenOptionsSound;
+
+interface
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UPliki, UIni, UThemes;
+
+type
+ TScreenOptionsSound = class(TMenu)
+ public
+ constructor Create(Back: String); override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ end;
+
+implementation
+
+uses UGraphic;
+
+function TScreenOptionsSound.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_ESCAPE :
+ begin
+ Ini.Save;
+ Music.PlayBack;
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+ if SelInteraction = 4 then begin
+ Ini.Save;
+ Music.PlayBack;
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 3) then begin
+ Music.PlayOption;
+ InteractInc;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 3) then begin
+ Music.PlayOption;
+ InteractDec;
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenOptionsSound.Create(Back: String);
+var
+ I: integer;
+begin
+ inherited Create(Back);
+
+ AddBackground(Theme.OptionsSound.Background.Tex);
+
+ for I := 0 to High(Theme.OptionsSound.Static) do
+ AddStatic(Theme.OptionsSound.Static[I]);
+
+ for I := 0 to High(Theme.OptionsSound.Text) do
+ AddText(Theme.OptionsSound.Text[I]);
+
+ AddSelect(Theme.OptionsSound.SelectMicBoost, Ini.MicBoost, IMicBoost);
+ AddSelect(Theme.OptionsSound.SelectClickAssist, Ini.ClickAssist, IClickAssist);
+ AddSelect(Theme.OptionsSound.SelectBeatClick, Ini.BeatClick, IBeatClick);
+ AddSelect(Theme.OptionsSound.SelectThreshold, Ini.Threshold, IThreshold);
+ //AddSelect(Theme.OptionsSound.SelectTwoPlayerMode, Ini.TwoPlayerMode, ITwoPlayerMode);
+
+ AddButton(Theme.OptionsSound.ButtonExit);
+ AddButtonText(14, 20, 'Exit');
+
+ Interaction := 0;
+end;
+
+procedure TScreenOptionsSound.onShow;
+begin
+ Interaction := 0;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenOptionsThemes.dcu b/Game/Code/Screens/UScreenOptionsThemes.dcu
new file mode 100644
index 00000000..98bec8a2
--- /dev/null
+++ b/Game/Code/Screens/UScreenOptionsThemes.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenOptionsThemes.pas b/Game/Code/Screens/UScreenOptionsThemes.pas
new file mode 100644
index 00000000..b7d18fa5
--- /dev/null
+++ b/Game/Code/Screens/UScreenOptionsThemes.pas
@@ -0,0 +1,118 @@
+unit UScreenOptionsThemes;
+
+interface
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UPliki, UIni, UThemes;
+
+type
+ TScreenOptionsThemes = class(TMenu)
+ public
+ SkinSelect: Integer;
+ constructor Create(Back: String); override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure InteractInc; override;
+ procedure InteractDec; override;
+ end;
+
+implementation
+
+uses UGraphic, USkins;
+
+function TScreenOptionsThemes.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_ESCAPE :
+ begin
+ Ini.Save;
+ Music.PlayBack;
+ FadeTo(@ScreenOptions);
+ end;
+ SDLK_RETURN:
+ begin
+ if SelInteraction = 3 then begin
+ Ini.Save;
+ Music.PlayBack;
+ FadeTo(@ScreenOptions);
+ end;
+ end;
+ SDLK_DOWN:
+ InteractNext;
+ SDLK_UP :
+ InteractPrev;
+ SDLK_RIGHT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 2) then begin
+ Music.PlayOption;
+ InteractInc;
+ end;
+ end;
+ SDLK_LEFT:
+ begin
+ if (SelInteraction >= 0) and (SelInteraction <= 2) then begin
+ Music.PlayOption;
+ InteractDec;
+ end;
+ end;
+ end;
+ end;
+end;
+
+procedure TScreenOptionsThemes.InteractInc;
+begin
+ inherited InteractInc;
+ //Update Skins
+ if (SelInteraction = 0) then
+ begin
+ Skin.OnThemeChange;
+ UpdateSelectSlideOptions (Theme.OptionsThemes.SelectSkin, SkinSelect, ISkin, Ini.SkinNo);
+ end;
+end;
+
+procedure TScreenOptionsThemes.InteractDec;
+begin
+ inherited InteractDec;
+ //Update Skins
+ if (SelInteraction = 0) then
+ begin
+ Skin.OnThemeChange;
+ UpdateSelectSlideOptions (Theme.OptionsThemes.SelectSkin, SkinSelect, ISkin, Ini.SkinNo);
+ end;
+end;
+
+constructor TScreenOptionsThemes.Create(Back: String);
+var
+ I: integer;
+begin
+ inherited Create(Back);
+
+ AddBackground(Theme.OptionsThemes.Background.Tex);
+
+ for I := 0 to High(Theme.OptionsThemes.Static) do
+ AddStatic(Theme.OptionsThemes.Static[I]);
+
+ for I := 0 to High(Theme.OptionsThemes.Text) do
+ AddText(Theme.OptionsThemes.Text[I]);
+
+ AddSelectSlide(Theme.OptionsThemes.SelectTheme, Ini.Theme, ITheme);
+ //SelectsS[High(SelectsS)].SetSelectOpt(Ini.Theme);
+
+ SkinSelect := AddSelectSlide(Theme.OptionsThemes.SelectSkin, Ini.SkinNo, ISkin);
+
+ //AddSelectSlideOption('SingStar');
+ AddSelectSlide(Theme.OptionsThemes.SelectColor, Ini.Color, IColor);
+
+ AddButton(Theme.OptionsThemes.ButtonExit);
+ AddButtonText(14, 20, 'Exit');
+end;
+
+procedure TScreenOptionsThemes.onShow;
+begin
+ Interaction := 0;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenPartyNewRound.dcu b/Game/Code/Screens/UScreenPartyNewRound.dcu
new file mode 100644
index 00000000..24b6953e
--- /dev/null
+++ b/Game/Code/Screens/UScreenPartyNewRound.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenPartyNewRound.pas b/Game/Code/Screens/UScreenPartyNewRound.pas
new file mode 100644
index 00000000..1e9be1f5
--- /dev/null
+++ b/Game/Code/Screens/UScreenPartyNewRound.pas
@@ -0,0 +1,397 @@
+unit UScreenPartyNewRound;
+
+interface
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UPliki, SysUtils, UThemes;
+
+type
+ TScreenPartyNewRound = class(TMenu)
+ public
+ //Texts:
+ TextRound1: Cardinal;
+ TextRound2: Cardinal;
+ TextRound3: Cardinal;
+ TextRound4: Cardinal;
+ TextRound5: Cardinal;
+ TextRound6: Cardinal;
+ TextRound7: Cardinal;
+
+ TextWinner1: Cardinal;
+ TextWinner2: Cardinal;
+ TextWinner3: Cardinal;
+ TextWinner4: Cardinal;
+ TextWinner5: Cardinal;
+ TextWinner6: Cardinal;
+ TextWinner7: Cardinal;
+
+ TextNextRound: Cardinal;
+ TextNextRoundNo: Cardinal;
+ TextNextPlayer1: Cardinal;
+ TextNextPlayer2: Cardinal;
+ TextNextPlayer3: Cardinal;
+ //Statics
+ StaticRound1: Cardinal;
+ StaticRound2: Cardinal;
+ StaticRound3: Cardinal;
+ StaticRound4: Cardinal;
+ StaticRound5: Cardinal;
+ StaticRound6: Cardinal;
+ StaticRound7: Cardinal;
+
+ //Scores
+ TextScoreTeam1: Cardinal;
+ TextScoreTeam2: Cardinal;
+ TextScoreTeam3: Cardinal;
+ TextNameTeam1: Cardinal;
+ TextNameTeam2: Cardinal;
+ TextNameTeam3: Cardinal;
+
+ StaticTeam1: Cardinal;
+ StaticTeam2: Cardinal;
+ StaticTeam3: Cardinal;
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic, UMain, UIni, UTexture, UParty, UDLLManager, ULanguage, ULog;
+
+function TScreenPartyNewRound.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 :
+ begin
+ Music.PlayBack;
+ FadeTo(@ScreenMain);
+ end;
+
+ SDLK_RETURN:
+ begin
+ Music.PlayStart;
+ if DLLMan.Selected.LoadSong then
+ begin
+ //Select PartyMode ScreenSong
+ ScreenSong.Mode := 1;
+ FadeTo(@ScreenSong);
+ end
+ else
+ begin
+ FadeTo(@ScreenSingModi);
+ 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: InteractNext;
+ SDLK_UP: InteractPrev;
+ SDLK_RIGHT: InteractNext;
+ SDLK_LEFT: InteractPrev;
+ end;
+ end
+ else // Key Up
+ case PressedKey of
+ SDLK_RETURN :
+ begin
+ end;
+ end;
+end;
+
+constructor TScreenPartyNewRound.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ AddBackground(Theme.PartyNewRound.Background.Tex);
+ Log.LogError(Theme.PartyNewRound.Background.Tex);
+
+ TextRound1 := AddText (Theme.PartyNewRound.TextRound1);
+ TextRound2 := AddText (Theme.PartyNewRound.TextRound2);
+ TextRound3 := AddText (Theme.PartyNewRound.TextRound3);
+ TextRound4 := AddText (Theme.PartyNewRound.TextRound4);
+ TextRound5 := AddText (Theme.PartyNewRound.TextRound5);
+ TextRound6 := AddText (Theme.PartyNewRound.TextRound6);
+ TextRound7 := AddText (Theme.PartyNewRound.TextRound7);
+
+ TextWinner1 := AddText (Theme.PartyNewRound.TextWinner1);
+ TextWinner2 := AddText (Theme.PartyNewRound.TextWinner2);
+ TextWinner3 := AddText (Theme.PartyNewRound.TextWinner3);
+ TextWinner4 := AddText (Theme.PartyNewRound.TextWinner4);
+ TextWinner5 := AddText (Theme.PartyNewRound.TextWinner5);
+ TextWinner6 := AddText (Theme.PartyNewRound.TextWinner6);
+ TextWinner7 := AddText (Theme.PartyNewRound.TextWinner7);
+
+ TextNextRound := AddText (Theme.PartyNewRound.TextNextRound);
+ TextNextRoundNo := AddText (Theme.PartyNewRound.TextNextRoundNo);
+ TextNextPlayer1 := AddText (Theme.PartyNewRound.TextNextPlayer1);
+ TextNextPlayer2 := AddText (Theme.PartyNewRound.TextNextPlayer2);
+ TextNextPlayer3 := AddText (Theme.PartyNewRound.TextNextPlayer3);
+
+ StaticRound1 := AddStatic (Theme.PartyNewRound.StaticRound1);
+ StaticRound2 := AddStatic (Theme.PartyNewRound.StaticRound2);
+ StaticRound3 := AddStatic (Theme.PartyNewRound.StaticRound3);
+ StaticRound4 := AddStatic (Theme.PartyNewRound.StaticRound4);
+ StaticRound5 := AddStatic (Theme.PartyNewRound.StaticRound5);
+ StaticRound6 := AddStatic (Theme.PartyNewRound.StaticRound6);
+ StaticRound7 := AddStatic (Theme.PartyNewRound.StaticRound7);
+
+ //Scores
+ TextScoreTeam1 := AddText (Theme.PartyNewRound.TextScoreTeam1);
+ TextScoreTeam2 := AddText (Theme.PartyNewRound.TextScoreTeam2);
+ TextScoreTeam3 := AddText (Theme.PartyNewRound.TextScoreTeam3);
+ TextNameTeam1 := AddText (Theme.PartyNewRound.TextNameTeam1);
+ TextNameTeam2 := AddText (Theme.PartyNewRound.TextNameTeam2);
+ TextNameTeam3 := AddText (Theme.PartyNewRound.TextNameTeam3);
+
+ StaticTeam1 := AddStatic (Theme.PartyNewRound.StaticTeam1);
+ StaticTeam2 := AddStatic (Theme.PartyNewRound.StaticTeam2);
+ StaticTeam3 := AddStatic (Theme.PartyNewRound.StaticTeam3);
+
+ AddButton (Theme.PartyNewRound.ButtonNext);
+
+ for I := 0 to High(Theme.PartyNewRound.Static) do
+ AddStatic(Theme.PartyNewRound.Static[I]);
+
+ for I := 0 to High(Theme.PartyNewRound.Text) do
+ AddText(Theme.PartyNewRound.Text[I]);
+
+ Interaction := 0;
+end;
+
+procedure TScreenPartyNewRound.onShow;
+var
+ I: Integer;
+begin
+ //If not First Round, End Last Round
+ if (PartySession.CurRound <> 255) then
+ PartySession.EndRound;
+
+ PartySession.StartRound;
+ Log.LogError(InttoStr(Length(DllMan.Plugins)));
+
+ //Set Visibility of Round Infos
+ I := Length(PartySession.Rounds);
+ if (I >= 1) then
+ begin
+ Static[StaticRound1].Visible := True;
+ Text[TextRound1].Visible := True;
+ Text[TextWinner1].Visible := True;
+
+ //Texts:
+ Text[TextRound1].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[0].Plugin].Name);
+ Text[TextWinner1].Text := PartySession.GetWinnerString(0);
+ end
+ else
+ begin
+ Static[StaticRound1].Visible := False;
+ Text[TextRound1].Visible := False;
+ Text[TextWinner1].Visible := False;
+ end;
+
+ if (I >= 2) then
+ begin
+ Static[StaticRound2].Visible := True;
+ Text[TextRound2].Visible := True;
+ Text[TextWinner2].Visible := True;
+
+ //Texts:
+ Text[TextRound2].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[1].Plugin].Name);
+ Text[TextWinner2].Text := PartySession.GetWinnerString(1);
+ end
+ else
+ begin
+ Static[StaticRound2].Visible := False;
+ Text[TextRound2].Visible := False;
+ Text[TextWinner2].Visible := False;
+ end;
+
+ if (I >= 3) then
+ begin
+ Static[StaticRound3].Visible := True;
+ Text[TextRound3].Visible := True;
+ Text[TextWinner3].Visible := True;
+
+ //Texts:
+ Text[TextRound3].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[2].Plugin].Name);
+ Text[TextWinner3].Text := PartySession.GetWinnerString(2);
+ end
+ else
+ begin
+ Static[StaticRound3].Visible := False;
+ Text[TextRound3].Visible := False;
+ Text[TextWinner3].Visible := False;
+ end;
+
+ if (I >= 4) then
+ begin
+ Static[StaticRound4].Visible := True;
+ Text[TextRound4].Visible := True;
+ Text[TextWinner4].Visible := True;
+
+ //Texts:
+ Text[TextRound4].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[3].Plugin].Name);
+ Text[TextWinner4].Text := PartySession.GetWinnerString(3);
+ end
+ else
+ begin
+ Static[StaticRound4].Visible := False;
+ Text[TextRound4].Visible := False;
+ Text[TextWinner4].Visible := False;
+ end;
+
+ if (I >= 5) then
+ begin
+ Static[StaticRound5].Visible := True;
+ Text[TextRound5].Visible := True;
+ Text[TextWinner5].Visible := True;
+
+ //Texts:
+ Text[TextRound5].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[4].Plugin].Name);
+ Text[TextWinner5].Text := PartySession.GetWinnerString(4);
+ end
+ else
+ begin
+ Static[StaticRound5].Visible := False;
+ Text[TextRound5].Visible := False;
+ Text[TextWinner5].Visible := False;
+ end;
+
+ if (I >= 6) then
+ begin
+ Static[StaticRound6].Visible := True;
+ Text[TextRound6].Visible := True;
+ Text[TextWinner6].Visible := True;
+
+ //Texts:
+ Text[TextRound6].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[5].Plugin].Name);
+ Text[TextWinner6].Text := PartySession.GetWinnerString(5);
+ end
+ else
+ begin
+ Static[StaticRound6].Visible := False;
+ Text[TextRound6].Visible := False;
+ Text[TextWinner6].Visible := False;
+ end;
+
+ if (I >= 7) then
+ begin
+ Static[StaticRound7].Visible := True;
+ Text[TextRound7].Visible := True;
+ Text[TextWinner7].Visible := True;
+
+ //Texts:
+ Text[TextRound7].Text := Language.Translate(DllMan.Plugins[PartySession.Rounds[6].Plugin].Name);
+ Text[TextWinner7].Text := PartySession.GetWinnerString(6);
+ end
+ else
+ begin
+ Static[StaticRound7].Visible := False;
+ Text[TextRound7].Visible := False;
+ Text[TextWinner7].Visible := False;
+ end;
+
+ //Display Scores
+ if (PartySession.Teams.NumTeams >= 1) then
+ begin
+ Text[TextScoreTeam1].Text := InttoStr(PartySession.Teams.TeamInfo[0].Score);
+ Text[TextNameTeam1].Text := String(PartySession.Teams.TeamInfo[0].Name);
+
+ Text[TextScoreTeam1].Visible := True;
+ Text[TextNameTeam1].Visible := True;
+ Static[StaticTeam1].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam1].Visible := False;
+ Text[TextNameTeam1].Visible := False;
+ Static[StaticTeam1].Visible := False;
+ end;
+
+ if (PartySession.Teams.NumTeams >= 2) then
+ begin
+ Text[TextScoreTeam2].Text := InttoStr(PartySession.Teams.TeamInfo[1].Score);
+ Text[TextNameTeam2].Text := String(PartySession.Teams.TeamInfo[1].Name);
+
+ Text[TextScoreTeam2].Visible := True;
+ Text[TextNameTeam2].Visible := True;
+ Static[StaticTeam2].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam2].Visible := False;
+ Text[TextNameTeam2].Visible := False;
+ Static[StaticTeam2].Visible := False;
+ end;
+
+ if (PartySession.Teams.NumTeams >= 3) then
+ begin
+ Text[TextScoreTeam3].Text := InttoStr(PartySession.Teams.TeamInfo[2].Score);
+ Text[TextNameTeam3].Text := String(PartySession.Teams.TeamInfo[2].Name);
+
+ Text[TextScoreTeam3].Visible := True;
+ Text[TextNameTeam3].Visible := True;
+ Static[StaticTeam3].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam3].Visible := False;
+ Text[TextNameTeam3].Visible := False;
+ Static[StaticTeam3].Visible := False;
+ end;
+
+ //nextRound Texts
+ Text[TextNextRound].Text := Language.Translate(DllMan.Selected.PluginDesc);
+ Text[TextNextRoundNo].Text := InttoStr(PartySession.CurRound + 1);
+ if (PartySession.Teams.NumTeams >= 1) then
+ begin
+ Text[TextNextPlayer1].Text := PartySession.Teams.Teaminfo[0].Playerinfo[PartySession.Teams.Teaminfo[0].CurPlayer].Name;
+ Text[TextNextPlayer1].Visible := True;
+ end
+ else
+ Text[TextNextPlayer1].Visible := False;
+
+ if (PartySession.Teams.NumTeams >= 2) then
+ begin
+ Text[TextNextPlayer2].Text := PartySession.Teams.Teaminfo[1].Playerinfo[PartySession.Teams.Teaminfo[1].CurPlayer].Name;
+ Text[TextNextPlayer2].Visible := True;
+ end
+ else
+ Text[TextNextPlayer2].Visible := False;
+
+ if (PartySession.Teams.NumTeams >= 3) then
+ begin
+ Text[TextNextPlayer3].Text := PartySession.Teams.Teaminfo[2].Playerinfo[PartySession.Teams.Teaminfo[2].CurPlayer].Name;
+ Text[TextNextPlayer3].Visible := True;
+ end
+ else
+ Text[TextNextPlayer3].Visible := False;
+
+ Log.LogError('Plugin Selected: ' + InttoStr(PartySession.Rounds[0].Plugin));
+
+
+// LCD.WriteText(1, ' Choose mode: ');
+// UpdateLCD;
+end;
+
+procedure TScreenPartyNewRound.SetAnimationProgress(Progress: real);
+begin
+ {Button[0].Texture.ScaleW := Progress;
+ Button[1].Texture.ScaleW := Progress;
+ Button[2].Texture.ScaleW := Progress; }
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenPartyOptions.dcu b/Game/Code/Screens/UScreenPartyOptions.dcu
new file mode 100644
index 00000000..8f0bbf3d
--- /dev/null
+++ b/Game/Code/Screens/UScreenPartyOptions.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenPartyOptions.pas b/Game/Code/Screens/UScreenPartyOptions.pas
new file mode 100644
index 00000000..148289e8
--- /dev/null
+++ b/Game/Code/Screens/UScreenPartyOptions.pas
@@ -0,0 +1,164 @@
+unit UScreenPartyOptions;
+
+interface
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UPliki, SysUtils, UThemes;
+
+type
+ TScreenPartyOptions = class(TMenu)
+ public
+ SelectLevel: Cardinal;
+ SelectPlayList: Cardinal;
+ SelectPlayList2: Cardinal;
+ SelectRounds: Cardinal;
+ SelectTeams: Cardinal;
+ SelectPlayers1: Cardinal;
+ SelectPlayers2: Cardinal;
+ SelectPlayers3: Cardinal;
+
+ PlayList: Integer;
+ PlayList2: Integer;
+ Rounds: Integer;
+ NumTeams: Integer;
+ NumPlayer1, NumPlayer2, NumPlayer3: Integer;
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+var
+ ILevel: array[0..2] of String;
+const
+ ITeams: array[0..1] of String =('2', '3');
+ IPlayers: array[0..3] of String =('1', '2', '3', '4');
+ IRounds: array[0..5] of String = ('2', '3', '4', '5', '6', '7');
+
+implementation
+
+uses UGraphic, UMain, UIni, UTexture, ULanguage, UParty, UDLLManager;
+
+function TScreenPartyOptions.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+var I: Integer;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+
+ SDLK_ESCAPE :
+ begin
+ Music.PlayBack;
+ FadeTo(@ScreenMain);
+ end;
+
+ SDLK_RETURN:
+ begin
+
+ //Save Difficulty
+ Ini.Difficulty := SelectsS[SelectLevel].SelectedOption;
+ Ini.SaveLevel;
+ //Save PlayList
+ //(Todo)
+ //Save Num Teams:
+ PartySession.Teams.NumTeams := NumTeams + 2;
+ PartySession.Teams.Teaminfo[0].NumPlayers := NumPlayer1+1;
+ PartySession.Teams.Teaminfo[1].NumPlayers := NumPlayer2+1;
+ PartySession.Teams.Teaminfo[2].NumPlayers := NumPlayer3+1;
+ //Save Rounds + Random
+ SetLength (PartySession.Rounds, Rounds + 2);
+ For I := 0 to high (PartySession.Rounds) do
+ begin
+ PartySession.Rounds[I].Plugin := Random (Length(DLLMan.Plugins));
+ PartySession.Rounds[I].Winner := 0;
+ end;
+ Music.PlayStart;
+ //Go to Player Screen
+ FadeTo(@ScreenPartyPlayer);
+ 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: InteractNext;
+ SDLK_UP: InteractPrev;
+ SDLK_RIGHT:
+ begin
+ Music.PlayOption;
+ InteractInc;
+ end;
+ SDLK_LEFT:
+ begin
+ Music.PlayOption;
+ InteractDec;
+ end;
+ end;
+ end
+ else // Key Up
+ case PressedKey of
+ SDLK_RETURN :
+ begin
+ end;
+ end;
+end;
+
+constructor TScreenPartyOptions.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ //Fill ILevel
+ ILevel[0] := Language.Translate('SING_EASY');
+ ILevel[1] := Language.Translate('SING_MEDIUM');
+ ILevel[2] := Language.Translate('SING_HARD');
+
+ NumTeams := 0;
+ NumPlayer1 := 0;
+ NumPlayer2 := 0;
+ NumPlayer3 := 0;
+ Rounds := 5;
+ PlayList := 0;
+ PlayList2 := 0;
+
+ AddBackground(Theme.PartyOptions.Background.Tex);
+
+ SelectLevel := AddSelectSlide (Theme.PartyOptions.SelectLevel, Ini.Difficulty, ILevel);
+ SelectPlayList := AddSelectSlide (Theme.PartyOptions.SelectPlayList, PlayList, ITeams);
+ SelectPlayList2 := AddSelectSlide (Theme.PartyOptions.SelectPlayList2, PlayList2, ITeams);
+ SelectRounds := AddSelectSlide (Theme.PartyOptions.SelectRounds, Rounds, IRounds);
+ SelectTeams := AddSelectSlide (Theme.PartyOptions.SelectTeams, NumTeams, ITeams);
+ SelectPlayers1 := AddSelectSlide (Theme.PartyOptions.SelectPlayers1, NumPlayer1, IPlayers);
+ SelectPlayers2 := AddSelectSlide (Theme.PartyOptions.SelectPlayers2, NumPlayer2, IPlayers);
+ SelectPlayers3 := AddSelectSlide (Theme.PartyOptions.SelectPlayers3, NumPlayer3, IPlayers);
+
+ for I := 0 to High(Theme.PartyOptions.Static) do
+ AddStatic(Theme.PartyOptions.Static[I]);
+
+ for I := 0 to High(Theme.PartyOptions.Text) do
+ AddText(Theme.PartyOptions.Text[I]);
+
+ Interaction := 0;
+end;
+
+procedure TScreenPartyOptions.onShow;
+begin
+ Randomize;
+
+// LCD.WriteText(1, ' Choose mode: ');
+// UpdateLCD;
+end;
+
+procedure TScreenPartyOptions.SetAnimationProgress(Progress: real);
+begin
+ {for I := 0 to 6 do
+ SelectS[I].Texture.ScaleW := Progress;}
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenPartyPlayer.dcu b/Game/Code/Screens/UScreenPartyPlayer.dcu
new file mode 100644
index 00000000..1afeac79
--- /dev/null
+++ b/Game/Code/Screens/UScreenPartyPlayer.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenPartyPlayer.pas b/Game/Code/Screens/UScreenPartyPlayer.pas
new file mode 100644
index 00000000..b954212a
--- /dev/null
+++ b/Game/Code/Screens/UScreenPartyPlayer.pas
@@ -0,0 +1,210 @@
+unit UScreenPartyPlayer;
+
+Interface
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UPliki, SysUtils, UThemes;
+
+type
+ TScreenPartyPlayer = class(TMenu)
+ public
+ Team1Name: Cardinal;
+ Player1Name: Cardinal;
+ Player2Name: Cardinal;
+ Player3Name: Cardinal;
+ Player4Name: Cardinal;
+
+ Team2Name: Cardinal;
+ Player5Name: Cardinal;
+ Player6Name: Cardinal;
+ Player7Name: Cardinal;
+ Player8Name: Cardinal;
+
+ Team3Name: Cardinal;
+ Player9Name: Cardinal;
+ Player10Name: Cardinal;
+ Player11Name: Cardinal;
+ Player12Name: Cardinal;
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic, UMain, UIni, UTexture, UParty;
+
+function TScreenPartyPlayer.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+var
+ I, J: integer;
+ procedure IntNext;
+ begin
+ repeat
+ InteractNext;
+ until Button[Interaction].Visible;
+ end;
+ procedure IntPrev;
+ begin
+ repeat
+ InteractPrev;
+ until Button[Interaction].Visible;
+ end;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_0..SDLK_9, SDLK_A..SDLK_Z, SDLK_SPACE, SDLK_MINUS, SDLK_EXCLAIM, SDLK_COMMA, SDLK_SLASH, SDLK_ASTERISK, SDLK_QUESTION, SDLK_QUOTE, SDLK_QUOTEDBL:
+ begin
+ Button[Interaction].Text[0].Text := Button[Interaction].Text[0].Text + chr(ScanCode);
+ end;
+
+ SDLK_BACKSPACE:
+ begin
+ Delete(Button[Interaction].Text[0].Text,
+ Length(Button[Interaction].Text[0].Text), 1);
+ end;
+
+ SDLK_ESCAPE :
+ begin
+ Ini.SaveNames;
+ Music.PlayBack;
+ FadeTo(@ScreenPartyOptions);
+ end;
+
+ SDLK_RETURN:
+ begin
+
+ for I := 0 to PartySession.Teams.NumTeams-1 do
+ begin
+ PartySession.Teams.Teaminfo[I].Name := PChar(Button[I*5].Text[0].Text);
+ for J := 0 to PartySession.Teams.Teaminfo[I].NumPlayers-1 do
+ begin
+ PartySession.Teams.Teaminfo[I].Playerinfo[J].Name := PChar(Button[I*5 + J+1].Text[0].Text);
+ PartySession.Teams.Teaminfo[I].Playerinfo[J].TimesPlayed := 0;
+ end;
+ PartySession.Teams.Teaminfo[I].Joker := Round (Length(PartySession.Rounds) * 0.85);
+ end;
+
+
+ //Start Party
+ PartySession.StartNewParty;
+
+ Music.PlayStart;
+ FadeTo(@ScreenPartyNewRound);
+ 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: IntNext;
+ SDLK_UP: IntPrev;
+ SDLK_RIGHT: IntNext;
+ SDLK_LEFT: IntPrev;
+ end;
+ end;
+end;
+
+constructor TScreenPartyPlayer.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ AddBackground(Theme.PartyPlayer.Background.Tex);
+
+ Team1Name := AddButton(Theme.PartyPlayer.Team1Name);
+ AddButton(Theme.PartyPlayer.Player1Name);
+ AddButton(Theme.PartyPlayer.Player2Name);
+ AddButton(Theme.PartyPlayer.Player3Name);
+ AddButton(Theme.PartyPlayer.Player4Name);
+
+ Team2Name := AddButton(Theme.PartyPlayer.Team2Name);
+ AddButton(Theme.PartyPlayer.Player5Name);
+ AddButton(Theme.PartyPlayer.Player6Name);
+ AddButton(Theme.PartyPlayer.Player7Name);
+ AddButton(Theme.PartyPlayer.Player8Name);
+
+ Team3Name := AddButton(Theme.PartyPlayer.Team3Name);
+ AddButton(Theme.PartyPlayer.Player9Name);
+ AddButton(Theme.PartyPlayer.Player10Name);
+ AddButton(Theme.PartyPlayer.Player11Name);
+ AddButton(Theme.PartyPlayer.Player12Name);
+
+ for I := 0 to High(Theme.PartyPlayer.Static) do
+ AddStatic(Theme.PartyPlayer.Static[I]);
+
+ for I := 0 to High(Theme.PartyPlayer.Text) do
+ AddText(Theme.PartyPlayer.Text[I]);
+
+ Interaction := 0;
+end;
+
+procedure TScreenPartyPlayer.onShow;
+var
+ I: integer;
+begin
+ If (PartySession.Teams.NumTeams>=1) then
+ begin
+ Button[0].Visible := True;
+ Button[1].Visible := (PartySession.Teams.Teaminfo[0].NumPlayers >=1);
+ Button[2].Visible := (PartySession.Teams.Teaminfo[0].NumPlayers >=2);
+ Button[3].Visible := (PartySession.Teams.Teaminfo[0].NumPlayers >=3);
+ Button[4].Visible := (PartySession.Teams.Teaminfo[0].NumPlayers >=4);
+ end
+ else
+ begin
+ Button[0].Visible := False;
+ Button[1].Visible := False;
+ Button[2].Visible := False;
+ Button[3].Visible := False;
+ Button[4].Visible := False;
+ end;
+
+ If (PartySession.Teams.NumTeams>=2) then
+ begin
+ Button[5].Visible := True;
+ Button[6].Visible := (PartySession.Teams.Teaminfo[1].NumPlayers >=1);
+ Button[7].Visible := (PartySession.Teams.Teaminfo[1].NumPlayers >=2);
+ Button[8].Visible := (PartySession.Teams.Teaminfo[1].NumPlayers >=3);
+ Button[9].Visible := (PartySession.Teams.Teaminfo[1].NumPlayers >=4);
+ end
+ else
+ begin
+ Button[5].Visible := False;
+ Button[6].Visible := False;
+ Button[7].Visible := False;
+ Button[8].Visible := False;
+ Button[9].Visible := False;
+ end;
+
+ If (PartySession.Teams.NumTeams>=3) then
+ begin
+ Button[10].Visible := True;
+ Button[11].Visible := (PartySession.Teams.Teaminfo[2].NumPlayers >=1);
+ Button[12].Visible := (PartySession.Teams.Teaminfo[2].NumPlayers >=2);
+ Button[13].Visible := (PartySession.Teams.Teaminfo[2].NumPlayers >=3);
+ Button[14].Visible := (PartySession.Teams.Teaminfo[2].NumPlayers >=4);
+ end
+ else
+ begin
+ Button[10].Visible := False;
+ Button[11].Visible := False;
+ Button[12].Visible := False;
+ Button[13].Visible := False;
+ Button[14].Visible := False;
+ end;
+
+end;
+
+procedure TScreenPartyPlayer.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/Screens/UScreenPartyScore.dcu b/Game/Code/Screens/UScreenPartyScore.dcu
new file mode 100644
index 00000000..9dffe2e5
--- /dev/null
+++ b/Game/Code/Screens/UScreenPartyScore.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenPartyScore.pas b/Game/Code/Screens/UScreenPartyScore.pas
new file mode 100644
index 00000000..9cbeb5d5
--- /dev/null
+++ b/Game/Code/Screens/UScreenPartyScore.pas
@@ -0,0 +1,183 @@
+unit UScreenPartyScore;
+
+interface
+
+uses
+ UMenu, SDL, UDisplay, UMusic, SysUtils, UThemes;
+
+type
+ TScreenPartyScore = class(TMenu)
+ public
+ TextScoreTeam1: Cardinal;
+ TextScoreTeam2: Cardinal;
+ TextScoreTeam3: Cardinal;
+ TextNameTeam1: Cardinal;
+ TextNameTeam2: Cardinal;
+ TextNameTeam3: Cardinal;
+ StaticTeam1: Cardinal;
+ StaticTeam2: Cardinal;
+ StaticTeam3: Cardinal;
+ TextWinner: Cardinal;
+
+ MaxScore: Word;
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic, UMain, UParty, UScreenSingModi, ULanguage;
+
+function TScreenPartyScore.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 :
+ begin
+ Music.PlayStart;
+ if (PartySession.CurRound <= High(PartySession.Rounds)) then
+ FadeTo(@ScreenPartyNewRound)
+ else
+ begin
+ PartySession.EndRound;
+ FadeTo(@ScreenPartyWin);
+ end;
+ end;
+
+ SDLK_RETURN:
+ begin
+ Music.PlayStart;
+ if (PartySession.CurRound <= High(PartySession.Rounds)) then
+ FadeTo(@ScreenPartyNewRound)
+ else
+ begin
+ PartySession.EndRound;
+ FadeTo(@ScreenPartyWin);
+ end;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenPartyScore.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ AddBackground(Theme.PartyScore.Background.Tex);
+
+ TextScoreTeam1 := AddText (Theme.PartyScore.TextScoreTeam1);
+ TextScoreTeam2 := AddText (Theme.PartyScore.TextScoreTeam2);
+ TextScoreTeam3 := AddText (Theme.PartyScore.TextScoreTeam3);
+ TextNameTeam1 := AddText (Theme.PartyScore.TextNameTeam1);
+ TextNameTeam2 := AddText (Theme.PartyScore.TextNameTeam2);
+ TextNameTeam3 := AddText (Theme.PartyScore.TextNameTeam3);
+
+ StaticTeam1 := AddStatic (Theme.PartyScore.StaticTeam1);
+ StaticTeam2 := AddStatic (Theme.PartyScore.StaticTeam2);
+ StaticTeam3 := AddStatic (Theme.PartyScore.StaticTeam3);
+
+ TextWinner := AddText (Theme.PartyScore.TextWinner);
+
+ for I := 0 to High(Theme.PartyScore.Static) do
+ AddStatic(Theme.PartyScore.Static[I]);
+
+ for I := 0 to High(Theme.PartyScore.Text) do
+ AddText(Theme.PartyScore.Text[I]);
+end;
+
+procedure TScreenPartyScore.onShow;
+var
+ I: Integer;
+begin
+ //Get Maxscore
+ MaxScore := 0;
+ for I := 0 to ScreenSingModi.PlayerInfo.NumPlayers - 1 do
+ begin
+ if (ScreenSingModi.PlayerInfo.Playerinfo[I].Score > MaxScore) then
+ MaxScore := ScreenSingModi.PlayerInfo.Playerinfo[I].Score;
+ end;
+
+ //Set Static Length
+ Static[StaticTeam1].Texture.ScaleW := ScreenSingModi.PlayerInfo.Playerinfo[0].Percentage / 100;
+ Static[StaticTeam2].Texture.ScaleW := ScreenSingModi.PlayerInfo.Playerinfo[1].Percentage / 100;
+ Static[StaticTeam3].Texture.ScaleW := ScreenSingModi.PlayerInfo.Playerinfo[2].Percentage / 100;
+
+ //Set Winnertext
+ Text[TextWinner].Text := Format(Language.Translate('PARTY_SCORE_WINS'), [PartySession.GetWinnerString(PartySession.CurRound)]);
+
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 1) then
+ begin
+ Text[TextScoreTeam1].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[0].Score);
+ Text[TextNameTeam1].Text := String(ScreenSingModi.TeamInfo.Teaminfo[0].Name);
+
+ Text[TextScoreTeam1].Visible := True;
+ Text[TextNameTeam1].Visible := True;
+ Static[StaticTeam1].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam1].Visible := False;
+ Text[TextNameTeam1].Visible := False;
+ Static[StaticTeam1].Visible := False;
+ end;
+
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 2) then
+ begin
+ Text[TextScoreTeam2].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[1].Score);
+ Text[TextNameTeam2].Text := String(ScreenSingModi.TeamInfo.Teaminfo[1].Name);
+
+ Text[TextScoreTeam2].Visible := True;
+ Text[TextNameTeam2].Visible := True;
+ Static[StaticTeam2].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam2].Visible := False;
+ Text[TextNameTeam2].Visible := False;
+ Static[StaticTeam2].Visible := False;
+ end;
+
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 3) then
+ begin
+ Text[TextScoreTeam3].Text := InttoStr(ScreenSingModi.PlayerInfo.Playerinfo[2].Score);
+ Text[TextNameTeam3].Text := String(ScreenSingModi.TeamInfo.Teaminfo[2].Name);
+
+ Text[TextScoreTeam3].Visible := True;
+ Text[TextNameTeam3].Visible := True;
+ Static[StaticTeam3].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam3].Visible := False;
+ Text[TextNameTeam3].Visible := False;
+ Static[StaticTeam3].Visible := False;
+ end;
+
+
+// LCD.WriteText(1, ' Choose mode: ');
+// UpdateLCD;
+end;
+
+procedure TScreenPartyScore.SetAnimationProgress(Progress: real);
+begin
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 1) then
+ Static[StaticTeam1].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[0].Percentage / 100;
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 2) then
+ Static[StaticTeam2].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[1].Percentage / 100;
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 3) then
+ Static[StaticTeam3].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[2].Percentage / 100;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenPartyWin.dcu b/Game/Code/Screens/UScreenPartyWin.dcu
new file mode 100644
index 00000000..d55c0809
--- /dev/null
+++ b/Game/Code/Screens/UScreenPartyWin.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenPartyWin.pas b/Game/Code/Screens/UScreenPartyWin.pas
new file mode 100644
index 00000000..ac5f38d9
--- /dev/null
+++ b/Game/Code/Screens/UScreenPartyWin.pas
@@ -0,0 +1,157 @@
+unit UScreenPartyWin;
+
+interface
+
+uses
+ UMenu, SDL, UDisplay, UMusic, SysUtils, UThemes;
+
+type
+ TScreenPartyWin = class(TMenu)
+ public
+ TextScoreTeam1: Cardinal;
+ TextScoreTeam2: Cardinal;
+ TextScoreTeam3: Cardinal;
+ TextNameTeam1: Cardinal;
+ TextNameTeam2: Cardinal;
+ TextNameTeam3: Cardinal;
+ StaticTeam1: Cardinal;
+ StaticTeam2: Cardinal;
+ StaticTeam3: Cardinal;
+ TextWinner: Cardinal;
+
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ procedure SetAnimationProgress(Progress: real); override;
+ end;
+
+implementation
+
+uses UGraphic, UMain, UParty, UScreenSingModi, ULanguage;
+
+function TScreenPartyWin.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 :
+ begin
+ Music.PlayStart;
+ FadeTo(@ScreenMain);
+ end;
+
+ SDLK_RETURN:
+ begin
+ Music.PlayStart;
+ FadeTo(@ScreenMain);
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenPartyWin.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ AddBackground(Theme.PartyWin.Background.Tex);
+
+ TextScoreTeam1 := AddText (Theme.PartyWin.TextScoreTeam1);
+ TextScoreTeam2 := AddText (Theme.PartyWin.TextScoreTeam2);
+ TextScoreTeam3 := AddText (Theme.PartyWin.TextScoreTeam3);
+ TextNameTeam1 := AddText (Theme.PartyWin.TextNameTeam1);
+ TextNameTeam2 := AddText (Theme.PartyWin.TextNameTeam2);
+ TextNameTeam3 := AddText (Theme.PartyWin.TextNameTeam3);
+
+ StaticTeam1 := AddStatic (Theme.PartyWin.StaticTeam1);
+ StaticTeam2 := AddStatic (Theme.PartyWin.StaticTeam2);
+ StaticTeam3 := AddStatic (Theme.PartyWin.StaticTeam3);
+
+ TextWinner := AddText (Theme.PartyWin.TextWinner);
+
+ for I := 0 to High(Theme.PartyWin.Static) do
+ AddStatic(Theme.PartyWin.Static[I]);
+
+ for I := 0 to High(Theme.PartyWin.Text) do
+ AddText(Theme.PartyWin.Text[I]);
+end;
+
+procedure TScreenPartyWin.onShow;
+var
+ I: Integer;
+begin
+
+ //Set Winnertext
+ Text[TextWinner].Text := Format(Language.Translate('PARTY_SCORE_WINS'), [PartySession.GetWinnerString(255)]);
+
+ if (PartySession.Teams.NumTeams >= 1) then
+ begin
+ Text[TextScoreTeam1].Text := InttoStr(PartySession.Teams.TeamInfo[0].Score);
+ Text[TextNameTeam1].Text := String(PartySession.Teams.TeamInfo[0].Name);
+
+ Text[TextScoreTeam1].Visible := True;
+ Text[TextNameTeam1].Visible := True;
+ Static[StaticTeam1].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam1].Visible := False;
+ Text[TextNameTeam1].Visible := False;
+ Static[StaticTeam1].Visible := False;
+ end;
+
+ if (PartySession.Teams.NumTeams >= 2) then
+ begin
+ Text[TextScoreTeam2].Text := InttoStr(PartySession.Teams.TeamInfo[1].Score);
+ Text[TextNameTeam2].Text := String(PartySession.Teams.TeamInfo[1].Name);
+
+ Text[TextScoreTeam2].Visible := True;
+ Text[TextNameTeam2].Visible := True;
+ Static[StaticTeam2].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam2].Visible := False;
+ Text[TextNameTeam2].Visible := False;
+ Static[StaticTeam2].Visible := False;
+ end;
+
+ if (PartySession.Teams.NumTeams >= 3) then
+ begin
+ Text[TextScoreTeam3].Text := InttoStr(PartySession.Teams.TeamInfo[2].Score);
+ Text[TextNameTeam3].Text := String(PartySession.Teams.TeamInfo[2].Name);
+
+ Text[TextScoreTeam3].Visible := True;
+ Text[TextNameTeam3].Visible := True;
+ Static[StaticTeam3].Visible := True;
+ end
+ else
+ begin
+ Text[TextScoreTeam3].Visible := False;
+ Text[TextNameTeam3].Visible := False;
+ Static[StaticTeam3].Visible := False;
+ end;
+
+
+// LCD.WriteText(1, ' Choose mode: ');
+// UpdateLCD;
+end;
+
+procedure TScreenPartyWin.SetAnimationProgress(Progress: real);
+begin
+ {if (ScreenSingModi.PlayerInfo.NumPlayers >= 1) then
+ Static[StaticTeam1].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[0].Score / maxScore;
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 2) then
+ Static[StaticTeam2].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[1].Score / maxScore;
+ if (ScreenSingModi.PlayerInfo.NumPlayers >= 3) then
+ Static[StaticTeam3].Texture.ScaleW := Progress * ScreenSingModi.PlayerInfo.Playerinfo[2].Score / maxScore;}
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenScore.dcu b/Game/Code/Screens/UScreenScore.dcu
new file mode 100644
index 00000000..eee72fd0
--- /dev/null
+++ b/Game/Code/Screens/UScreenScore.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenScore.pas b/Game/Code/Screens/UScreenScore.pas
new file mode 100644
index 00000000..2e509a6f
--- /dev/null
+++ b/Game/Code/Screens/UScreenScore.pas
@@ -0,0 +1,586 @@
+unit UScreenScore;
+
+interface
+
+uses
+ UMenu, SDL, SysUtils, UDisplay, UMusic, USongs, UThemes, ULCD, OpenGL;
+
+type
+ TScreenScore = class(TMenu)
+ public
+ TextArtist: integer;
+ TextTitle: integer;
+
+ TextName: array[1..6] of integer;
+ TextScore: array[1..6] of integer;
+
+ TextNotes: array[1..6] of integer;
+ TextNotesScore: array[1..6] of integer;
+ TextLineBonus: array[1..6] of integer;
+ TextLineBonusScore: array[1..6] of integer;
+ TextGoldenNotes: array[1..6] of integer;
+ TextGoldenNotesScore: array[1..6] of integer;
+ TextTotal: array[1..6] of integer;
+ TextTotalScore: array[1..6] of integer;
+
+ PlayerStatic: array[1..6] of array of integer;
+
+ StaticBoxLightest: array[1..6] of integer;
+ StaticBoxLight: array[1..6] of integer;
+ StaticBoxDark: array[1..6] of integer;
+
+ StaticBackLevel: array[1..6] of integer;
+ StaticBackLevelRound: array[1..6] of integer;
+ StaticLevel: array[1..6] of integer;
+ StaticLevelRound: array[1..6] of integer;
+
+ Animation: real;
+ Fadeout: boolean;
+ constructor Create(Back: String); override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ function Draw: boolean; override;
+ procedure FillPlayer(Item, P: integer);
+ end;
+
+implementation
+
+{$IFDEF TRANSLATE}
+uses UGraphic, UScreenSong, UMenuStatic, UTime, UMain, UIni, ULanguage;
+{$ELSE}
+uses UGraphic, UScreenSong, UMenuStatic, UTime, UMain, UIni;
+{$ENDIF}
+function TScreenScore.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then begin
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+
+ SDLK_ESCAPE :
+ begin
+ if (not Fadeout) then begin
+// Music.StopShuffle;
+ FadeTo(@ScreenTop5);
+ Fadeout := true;
+ end;
+ end;
+ SDLK_RETURN:
+ begin
+ if (not Fadeout) then begin
+// Music.StopShuffle;
+ FadeTo(@ScreenTop5);
+ Fadeout := true;
+ end;
+ end;
+{ SDLK_SYSREQ:
+ begin
+ beep;
+ end;}
+ SDLK_SYSREQ:
+ begin
+ Display.PrintScreen;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenScore.Create(Back: String);
+var
+ P: integer;
+ I: integer;
+begin
+ inherited Create(Back);
+
+ // background arrows sorted from farthest to nearest
+{ AddStatic(-2000 + 400, 100, 360, 60, 1, 1, 1, Skin.Arrow2, 'JPG', 'Arrow');
+ AddStatic(-2000 + -50, 200, 420, 70, 1, 1, 1, Skin.Arrow, 'JPG', 'Arrow');
+ AddStatic(-2000 + 90, 30, 500, 90, 1, 1, 1, Skin.Arrow, 'JPG', 'Arrow');
+ AddStatic(-2000 + -250, 100, 800, 150, 1, 1, 1, Skin.Arrow, 'JPG', 'Arrow');
+
+ Static[0].Texture.Rot := 100 * pi/180;
+ Static[1].Texture.Rot := 7 * pi/180;
+ Static[2].Texture.Rot := 35 * pi/180;
+
+
+ // main arrow with text
+ AddStatic(0, 340, 1000, 180, 1, 1, 1, Skin.Arrow2, 'JPG', 'Arrow');
+// AddText(450, 409, 4, 15, 1, 1, 1, 'Smile');
+ AddText(450, 409, 4, 15, 1, 1, 1, 'Let''s see the results');
+ Text[0].Y := 401;
+
+ Static[4].Texture.Rot := -3 * pi/180;
+
+
+ // two mid arrows
+ AddStatic(-2000 + -250, 100, 800, 150, 1, 1, 1, Skin.Arrow, 'JPG', 'Arrow');
+ AddStatic(-2000 + -250, 100, 800, 150, 1, 1, 1, Skin.Arrow, 'JPG', 'Arrow');
+
+
+ // last arrow
+ AddStatic(-2000, 340, 1100, 180, 1, 1, 1, Skin.Arrow2, 'JPG', 'Arrow');
+// AddText(-2000, 407, 4, 17, 1, 1, 1, 'SHUFFLE !');
+ AddText(-2000, 407, 4, 15, 1, 1, 1, 'SHUFFLE !');
+
+ Static[7].Texture.Rot := 184 * pi/180;
+
+ // score text
+ AddText(-2000, 407, 4, 17, 1, 1, 1, '10010 points');
+ AddText(-2000, 407, 4, 17, 1, 1, 1, 'Cheater');
+
+ Fadeout := false;}
+
+
+ // Singstar Theme
+ AddBackground(Theme.Score.Background.Tex);
+
+ for I := 0 to High(Theme.Score.Static) do
+ AddStatic(Theme.Score.Static[I]);
+
+ for I := 0 to High(Theme.Score.Text) do
+ AddText(Theme.Score.Text[I]);
+
+ TextArtist := AddText(Theme.Score.TextArtist);
+ TextTitle := AddText(Theme.Score.TextTitle);
+
+ for P := 1 to 6 do begin
+ TextName[P] := AddText(Theme.Score.TextName[P]);
+ TextScore[P] := AddText(Theme.Score.TextScore[P]);
+
+ TextNotes[P] := AddText(Theme.Score.TextNotes[P]);
+ TextNotesScore[P] := AddText(Theme.Score.TextNotesScore[P]);
+ TextLineBonus[P] := AddText(Theme.Score.TextLineBonus[P]);
+ TextLineBonusScore[P] := AddText(Theme.Score.TextLineBonusScore[P]);
+ TextGoldenNotes[P] := AddText(Theme.Score.TextGoldenNotes[P]);
+ TextGoldenNotesScore[P] := AddText(Theme.Score.TextGoldenNotesScore[P]);
+ TextTotal[P] := AddText(Theme.Score.TextTotal[P]);
+ TextTotalScore[P] := AddText(Theme.Score.TextTotalScore[P]);
+
+ SetLength(PlayerStatic[P], Length(Theme.Score.PlayerStatic[P]));
+ for I := 0 to High(Theme.Score.PlayerStatic[P]) do
+ PlayerStatic[P, I] := AddStatic(Theme.Score.PlayerStatic[P, I]);
+
+ StaticBoxLightest[P] := AddStatic(Theme.Score.StaticBoxLightest[P]);
+ StaticBoxLight[P] := AddStatic(Theme.Score.StaticBoxLight[P]);
+ StaticBoxDark[P] := AddStatic(Theme.Score.StaticBoxDark[P]);
+
+ StaticBackLevel[P] := AddStatic(Theme.Score.StaticBackLevel[P]);
+ StaticBackLevelRound[P] := AddStatic(Theme.Score.StaticBackLevelRound[P]);
+ StaticLevel[P] := AddStatic(Theme.Score.StaticLevel[P]);
+ StaticLevelRound[P] := AddStatic(Theme.Score.StaticLevelRound[P]);
+ end;
+end;
+
+procedure TScreenScore.onShow;
+var
+ P: integer; // player
+ PP: integer; // another player variable
+ S: string;
+ I: integer;
+ Lev: real;
+ Skip: integer;
+ V: array[1..6] of boolean; // visibility array
+ MaxH: real; // maximum height of score bar
+ Wsp: real;
+begin
+{ CountSkipTimeSet;
+
+ Animation := 0;
+ Fadeout := false;
+
+ Text[1].Text := AktSong.Artist + ' - ' + AktSong.Title;
+ Text[2].Text := ' ' + IntToStr((Round(Gracz[0].Punkty) div 10) * 10) + ' points';
+
+ Static[0].Texture.X := -2000;
+ Static[1].Texture.X := -2000;
+ Static[2].Texture.X := -2000;
+ Static[3].Texture.X := -2000;
+ Static[4].Texture.X := -2000;
+ Static[5].Texture.X := -2000;
+ Static[6].Texture.X := -2000;
+ Static[7].Texture.X := -2000;
+
+ Text[0].X := -2000;
+ Text[1].X := -2000;
+ Text[2].X := -2000;
+ Text[3].X := -2000;
+
+
+ case (Round(Gracz[0].Punkty) div 10) * 10 of
+ 0..1000: Text[3].Text := ' Tone Deaf';
+ 2010..4000: Text[3].Text := ' Amateur';
+ 4010..6000: Text[3].Text := ' Rising Star';
+ 6010..8000: Text[3].Text := ' Lead Singer';
+ 8010..9000: Text[3].Text := ' Hit Artist';
+ 9010..10000: Text[3].Text := ' Superstar';
+ end;
+
+ Music.PlayShuffle;}
+
+ // Singstar
+ Fadeout := false;
+
+ Text[TextArtist].Text := AktSong.Artist;
+ Text[TextTitle].Text := AktSong.Title;
+
+ // set visibility
+ case PlayersPlay of
+ 1: begin
+ V[1] := true;
+ V[2] := false;
+ V[3] := false;
+ V[4] := false;
+ V[5] := false;
+ V[6] := false;
+ end;
+ 2, 4: begin
+ V[1] := false;
+ V[2] := true;
+ V[3] := true;
+ V[4] := false;
+ V[5] := false;
+ V[6] := false;
+ end;
+ 3, 6: begin
+ V[1] := false;
+ V[2] := false;
+ V[3] := false;
+ V[4] := true;
+ V[5] := true;
+ V[6] := true;
+ end;
+ end;
+
+ for P := 1 to 6 do begin
+ Text[TextName[P]].Visible := V[P];
+ Text[TextScore[P]].Visible := V[P];
+
+ Text[TextNotes[P]].Visible := V[P];
+ Text[TextNotesScore[P]].Visible := V[P];
+ Text[TextLineBonus[P]].Visible := V[P];
+ Text[TextLineBonusScore[P]].Visible := V[P];
+ Text[TextGoldenNotes[P]].Visible := V[P];
+ Text[TextGoldenNotesScore[P]].Visible := V[P];
+ Text[TextTotal[P]].Visible := V[P];
+ Text[TextTotalScore[P]].Visible := V[P];
+
+ for I := 0 to high(PlayerStatic[P]) do
+ Static[PlayerStatic[P, I]].Visible := V[P];
+
+ Static[StaticBoxLightest[P]].Visible := V[P];
+ Static[StaticBoxLight[P]].Visible := V[P];
+ Static[StaticBoxDark[P]].Visible := V[P];
+
+ Static[StaticBackLevel[P]].Visible := V[P];
+ Static[StaticBackLevelRound[P]].Visible := V[P];
+ Static[StaticLevel[P]].Visible := V[P];
+ Static[StaticLevelRound[P]].Visible := V[P];
+ end;
+
+ if PlayersPlay <= 3 then begin // only for 1 screen mode
+ for P := 0 to PlayersPlay-1 do begin
+ case PlayersPlay of
+ 1: PP := 1;
+ 2: PP := P + 2;
+ 3: PP := P + 4;
+ end;
+ //PP := 1;
+
+ Text[TextName[PP]].Text := Ini.Name[P];
+
+ {$IFDEF TRANSLATE}
+ case (Player[P].ScoreTotalI) of
+ 0..2000: Text[TextScore[PP]].Text := Language.Translate('SING_SCORE_TONE_DEAF');
+ 2010..4000: Text[TextScore[PP]].Text := Language.Translate('SING_SCORE_AMATEUR');
+ 4010..6000: Text[TextScore[PP]].Text := Language.Translate('SING_SCORE_RISING_STAR');
+ 6010..8000: Text[TextScore[PP]].Text := Language.Translate('SING_SCORE_LEAD_SINGER');
+ 8010..9000: Text[TextScore[PP]].Text := Language.Translate('SING_SCORE_HIT_ARTIST');
+ 9010..9800: Text[TextScore[PP]].Text := Language.Translate('SING_SCORE_SUPERSTAR');
+ 9810..10000: Text[TextScore[PP]].Text := Language.Translate('SING_SCORE_ULTRASTAR');
+ end;
+ {$ELSE}
+ case (Player[P].ScoreTotalI) of
+ 0..2000: Text[TextScore[PP]].Text := 'Tone Deaf';
+ 2010..4000: Text[TextScore[PP]].Text := 'Amateur';
+ 4010..6000: Text[TextScore[PP]].Text := 'Rising Star';
+ 6010..8000: Text[TextScore[PP]].Text := 'Lead Singer';
+ 8010..9000: Text[TextScore[PP]].Text := 'Hit Artist';
+ 9010..9800: Text[TextScore[PP]].Text := 'Superstar';
+ 9810..10000: Text[TextScore[PP]].Text := 'Ultrastar';
+ end;
+ {$ENDIF}
+
+ S := IntToStr(Player[P].ScoreI);
+ while (Length(S)<4) do S := '0' + S;
+ Text[TextNotesScore[PP]].Text := S;
+
+ S := IntToStr(Player[P].ScoreLineI);
+ while (Length(S)<4) do S := '0' + S;
+ Text[TextLineBonusScore[PP]].Text := S;
+
+ S := IntToStr(Player[P].ScoreGoldenI);
+ while (Length(S)<4) do S := '0' + S;
+ Text[TextGoldenNotesScore[PP]].Text := S;
+
+ S := IntToStr(Player[P].ScoreTotalI);
+ while (Length(S)<5) do S := '0' + S;
+ Text[TextTotalScore[PP]].Text := S;
+
+ // Level bar length
+{ Lev := ((Round(Player[P].Punkty) div 10) * 10) / 10000;
+ Static[StaticLevel[PP]].Texture.H := Round(Static[StaticBackLevel[PP]].Texture.H * Lev);
+ Static[StaticLevel[PP]].Texture.Y := Static[StaticBackLevel[PP]].Texture.Y + Static[StaticBackLevel[PP]].Texture.H - Static[StaticLevel[PP]].Texture.H;
+ Static[StaticLevelRound[PP]].Texture.Y := Static[StaticLevel[PP]].Texture.Y - Static[StaticLevelRound[PP]].Texture.H;}
+ // doesn't align too much... (to fix)
+ // hint: play with wrapping textures
+ // resolution: setting TexY1 and TexY2 to 0.1 and 0.9
+
+ Lev := Player[P].ScoreTotalI / 10000;
+ MaxH := Static[StaticBackLevel[PP]].Texture.H + Static[StaticBackLevelRound[PP]].Texture.H / 2;
+
+ // developer note (Polish):
+ // w sumie np. 120 pix
+ // ten static moze miec 100 pix
+ // wlacza sie od 20 pix i rosnie do 120 pix
+ // wiec wysokosc = wyznaczona ilosc - 20
+ // nie moze byc mniejsze od 0
+ // Lev * MaxH = total number of pixels to draw
+ Static[StaticLevel[PP]].Visible := true;
+ Static[StaticLevel[PP]].Texture.H := Lev * MaxH - Static[StaticBackLevelRound[PP]].Texture.H / 2;
+ if Static[StaticLevel[PP]].Texture.H < 0 then Static[StaticLevel[PP]].Visible := false;
+
+ // Y doesn't change and depend on the back texture coordinate
+ Static[StaticLevel[PP]].Texture.Y := Static[StaticBackLevel[PP]].Texture.Y + Static[StaticBackLevel[PP]].Texture.H - Static[StaticLevel[PP]].Texture.H;
+
+ // we modify LevelRound texture by changing it's Y. TexY1 and TexY2 change when the height to draw is lower than 20
+ if Lev * MaxH < Static[StaticBackLevelRound[PP]].Texture.H / 2 then begin
+ // when it's lower than 20 => we move TexY1 and TexY2 higher to show only part of this texture
+ Static[StaticLevelRound[PP]].Texture.Y := Static[StaticBackLevel[PP]].Texture.Y + Static[StaticBackLevel[PP]].Texture.H - Static[StaticBackLevelRound[PP]].Texture.H;
+ // - 0.25 when points = 0
+ // - 0 wnen there are more points
+ // if Lev * MaxH = Static[StaticBackLevelRound[PP]].Texture.H / 2) then we do not change it
+ // if Lev * MaxH = 0 then we substract 0.25
+ // we substract (0.25 - 0.25 * (Lev * MaxH)/Static[StaticBackLevelRound[PP]].Texture.H / 2)
+ Wsp := Lev * MaxH / (Static[StaticBackLevelRound[PP]].Texture.H / 2);
+ Static[StaticLevelRound[PP]].Texture.TexY1 := Static[StaticBackLevelRound[PP]].Texture.TexY1 - 0.25 + 0.25 * Wsp;
+ Static[StaticLevelRound[PP]].Texture.TexY2 := Static[StaticBackLevelRound[PP]].Texture.TexY2 - 0.25 + 0.25 * Wsp;
+ end else begin
+ // when it's higher or equal 20 => full texture is being shown
+ Static[StaticLevelRound[PP]].Texture.TexY1 := Static[StaticBackLevelRound[PP]].Texture.TexY1;
+ Static[StaticLevelRound[PP]].Texture.TexY2 := Static[StaticBackLevelRound[PP]].Texture.TexY2;
+ Static[StaticLevelRound[PP]].Texture.Y := Static[StaticLevel[PP]].Texture.Y - Static[StaticBackLevelRound[PP]].Texture.H;
+ end;
+
+ end; // for
+ end; // if
+
+ LCD.HideCursor;
+ LCD.Clear;
+ LCD.WriteText(1, Ini.Name[0]);
+ LCD.WriteText(2, 'Score: ' + Text[TextTotalScore[1]].Text);
+
+end;
+
+function TScreenScore.Draw: boolean;
+var
+{ Min: real;
+ Max: real;
+ Wsp: real;
+ Wsp2: real;
+ Pet: integer;}
+
+ Item: integer;
+ P: integer;
+ C: integer;
+begin
+ // star animation
+{ Animation := Animation + TimeSkip*1000;
+
+ // move right
+ Min := 0; Max := 500;
+ if (Animation >= Min) and (Animation < Max) then begin
+ Wsp := (Animation - Min) / (Max - Min);
+ Wsp2 := 1 - Wsp;
+
+ Static[0].Texture.X := 400 + Wsp2 * 50; // prawa mala
+ Static[0].Texture.Y := 150 - Wsp2 * 500;
+ Static[1].Texture.X := -50 - Wsp2 * 500; // lewa mala
+ Static[1].Texture.Y := 200 + Wsp2 * 50;
+ Static[2].Texture.X := 100 - Wsp2 * 200; // gorna w prawo
+ Static[2].Texture.Y := 80 - Wsp2 * 200;
+ Static[3].Texture.X := -280 - Wsp2 * 1000; // lewa wieksza gorna
+ Static[3].Texture.Y := 90;
+
+
+ Static[4].Texture.X := -1200 + Wsp * 1000;
+ Text[0].X := Static[4].Texture.X + 430;
+ end;
+
+ // slowly move right
+ Min := 500; Max := 4100;
+ if (Animation >= Min) and (Animation < Max) then begin
+ Wsp := (Animation - Min) / (Max - Min);
+
+ Static[0].Texture.X := 400 - Wsp * 10; // prawa mala
+ Static[0].Texture.Y := 150 + Wsp * 50;
+ Static[1].Texture.X := -50 + Wsp * 50; // lewa mala
+ Static[1].Texture.Y := 200;
+ Static[2].Texture.X := 100 + Wsp * 50; // gorna w prawo
+ Static[2].Texture.Y := 80 + Wsp * 30;
+ Static[3].Texture.X := -280 + Wsp * 200; // lewa wieksza gorna
+ Static[3].Texture.Y := 90;
+
+ Static[4].Texture.X := -200 + Wsp * 150; // duza glowna
+ Text[0].X := Static[4].Texture.X + 430;
+ end;
+
+ // fast move right
+ Min := 4100; Max := 4400;
+ if (Animation >= Min) and (Animation < Max) then begin
+ Wsp := (Animation - Min) / (Max - Min);
+ Wsp2 := 1 - Wsp;
+
+ Static[0].Texture.X := 390 - Wsp * 200; // prawa mala
+ Static[0].Texture.Y := 200 + Wsp * 1000;
+ Static[1].Texture.X := 0 + Wsp * 1000; // lewa mala
+ Static[1].Texture.Y := 200;
+ Static[2].Texture.X := 150 + Wsp * 1000; // gorna w prawo
+ Static[2].Texture.Y := 110 + Wsp * 600;
+ Static[3].Texture.X := -80 + Wsp * 2000; // lewa wieksza gorna
+ Static[3].Texture.Y := 90;
+
+ Static[4].Texture.X := -50 + Wsp * 2000;
+ Text[0].X := Static[4].Texture.X + 430;
+
+ Static[7].Texture.X := 100 + Wsp2 * 3000;
+ Text[1].X := Static[7].Texture.X + 230; // 300
+ Text[1].Y := Static[7].Texture.Y + 140; // 120 Sh
+
+ Text[2].X := Static[7].Texture.X + 250;
+ Text[2].Y := Static[7].Texture.Y - 250;
+ Text[3].X := Static[7].Texture.X + 250;
+ Text[3].Y := Static[7].Texture.Y - 200;
+ end;
+
+ // last arrow
+ Min := 4400; Max := 8000;
+ if (Animation >= Min) and (Animation < Max) then begin
+ Wsp := (Animation - Min) / (Max - Min);
+
+ Static[7].Texture.X := 100 - Wsp * 100;
+ Text[1].X := Static[7].Texture.X + 230; // 300
+ Text[1].Y := Static[7].Texture.Y + 140; // 120
+
+ Text[2].X := Static[7].Texture.X + 250;
+ Text[2].Y := Static[7].Texture.Y - 250;
+ Text[3].X := Static[7].Texture.X + 250;
+ Text[3].Y := Static[7].Texture.Y - 200;
+ end;
+
+ // fade last arrow to left
+ Min := 8000; Max := 8300;
+ if (Animation >= Min) and (Animation < Max) then begin
+ Wsp := (Animation - Min) / (Max - Min);
+
+ Static[7].Texture.X := 0 - Wsp * 3000;
+ Static[7].Texture.Y := 340 - Wsp * 50;
+ Text[1].X := Static[7].Texture.X + 230; // 300 Sh
+ Text[1].Y := Static[7].Texture.Y + 140; // 120 Sh
+
+ Text[2].X := Static[7].Texture.X + 250;
+ Text[2].Y := Static[7].Texture.Y - 250;
+ Text[3].X := Static[7].Texture.X + 250;
+ Text[3].Y := Static[7].Texture.Y - 200;
+ end;
+
+ Min := 8300;
+ if (Animation >= Min) and (not Fadeout) then begin
+ Music.StopShuffle;
+ FadeTo(@ScreenSong);
+ Fadeout := true;
+ end;}
+
+
+ // 0.5.0: try also use 4 players screen with nicks
+ if PlayersPlay = 4 then begin
+ for Item := 2 to 3 do begin
+ if ScreenAct = 1 then P := Item-2;
+ if ScreenAct = 2 then P := Item;
+
+ FillPlayer(Item, P);
+ end;
+ end;
+
+
+ // Singstar - let it be...... with 6 statics
+ if PlayersPlay = 6 then begin
+ for Item := 4 to 6 do begin
+ if ScreenAct = 1 then P := Item-4;
+ if ScreenAct = 2 then P := Item-1;
+
+ FillPlayer(Item, P);
+
+{ if ScreenAct = 1 then begin
+ LoadColor(
+ Static[StaticBoxLightest[Item]].Texture.ColR,
+ Static[StaticBoxLightest[Item]].Texture.ColG,
+ Static[StaticBoxLightest[Item]].Texture.ColB,
+ 'P1Dark');
+ end;
+
+ if ScreenAct = 2 then begin
+ LoadColor(
+ Static[StaticBoxLightest[Item]].Texture.ColR,
+ Static[StaticBoxLightest[Item]].Texture.ColG,
+ Static[StaticBoxLightest[Item]].Texture.ColB,
+ 'P4Dark');
+ end;}
+
+ end;
+ end;
+
+ inherited Draw;
+end;
+
+procedure TScreenScore.FillPlayer(Item, P: integer);
+var
+ S: string;
+begin
+ Text[TextName[Item]].Text := Ini.Name[P];
+
+ S := IntToStr((Round(Player[P].Score) div 10) * 10);
+ while (Length(S)<4) do S := '0' + S;
+ Text[TextNotesScore[Item]].Text := S;
+
+ while (Length(S)<5) do S := '0' + S;
+ Text[TextTotalScore[Item]].Text := S;
+
+ LoadColor(
+ Text[TextName[Item]].ColR,
+ Text[TextName[Item]].ColG,
+ Text[TextName[Item]].ColB,
+ 'P' + IntToStr(P+1) + 'Dark');
+
+ LoadColor(
+ Static[StaticBoxLightest[Item]].Texture.ColR,
+ Static[StaticBoxLightest[Item]].Texture.ColG,
+ Static[StaticBoxLightest[Item]].Texture.ColB,
+ 'P' + IntToStr(P+1) + 'Lightest');
+
+ LoadColor(
+ Static[StaticBoxLight[Item]].Texture.ColR,
+ Static[StaticBoxLight[Item]].Texture.ColG,
+ Static[StaticBoxLight[Item]].Texture.ColB,
+ 'P' + IntToStr(P+1) + 'Light');
+
+ LoadColor(
+ Static[StaticBoxDark[Item]].Texture.ColR,
+ Static[StaticBoxDark[Item]].Texture.ColG,
+ Static[StaticBoxDark[Item]].Texture.ColB,
+ 'P' + IntToStr(P+1) + 'Dark');
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenSing.dcu b/Game/Code/Screens/UScreenSing.dcu
new file mode 100644
index 00000000..0e227a17
--- /dev/null
+++ b/Game/Code/Screens/UScreenSing.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenSing.pas b/Game/Code/Screens/UScreenSing.pas
new file mode 100644
index 00000000..2a97482d
--- /dev/null
+++ b/Game/Code/Screens/UScreenSing.pas
@@ -0,0 +1,1121 @@
+unit UScreenSing;
+
+interface
+
+uses UMenu, UMusic, SDL, SysUtils, UPliki, UTime, USongs, UIni, ULog, USmpeg, UTexture, ULyrics,
+ TextGL, OpenGL12, BASS, UThemes, ULCD;
+
+type
+ TScreenSing = class(TMenu)
+ 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;
+
+ 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);
+ 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_ESCAPE :
+ begin
+ //Record Sound Hack:
+ //Sound[0].BufferLong
+
+ Finish;
+ Music.PlayBack;
+ FadeTo(@ScreenScore);
+ end;
+
+ SDLK_Q:
+ begin
+ Finish;
+ Result := false;
+ 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
+ else // Key Up
+ case PressedKey of
+ SDLK_RETURN :
+ begin
+ end;
+ end;
+end;
+
+//Pause Mod
+procedure TScreenSing.Pause;
+begin
+ if not paused then //Pause einschalten
+ begin
+ PauseTime := Czas.Teraz;
+ Paused := true;
+ //stop Music
+ Music.Pause;
+ if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then //Video
+ PauseSmpeg; //Video
+ end
+ else //Pause ausschalten
+ begin
+ Czas.Teraz := PauseTime; //Position of Notes
+ Music.MoveTo (PauseTime);//Position of Music
+ Music.Play; //Play Music
+ if (AktSong.Video <> '') and FileExists(AktSong.Path + AktSong.Video) then //Video
+ PlaySmpeg;
+ //SkipSmpeg(PauseTime);
+ Paused := false;
+ end;
+end;
+//Pause Mod End
+
+constructor TScreenSing.Create;
+var
+ I: integer;
+ P: integer;
+begin
+ inherited Create;
+
+ AddBackground(Theme.Sing.Background.Tex);
+
+ for I := 0 to High(Theme.Sing.Static) do
+ AddStatic(Theme.Sing.Static[I]);
+
+ for I := 0 to High(Theme.Sing.Text) do
+ AddText(Theme.Sing.Text[I]);
+
+ // time
+ TextTime := AddText(75, 14, 1, 8, 0.25, 0.25, 0.25, '00:00');
+
+ StaticP1 := AddStatic(Theme.Sing.StaticP1);
+ StaticP1ScoreBG := AddStatic(Theme.Sing.StaticP1ScoreBG);
+ TextP1 := AddText(Theme.Sing.TextP1);
+ TextP1Score := AddText(Theme.Sing.TextP1Score);
+
+ StaticP2R := AddStatic(Theme.Sing.StaticP2R);
+ StaticP2RScoreBG := AddStatic(Theme.Sing.StaticP2RScoreBG);
+ TextP2R := AddText(Theme.Sing.TextP2R);
+ TextP2RScore := AddText(Theme.Sing.TextP2RScore);
+
+ StaticP2M := AddStatic(Theme.Sing.StaticP2M);
+ StaticP2MScoreBG := AddStatic(Theme.Sing.StaticP2MScoreBG);
+ TextP2M := AddText(Theme.Sing.TextP2M);
+ TextP2MScore := AddText(Theme.Sing.TextP2MScore);
+
+ StaticP3R := AddStatic(Theme.Sing.StaticP3R);
+ StaticP3RScoreBG := AddStatic(Theme.Sing.StaticP3RScoreBG);
+ TextP3R := AddText(Theme.Sing.TextP3R);
+ TextP3RScore := AddText(Theme.Sing.TextP3RScore);
+
+ LyricMain := TLyric.Create;
+ LyricSub := TLyric.Create;
+end;
+
+procedure TScreenSing.onShow;
+var
+ P: integer;
+ V1: boolean;
+ 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;
+ V2R := false;
+ V2M := false;
+ V3R := false;
+ end;
+ 2: begin
+ V1 := true;
+ V2R := true;
+ V2M := false;
+ V3R := false;
+ end;
+ 3: begin
+ V1 := true;
+ V2R := false;
+ V2M := true;
+ V3R := true;
+ end;
+ 4: begin // double screen
+ V1 := true;
+ V2R := true;
+ V2M := false;
+ V3R := false;
+ end;
+ 6: begin // double screen
+ V1 := true;
+ V2R := false;
+ V2M := true;
+ V3R := true;
+ end;
+
+ end;
+
+
+
+ Static[StaticP2R].Visible := V2R;
+ Static[StaticP2RScoreBG].Visible := V2R;
+ Text[TextP2R].Visible := V2R;
+ Text[TextP2RScore].Visible := V2R;
+
+ 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
+ CzyscNuty;
+// Log.LogWarning(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName, '!!!');
+ AktSong := CatSongs.Song[CatSongs.Selected];
+
+ WczytajCzesci(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName);
+ 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);
+ AktSong.VideoLoaded := true;
+ end;
+
+ // set background
+ if (AktSong.Background <> '') and (AktSong.VideoLoaded = false) then
+ Tex_Background := Texture.LoadTexture(AktSong.Path + AktSong.Background)
+ 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 + 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 := 26/255;
+ LyricMain.ColSG := 165/255;
+ LyricMain.ColSB := 220/255;
+
+ LyricSub.ColR := 0.6;
+ LyricSub.ColG := 0.6;
+ LyricSub.ColB := 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;
+
+ {Static[StaticP2R].Visible := V2R;
+ Static[StaticP2RScoreBG].Visible := V2R;
+ Text[TextP2R].Visible := V2R;
+ Text[TextP2RScore].Visible := V2R;
+
+ 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;}
+
+ //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.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;
+
+ //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.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;
+
+ //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.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;
+
+ //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.StaticP1ScoreBG.x;
+ Player[2].LineBonus_TargetY := Theme.Sing.TextP1Score.Y;
+ Player[2].LineBonus_StartX := Theme.Sing.StaticP1ScoreBG.x;
+ Player[2].LineBonus_StartY := Theme.Sing.TextP1Score.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.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;
+
+ //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.StaticP1ScoreBG.x;
+ Player[3].LineBonus_TargetY := Theme.Sing.TextP1Score.Y;
+ Player[3].LineBonus_StartX := Theme.Sing.StaticP1ScoreBG.x;
+ Player[3].LineBonus_StartY := Theme.Sing.TextP1Score.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
+ //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);
+
+ // 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 - 87);
+ Player[0].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_StartY := Skin_P2_NotesB - 105;
+ end;
+
+ 2: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
+ end;
+
+ 3: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_TargetY := 120 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_StartY := 120 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_TargetY := 245 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_StartY := 245 + 28;
+
+ //P3
+ Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[2].LineBonus_TargetY := 370 - 65 + 28;
+ Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[2].LineBonus_StartY := 370 + 28;
+ end;
+
+ 4: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
+
+ //P3
+ Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[2].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
+ Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[2].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
+
+ //P4
+ Player[3].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[3].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
+ Player[3].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[3].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
+ end;
+
+ 6: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_TargetY := 120 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_StartY := 120 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_TargetY := 245 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_StartY := 245 + 28;
+
+ //P3
+ Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[2].LineBonus_TargetY := 370 - 65 + 28;
+ Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[2].LineBonus_StartY := 370 + 28;
+
+ //P4
+ Player[3].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[3].LineBonus_TargetY := 120 - 65 + 28;
+ Player[3].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[3].LineBonus_StartY := 120 + 28;
+
+ //P5
+ Player[4].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[4].LineBonus_TargetY := 245 - 65 + 28;
+ Player[4].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[4].LineBonus_StartY := 245 + 28;
+
+ //P6
+ Player[5].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[5].LineBonus_TargetY := 370 - 65 + 28;
+ Player[5].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ 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 PlaySmpeg;
+
+ // 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
+ // set player colors
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ LoadColor(Static[StaticP1].Texture.ColR, Static[StaticP1].Texture.ColG,
+ Static[StaticP1].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P2Dark');
+
+
+
+ LoadColor(Static[StaticP1ScoreBG].Texture.ColR, Static[StaticP1ScoreBG].Texture.ColG,
+ Static[StaticP1ScoreBG].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[StaticP1].Texture.ColR, Static[StaticP1].Texture.ColG,
+ Static[StaticP1].Texture.ColB, 'P3Dark');
+ LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P4Dark');
+
+
+
+ LoadColor(Static[StaticP1ScoreBG].Texture.ColR, Static[StaticP1ScoreBG].Texture.ColG,
+ Static[StaticP1ScoreBG].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[StaticP1].Texture.ColR, Static[StaticP1].Texture.ColG,
+ Static[StaticP1].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[StaticP1ScoreBG].Texture.ColR, Static[StaticP1ScoreBG].Texture.ColG,
+ Static[StaticP1ScoreBG].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[StaticP1].Texture.ColR, Static[StaticP1].Texture.ColG,
+ Static[StaticP1].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[StaticP1ScoreBG].Texture.ColR, Static[StaticP1ScoreBG].Texture.ColG,
+ Static[StaticP1ScoreBG].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;
+
+//Original 0.5.0
+{ // set player colors
+ if PlayersPlay = 4 then begin
+ if ScreenAct = 1 then begin
+ //LoadColor(Static[StaticP1].Texture.ColR, Static[StaticP1].Texture.ColG,
+ //Static[StaticP1].Texture.ColB, 'P1Dark');
+// LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
+ // Static[StaticP2R].Texture.ColB, 'P2Dark');
+ end;
+ if ScreenAct = 2 then begin
+ LoadColor(Static[StaticP1].Texture.ColR, Static[StaticP1].Texture.ColG,
+ Static[StaticP1].Texture.ColB, 'P3Dark');
+ LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P4Dark');
+ end;
+ end;
+
+ if PlayersPlay = 6 then begin
+ if ScreenAct = 1 then begin
+ LoadColor(Static[StaticP1].Texture.ColR, Static[StaticP1].Texture.ColG,
+ Static[StaticP1].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');
+ end;
+ if ScreenAct = 2 then begin
+ LoadColor(Static[StaticP1].Texture.ColR, Static[StaticP1].Texture.ColG,
+ Static[StaticP1].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');
+ 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[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[TextP1].Text := 'P3';
+ Text[TextP2R].Text := 'P4';
+ end;
+ 6: begin
+ Text[TextP1].Text := 'P4';
+ Text[TextP2M].Text := 'P5';
+ Text[TextP3R].Text := 'P6';
+ end;
+ end; // case
+ end; // if
+
+ // 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;
+
+ // update static menu with time ...
+ Min := Round(Czas.Teraz) div 60;
+ Sec := Round(Czas.Teraz) mod 60;
+ Text[TextTime].Text := '';
+ if Min < 10 then Text[TextTime].Text := '0';
+ Text[TextTime].Text := Text[TextTime].Text + IntToStr(Min) + ':';
+ if Sec < 10 then Text[TextTime].Text := Text[TextTime].Text + '0';
+ Text[TextTime].Text := Text[TextTime].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[TextP1Score].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[TextP1Score].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[TextP1Score].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[TextP1Score].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[TextP1Score].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[TextP1Score].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;
+
+
+ // beat flash
+{ Flash := 1 - (Czas.MidBeat - Czas.AktBeat);
+ if (Czas.AktBeat + AktSong.NotesGAP) mod AktSong.Resolution = 0 then Flash := 1
+ else Flash := 0;
+ if Czas.AktBeat < 0 then Flash := 0;
+ glClearColor(Flash, Flash, Flash, 1);}
+
+ // beat sound
+// if (Ini.BeatClick = 1) and (Flash = 1) and (Czas.AktBeat <> Czas.OldBeat) then Music.PlayClick;
+
+ // draw static menu (BG)
+ DrawBG;
+ //Draw Background
+ SingDrawBackground;
+ // update and draw movie
+ if ShowFinish and AktSong.VideoLoaded then begin
+ UpdateSmpeg; // this only draws
+ 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
+
+
+ // 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 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;
+ AktSong.VideoLoaded := false; // to prevent drawing closed video
+ end;
+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
+
+ If (Ini.LineBonus > 0) then
+ begin
+
+ //Generate Steps 0 to 8
+ A := Floor(A / (B * Czesci[0].Czesc[S].TotalNotes / Czesci[0].Wartosc) * 8);
+ if A >= 8 then
+ Player[I].LineBonus_Text := Language.Translate('LINEBONUS_PERFECT')
+ else if (A = 6) or (A = 7) then
+ Player[I].LineBonus_Text := Language.Translate('LINEBONUS_BETTER')
+ else if A = 5 then
+ Player[I].LineBonus_Text := Language.Translate('LINEBONUS_GOOD')
+ else if (A = 3) or (A = 4) then
+ Player[I].LineBonus_Text := Language.Translate('LINEBONUS_NORMAL')
+ else if A = 2 then
+ Player[I].LineBonus_Text := Language.Translate('LINEBONUS_BAD')
+ else
+ Player[I].LineBonus_Text := Language.Translate('LINEBONUS_WORST');
+
+ //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
+ 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;
+
+
+
+ end;
+
+//Refresh LastScore
+Player[I].ScoreLast := Player[I].Score + Player[I].ScoreGolden;
+
+end;
+//PhrasenBonus - Line Bonus Mod End// }
+
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenSingModi.dcu b/Game/Code/Screens/UScreenSingModi.dcu
new file mode 100644
index 00000000..4f806afe
--- /dev/null
+++ b/Game/Code/Screens/UScreenSingModi.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenSingModi.pas b/Game/Code/Screens/UScreenSingModi.pas
new file mode 100644
index 00000000..88034f61
--- /dev/null
+++ b/Game/Code/Screens/UScreenSingModi.pas
@@ -0,0 +1,1088 @@
+unit UScreenSingModi;
+
+interface
+
+uses UMenu, UMusic, SDL, SysUtils, UPliki, UTime, USongs, UIni, ULog, USmpeg, 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;
+
+// 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 :
+ 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
+ P: integer;
+ V1: boolean;
+ V2R: boolean;
+ V2M: boolean;
+ V3R: boolean;
+ NR: TRecR; //Line Bonus Mod }
+var
+ I: Integer;
+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;
+ V2R := false;
+ V2M := false;
+ V3R := false;
+ end;
+ 2: begin
+ V1 := true;
+ V2R := true;
+ V2M := false;
+ V3R := false;
+ end;
+ 3: begin
+ V1 := true;
+ V2R := false;
+ V2M := true;
+ V3R := true;
+ end;
+ 4: begin // double screen
+ V1 := true;
+ V2R := true;
+ V2M := false;
+ V3R := false;
+ end;
+ 6: begin // double screen
+ V1 := true;
+ V2R := false;
+ V2M := true;
+ V3R := true;
+ end;
+
+ end;
+
+
+
+ Static[StaticP2R].Visible := V2R;
+ Static[StaticP2RScoreBG].Visible := V2R;
+ Text[TextP2R].Visible := V2R;
+ Text[TextP2RScore].Visible := V2R;
+
+ 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
+ CzyscNuty;
+// Log.LogWarning(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName, '!!!');
+ AktSong := CatSongs.Song[CatSongs.Selected];
+
+ WczytajCzesci(CatSongs.Song[CatSongs.Selected].Path + CatSongs.Song[CatSongs.Selected].FileName);
+ 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);
+ AktSong.VideoLoaded := true;
+ end;
+
+ // set background
+ if (AktSong.Background <> '') and (AktSong.VideoLoaded = false) then
+ Tex_Background := Texture.LoadTexture(AktSong.Path + AktSong.Background)
+ 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 + 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 := 26/255;
+ LyricMain.ColSG := 165/255;
+ LyricMain.ColSB := 220/255;
+
+ LyricSub.ColR := 0.6;
+ LyricSub.ColG := 0.6;
+ LyricSub.ColB := 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;
+
+ {Static[StaticP2R].Visible := V2R;
+ Static[StaticP2RScoreBG].Visible := V2R;
+ Text[TextP2R].Visible := V2R;
+ Text[TextP2RScore].Visible := V2R;
+
+ 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;} {
+
+ //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.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;
+
+ //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.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;
+
+ //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.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;
+
+ //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.StaticP1ScoreBG.x;
+ Player[2].LineBonus_TargetY := Theme.Sing.TextP1Score.Y;
+ Player[2].LineBonus_StartX := Theme.Sing.StaticP1ScoreBG.x;
+ Player[2].LineBonus_StartY := Theme.Sing.TextP1Score.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.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;
+
+ //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.StaticP1ScoreBG.x;
+ Player[3].LineBonus_TargetY := Theme.Sing.TextP1Score.Y;
+ Player[3].LineBonus_StartX := Theme.Sing.StaticP1ScoreBG.x;
+ Player[3].LineBonus_StartY := Theme.Sing.TextP1Score.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
+ //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);
+
+ // 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 - 87);
+ Player[0].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_StartY := Skin_P2_NotesB - 105;
+ end;
+
+ 2: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
+ end;
+
+ 3: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_TargetY := 120 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_StartY := 120 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_TargetY := 245 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_StartY := 245 + 28;
+
+ //P3
+ Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[2].LineBonus_TargetY := 370 - 65 + 28;
+ Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[2].LineBonus_StartY := 370 + 28;
+ end;
+
+ 4: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
+
+ //P3
+ Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[2].LineBonus_TargetY := Skin_P1_NotesB - 105 - 65 + 28;
+ Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[2].LineBonus_StartY := Skin_P1_NotesB - 105 + 28;
+
+ //P4
+ Player[3].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[3].LineBonus_TargetY := Skin_P2_NotesB - 105 - 65 + 28;
+ Player[3].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[3].LineBonus_StartY := Skin_P2_NotesB - 105 + 28;
+ end;
+
+ 6: begin
+ //P1
+ Player[0].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_TargetY := 120 - 65 + 28;
+ Player[0].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[0].LineBonus_StartY := 120 + 28;
+
+ //P2
+ Player[1].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_TargetY := 245 - 65 + 28;
+ Player[1].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[1].LineBonus_StartY := 245 + 28;
+
+ //P3
+ Player[2].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[2].LineBonus_TargetY := 370 - 65 + 28;
+ Player[2].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[2].LineBonus_StartY := 370 + 28;
+
+ //P4
+ Player[3].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[3].LineBonus_TargetY := 120 - 65 + 28;
+ Player[3].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[3].LineBonus_StartY := 120 + 28;
+
+ //P5
+ Player[4].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[4].LineBonus_TargetY := 245 - 65 + 28;
+ Player[4].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[4].LineBonus_StartY := 245 + 28;
+
+ //P6
+ Player[5].LineBonus_TargetX := Round(Nr.Right + 10*ScreenX - 87);
+ Player[5].LineBonus_TargetY := 370 - 65 + 28;
+ Player[5].LineBonus_StartX := Round(Nr.Right + 10*ScreenX - 87);
+ 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'); }
+
+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[StaticP1ScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ScoreBG].Texture.Y + Static[StaticP1ScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[2].PosX := Static[StaticP1ScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[2].PosY := Static[StaticP1ScoreBG].Texture.Y + Static[StaticP1ScoreBG].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[StaticP1ScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[0].PosY := Static[StaticP1ScoreBG].Texture.Y + Static[StaticP1ScoreBG].Texture.H;
+ PlayerInfo.Playerinfo[3].PosX := Static[StaticP1ScoreBG].Texture.X;
+ PlayerInfo.Playerinfo[3].PosY := Static[StaticP1ScoreBG].Texture.Y + Static[StaticP1ScoreBG].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;
+
+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[TextP1Score].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP1ScoreBG].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[TextP1Score].Visible := DLLMan.Selected.ShowScore;
+ Static[StaticP1ScoreBG].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[StaticP1].Texture.ColR, Static[StaticP1].Texture.ColG,
+ Static[StaticP1].Texture.ColB, 'P1Dark');
+ LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P2Dark');
+
+
+
+ LoadColor(Static[StaticP1ScoreBG].Texture.ColR, Static[StaticP1ScoreBG].Texture.ColG,
+ Static[StaticP1ScoreBG].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[StaticP1].Texture.ColR, Static[StaticP1].Texture.ColG,
+ Static[StaticP1].Texture.ColB, 'P3Dark');
+ LoadColor(Static[StaticP2R].Texture.ColR, Static[StaticP2R].Texture.ColG,
+ Static[StaticP2R].Texture.ColB, 'P4Dark');
+
+
+
+ LoadColor(Static[StaticP1ScoreBG].Texture.ColR, Static[StaticP1ScoreBG].Texture.ColG,
+ Static[StaticP1ScoreBG].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[StaticP1].Texture.ColR, Static[StaticP1].Texture.ColG,
+ Static[StaticP1].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[StaticP1ScoreBG].Texture.ColR, Static[StaticP1ScoreBG].Texture.ColG,
+ Static[StaticP1ScoreBG].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[StaticP1].Texture.ColR, Static[StaticP1].Texture.ColG,
+ Static[StaticP1].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[StaticP1ScoreBG].Texture.ColR, Static[StaticP1ScoreBG].Texture.ColG,
+ Static[StaticP1ScoreBG].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[TextP2R].Text := 'P2';
+ Text[TextP2M].Text := 'P2';
+ Text[TextP3R].Text := 'P3';
+ end;
+
+ if ScreenAct = 2 then begin
+ case PlayersPlay of
+ 4: begin
+ Text[TextP1].Text := 'P3';
+ Text[TextP2R].Text := 'P4';
+ end;
+ 6: begin
+ Text[TextP1].Text := 'P4';
+ Text[TextP2M].Text := 'P5';
+ Text[TextP3R].Text := 'P6';
+ end;
+ end; // case
+ end; // if
+
+
+ // 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;
+
+ // .. 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[TextP1Score].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[TextP1Score].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[TextP1Score].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[TextP1Score].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[TextP1Score].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[TextP1Score].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[TextTime].Text := '';
+ if Min < 10 then Text[TextTime].Text := '0';
+ Text[TextTime].Text := Text[TextTime].Text + IntToStr(Min) + ':';
+ if Sec < 10 then Text[TextTime].Text := Text[TextTime].Text + '0';
+ Text[TextTime].Text := Text[TextTime].Text + IntToStr(Sec);
+end;
+
+ // draw static menu (BG)
+ DrawBG;
+
+ //Draw Background
+ if (DllMan.Selected.LoadSong) AND (DllMan.Selected.LoadBack) then
+ SingDrawBackground;
+
+ // update and draw movie
+ 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
+
+ //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;
+ Result.ScaleW := Tex.ScaleW;
+ Result.ScaleH := Tex.ScaleH;
+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.dcu b/Game/Code/Screens/UScreenSong.dcu
new file mode 100644
index 00000000..abc9cc4f
--- /dev/null
+++ b/Game/Code/Screens/UScreenSong.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenSong.pas b/Game/Code/Screens/UScreenSong.pas
new file mode 100644
index 00000000..0d7860a7
--- /dev/null
+++ b/Game/Code/Screens/UScreenSong.pas
@@ -0,0 +1,1690 @@
+unit UScreenSong;
+
+interface
+
+uses
+ UMenu, SDL, UMusic, UPliki, UTime, UDisplay, USongs, SysUtils, ULog, UThemes, UTexture, ULanguage,
+ ULCD, ULight, UIni;
+
+type
+ TScreenSong = class(TMenu)
+ public
+ TextArtist: integer;
+ TextTitle: integer;
+ TextNumber: integer;
+
+ 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;
+
+ constructor Create; override;
+ procedure SetScroll;
+ procedure SetScroll1;
+ procedure SetScroll2;
+ procedure SetScroll3;
+ procedure SetScroll4;
+ procedure SetScroll5;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+ procedure onShow; override;
+ procedure SelectNext;
+ procedure SelectPrev;
+ procedure UpdateLCD;
+ procedure SkipTo(Target: integer);
+ 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 Tob left
+ procedure HideCatTL;// Show Cat in Tob left
+ procedure Refresh; //Refresh Song Sorting
+ procedure DrawEqualizer;
+ //Party Mode
+ procedure SelectRandomSong;
+ procedure SetJoker;
+
+ //procedures for Menu
+ procedure StartSong;
+ procedure OpenEditor;
+ procedure DoJoker(Team: Byte);
+ end;
+
+implementation
+uses UGraphic, UMain, UCovers, math, OpenGL12, Windows, USkins, UDLLManager, UParty, UScreenSongMenu;
+
+// ***** Public methods ****** //
+
+//Show Wrong Song when Tabs on Fix
+procedure TScreenSong.FixSelected;
+var I, I2: Integer;
+ 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;
+
+procedure TScreenSong.FixSelected2;
+var I, I2: Integer;
+ 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;
+//Show Wrong Song when Tabs on Fix 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(CatSongs.Song[Cat].Path + CatSongs.Song[Cat].Cover, '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;
+ 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 Menu
+ if (ScreenSongMenu.Visible) then
+ begin
+ Result := ScreenSongMenu.ParseInput(PressedKey, ScanCode, PressedDown);
+ Exit;
+ end;
+
+ If (PressedDown) Then
+ begin // Key Down
+
+// HS := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT);
+{ if (not HighSpeed) and (HS > 0) then begin
+ HighSpeed := true;
+ SDL_EnableKeyRepeat(50, 50);
+ end;
+ if (HighSpeed) and (HS = 0) then begin
+ HighSpeed := false;
+ SDL_EnableKeyRepeat(125, 125);
+ end;}
+
+ SDL_ModState := SDL_GetModState and (KMOD_LSHIFT + KMOD_RSHIFT
+ + KMOD_LCTRL + KMOD_RCTRL + KMOD_LALT + KMOD_RALT);
+
+ // Jump to Key Mod
+ if (SDL_ModState = KMOD_LALT) AND (Mode = 0) then //Jump to Key
+ begin
+ //get Letter
+ case PressedKey of
+ SDLK_A : Letter := 'A';
+ SDLK_B : Letter := 'B';
+ SDLK_C : Letter := 'C';
+ SDLK_D : Letter := 'D';
+ SDLK_E : Letter := 'E';
+ SDLK_F : Letter := 'F';
+ SDLK_G : Letter := 'G';
+ SDLK_H : Letter := 'H';
+ SDLK_I : Letter := 'I';
+ SDLK_J : Letter := 'J';
+ SDLK_K : Letter := 'K';
+ SDLK_L : Letter := 'L';
+ SDLK_M : Letter := 'M';
+ SDLK_N : Letter := 'N';
+ SDLK_O : Letter := 'O';
+ SDLK_P : Letter := 'P';
+ SDLK_Q : Letter := 'Q';
+ SDLK_R : Letter := 'R';
+ SDLK_S : Letter := 'S';
+ SDLK_T : Letter := 'T';
+ SDLK_U : Letter := 'U';
+ SDLK_V : Letter := 'V';
+ SDLK_W : Letter := 'W';
+ SDLK_X : Letter := 'X';
+ SDLK_Y : Letter := 'Y';
+ SDLK_Z : Letter := 'Z';
+ SDLK_1 : Letter := '1';
+ SDLK_2 : Letter := '2';
+ SDLK_3 : Letter := '3';
+ SDLK_4 : Letter := '4';
+ SDLK_5 : Letter := '5';
+ SDLK_6 : Letter := '6';
+ SDLK_7 : Letter := '7';
+ SDLK_8 : Letter := '8';
+ SDLK_9 : Letter := '9';
+ SDLK_0 : Letter := '0';
+ else exit;
+ end;
+
+ {//Search Letter
+ for I := Interaction + 1 to high(CatSongs.Song) do
+ begin
+ if CatSongs.Song[I].Visible and (Letter = Uppercase(CatSongs.Song[I].Artist)[1]) then
+ break; //Found Song
+ if I = Interaction then //went through complete array but nothing Found
+ break;
+ if I = high(CatSongs.Song) then //At the end of the array->Go to beginning
+ for I2 := low(CatSongs.Song) to Interaction do
+ if CatSongs.Song[I].Visible and (Letter = Uppercase(CatSongs.Song[I].Artist)[1]) then
+ break; //Found Song
+ end; }
+
+ for I := 0 to High(CatSongs.Song) do begin
+ if (CatSongs.Song[I].Visible) AND (UpperCase(CatSongs.Song[I].Artist[1]) = Letter) then
+ begin
+ //Select Song
+ Interaction := I;
+ SkipTo(Interaction);
+ break;
+ end;
+ end;
+
+ //Don't do other Functions
+ exit;
+ end;
+
+ if (SDL_ModState = KMOD_LALT or KMOD_LSHIFT) then //Jump to Key
+ begin
+ //get Letter
+ case PressedKey of
+ SDLK_a..SDLK_z : Letter := Chr(Ord('a')+PressedKey-97);
+ SDLK_1 : Letter := '1';
+ SDLK_2 : Letter := '2';
+ SDLK_3 : Letter := '3';
+ SDLK_4 : Letter := '4';
+ SDLK_5 : Letter := '5';
+ SDLK_6 : Letter := '6';
+ SDLK_7 : Letter := '7';
+ SDLK_8 : Letter := '8';
+ SDLK_9 : Letter := '9';
+ SDLK_0 : Letter := '0';
+ else exit;
+ end;
+
+ {//Search Letter
+ for I := Interaction + 1 to high(CatSongs.Song) do
+ begin
+ if CatSongs.Song[I].Visible and (Letter = Uppercase(CatSongs.Song[I].Artist)[1]) then
+ break; //Found Song
+ if I = Interaction then //went through complete array but nothing Found
+ break;
+ if I = high(CatSongs.Song) then //At the end of the array->Go to beginning
+ for I2 := low(CatSongs.Song) to Interaction do
+ if CatSongs.Song[I].Visible and (Letter = Uppercase(CatSongs.Song[I].Artist)[1]) then
+ break; //Found Song
+ end; }
+
+ {for I := 0 to High(CatSongs.Song) do begin
+ if (CatSongs.Song[I].Visible) AND (UpperCase(CatSongs.Song[I].Artist[1]) = Letter) then}
+
+ for I := Interaction + 1 to high(CatSongs.Song) + 1 do
+ begin
+ if (I > high(CatSongs.Song)) then
+ begin
+ for I2 := low(CatSongs.Song) to Interaction do
+ begin
+ if CatSongs.Song[I2].Visible and (Letter = lowercase(CatSongs.Song[I2].Artist[1])) then
+ begin
+ Interaction := I2;
+ break; //Found Song
+ end;
+ end;
+ break;
+ end
+ else if CatSongs.Song[I].Visible and (Letter = lowercase(CatSongs.Song[I].Artist[1])) then
+ begin
+ Interaction := I;
+ break; //Found Song
+ end;
+ end;
+
+
+ //Select Song
+ SkipTo(Interaction);
+
+ //Don't do other Functions
+ exit;
+ end;
+
+
+ case PressedKey of
+ SDLK_ESCAPE :
+ 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
+ Music.Stop;
+ Music.PlayBack;
+// FadeTo(@ScreenLevel);
+ FadeTo(@ScreenMain);
+
+// Music.Open(Skin.SkinPath + 'Menu Music 3.mp3');
+// Music.Play;
+ end;
+ end;
+ end;
+ SDLK_RETURN:
+ begin
+ if Length(Songs.Song) > 0 then begin
+// PortWriteB($378, 0);
+ 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:
+ Music.Close;
+ if Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3) then begin
+ Music.MoveTo(Music.Length / 4);
+ Music.Play;
+ end;
+
+ end else begin // clicked on song
+ if (Mode = 0) then //Normal Mode -> Start Song
+ begin
+ StartSong;
+
+ end
+ else if (Mode = 1) then //PartyMode -> Show Menu
+ begin
+ ScreenSongMenu.Visible := True;
+ ScreenSongMenu.MenuShow(SM_Party_Main);
+ end;
+ end;
+ end;
+ end;
+
+ SDLK_M: //Show SongMenu
+ begin
+ if Length(Songs.Song) > 0 then begin
+ if not CatSongs.Song[Interaction].Main then begin // clicked on Song
+ ScreenSongMenu.Visible := True;
+ ScreenSongMenu.MenuShow(SM_Main);
+ end;
+ end;
+ end;
+
+ SDLK_DOWN:
+ begin
+ if (Mode = 0) then
+ begin
+{ if Length(Songs.Song) > 0 then begin
+ Music.PlayChange;
+ InteractNext;
+ Music.Close;
+ if Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3) then Music.Play;
+ SetScroll;
+ end;}
+
+ //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;
+ Music.Close;
+ if Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3) then begin
+ Music.MoveTo(Music.Length / 4);
+ Music.Play;
+ end;
+
+ end;
+
+ //
+ //Cat Change Hack End}
+ end;
+ end;
+ SDLK_UP:
+ begin
+ if (Mode = 0) then
+ begin
+{ if Length(Songs.Song) > 0 then begin
+ Music.PlayChange;
+ InteractPrev;
+ Music.Close;
+ if Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3) then Music.Play;
+ SetScroll;
+ end;}
+ //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;
+ Music.Close;
+ if Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3) then begin
+ Music.MoveTo(Music.Length / 4);
+ Music.Play;
+ 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;
+ Music.Close;
+ if Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3) then begin
+ Music.MoveTo(Music.Length / 4);
+ Music.Play;
+ end;
+ SetScroll4;
+ UpdateLCD;
+ Light.LightOne(1, 200);
+ end;
+ end;
+
+ SDLK_LEFT:
+ begin
+ if (Length(Songs.Song) > 0)AND (Mode = 0) then begin
+ Music.PlayChange;
+ SelectPrev;
+ Music.Close;
+ if Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3) then begin
+ Music.MoveTo(Music.Length / 4);
+ Music.Play;
+ end;
+ 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(2+Random(CatSongs.VisibleSongs-1));
+ end;
+ Music.PlayChange;
+
+ Music.Close;
+ if Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3) then begin
+ Music.MoveTo(Music.Length / 4);
+ Music.Play;
+ end;
+ 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;
+
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+ end;
+ end
+ else // Key Up
+ case PressedKey of
+ SDLK_RETURN :
+ begin
+ end;
+ end;
+end;
+
+constructor TScreenSong.Create;
+var
+ Pet: integer;
+ I: integer;
+begin
+ inherited Create;
+
+// AddStatic(200, 10, 400, 90, Skin.SelectSong);
+// AddStatic(200-10, 140-5, 400+20, 50+10, Skin.Selection, 'JPG', 'Font Gray');
+
+ AddBackground(Theme.Song.Background.Tex);
+
+ for I := 0 to High(Theme.Song.Static) do
+ AddStatic(Theme.Song.Static[I]);
+
+ for I := 0 to High(Theme.Song.Text) do
+ AddText(Theme.Song.Text[I]);
+
+ 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);
+
+ //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);
+
+ // Song List
+// Songs.LoadSongList; // moved to the UltraStar unit
+ CatSongs.Refresh;
+ for Pet := 0 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;
+
+
+// AddButtonText(11, 10, CatSongs.Song[Pet].Title); // new way
+ end;
+// Covers.Save;
+
+ { if Length(CatSongs.Song) > 0 then // setting to first song
+ Interaction := 0
+ else begin // no song detected
+ AddButton(400-200, 140, 400, 50, Skin.Button, 'JPG', 'Transparent Range');
+ AddButtonText(11, 10, 'No songs detected');
+ end;}
+
+ // Randomize Patch
+ Randomize;
+ //Equalizer
+ SetLength(EqualizerBands, Theme.Song.Equalizer.Bands);
+ //ClearArray
+ For I := low(EqualizerBands) to high(EqualizerBands) do
+ EqualizerBands[I] := 3;
+end;
+
+procedure TScreenSong.SetScroll;
+begin
+//Set Positions
+ Case Theme.Song.Cover.Style of
+ 3: SetScroll3;
+ 5: SetScroll5
+ else SetScroll4;
+ end;
+//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 (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;
+
+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 * (B - SongCurrent) / Length(Button);
+// Wsp := 2 * pi * (CatSongs.VisibleIndex(B) - 0) / CatSongs.VisibleSongs;
+ 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 + (300 + 37 * VS {CatSongs.VisibleSongs} {Length(Button)} * sin(Wsp) - 400) * Z2; // 0.5.0 (I): 2 times faster by not calling CatSongs.VisibleSongs
+ Button[B].Z := Z;
+
+ Button[B].H := Theme.Song.Cover.H * Z2;
+ Button[B].W := Button[B].H;
+
+// Button[B].Y := {50 +} 140 + 50 - 50 * Z2;
+ Button[B].Y := Theme.Song.Cover.Y + (Theme.Song.Cover.H - Button[B].H) * 0.65;
+ 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;
+ {function margin (const X, Y, VS: real):real; //Margin of to Buttons
+ begin
+ Result := Frac(x / y) * y;
+ if (X - VS) >= -3 then
+ Result := X - VS - Y
+ else if (X + 3) >= VS then
+ Result := X - VS + Y
+ else
+ Result := X - Y;
+ end; }
+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 Visability
+ if Button[B].Visible then //Only Change Pos for Visible Buttons
+ begin
+ Pos := (CatSongs.VisibleIndex(B) - SongCurrent);
+ if (Pos < -VS) then
+ Pos := Pos + VS
+ else if (Pos > VS) then
+ Pos := Pos - VS;
+
+ if (Abs(Pos) < 3) then {fixed Positions}
+ begin
+ Angle := Pi * (Pos / 5);
+ //Button[B].Visible := False;
+
+ Button[B].H := Theme.Song.Cover.H * cos(Angle);//Power(Z2, 3);
+
+ Button[B].Z := 0.95 - Abs(Pos) * 0.01;
+
+ Button[B].Y := (Theme.Song.Cover.Y + (Theme.Song.Cover.H - Button[B].H) * 0.7);
+
+ Button[B].W := Button[B].H;
+
+ Diff := (Button[B].H - Theme.Song.Cover.H)/2;;
+
+ if (X < 0) then
+ Button[B].X := Theme.Song.Cover.X + Theme.Song.Cover.W * Sin(Angle){ - Theme.Song.Cover.H/2} - Diff
+ else
+ Button[B].X := Theme.Song.Cover.X + Theme.Song.Cover.W * Sin(Angle){ - Theme.Song.Cover.H/2}- Diff;
+
+ Button[B].Visible := True;
+ end
+ else
+ begin {Behind the Front Covers}
+ //Button[B].Visible := False;
+ Pos := Frac(Pos / VS);
+ if Pos < 0 then
+ Pos := Pos + 1;
+
+ Angle := Abs(2 * pi * ((Pos) / VS / 2));
+ //Pos := Power(Pos*2 - 1, 3);
+
+ Button[B].Z := (0.2 + Pos/2) -0.00001; //z < 0.49999 is behind the cover 1 is in front of the covers
+
+ //Pos := abs(Pos) mod 1;
+
+ X := sin(Angle);
+ //Button[B].H := (0.2 + 0.4 * Abs(Pos)) * Theme.Song.Cover.H; //Cover High + Width
+ Button[B].H := 80;
+ Button[B].W := Button[B].H;
+
+ Diff := (Theme.Song.Cover.H - Button[B].H)/2;
+
+ //Button[B].X := Theme.Song.Cover.X + (Theme.Song.Cover.W) * Sin(Angle) - diff
+ //Button[B].X := Theme.Song.Cover.X + Theme.Song.Cover.W * Pos - Diff;
+
+ if (X < 0) then
+ Button[B].X := Theme.Song.Cover.X + Theme.Song.Cover.W * Sin(Angle) - Theme.Song.Cover.H/2 + Diff
+ else
+ Button[B].X := Theme.Song.Cover.X + Theme.Song.Cover.W * Sin(Angle) - Theme.Song.Cover.H/2;
+
+ 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
+
+ {X := sin(Angle);
+
+ Button[B].H := (0.5 + Power(cos(Angle), 1.7))/1.5 * Theme.Song.Cover.H; //Cover High + Width
+ Button[B].W := Button[B].H;
+
+ {if (X < 0) then
+ Diff := Theme.Song.Cover.H - Button[B].H
+ else
+ Diff := 0;
+
+ if (((CatSongs.VisibleIndex(B) - SongCurrent)>= -3) AND ((CatSongs.VisibleIndex(B) - SongCurrent) <= 3)) OR (((CatSongs.VisibleIndex(B) - SongCurrent)>= -3 + VS) AND ((CatSongs.VisibleIndex(B) - SongCurrent) <= 3 + VS)) OR (((CatSongs.VisibleIndex(B) - SongCurrent)>= -3 - VS) AND ((CatSongs.VisibleIndex(B) - SongCurrent) <= 3 - VS)) then
+ Button[B].X := Theme.Song.Cover.X + diff + margin(CatSongs.VisibleIndex(B), SongCurrent, VS)* 30
+ else
+ Button[B].X := Theme.Song.Cover.X + Theme.Song.Cover.W * X + diff;}{
+
+ Diff := (Button[B].H - Theme.Song.Cover.H)/2;
+
+ if X < 0 then
+ Button[B].X := Theme.Song.Cover.X + (Theme.Song.Cover.W) * -Power(-X, 1/2) - diff
+ else
+ Button[B].X := Theme.Song.Cover.X + (Theme.Song.Cover.W) * Power(X, 1/2) - diff;}
+ 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;
+ SelectNext;SelectPrev; //Workaround <- must be fixed sometime
+ FixSelected;
+ //Show Cat in Top Left Mod
+ HideCatTL;
+ end;
+
+
+ if Length(CatSongs.Song) > 0 then begin
+ Music.SetLoop(false);
+ Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3);
+ Music.MoveTo(Music.Length / 4);
+ Music.Play;
+ SetScroll;
+ UpdateLCD;
+ end;
+
+ //Party Mode
+ if (Mode = 1) then
+ begin
+ SelectRandomSong;
+ end;
+
+ SetJoker;
+end;
+
+function TScreenSong.Draw: boolean;
+var
+ dx: real;
+ dt: real;
+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);
+
+
+ // 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;
+ CoverTime := CoverTime + TimeSkip;
+ Button[Interaction].Texture2.Alpha := (CoverTime - 1) * 1.5;
+ if Button[Interaction].Texture2.Alpha > 1 then Button[Interaction].Texture2.Alpha := 1;
+
+ inherited Draw;
+
+ //Draw Equalizer
+ if Theme.Song.Equalizer.Visible then
+ DrawEqualizer;
+
+ //Draw Song Menu
+ if (ScreenSongMenu.Visible) then
+ begin
+ ScreenSongMenu.Draw;
+ end;
+end;
+
+procedure TScreenSong.SelectNext;
+var
+ Skip: integer;
+ I: integer;
+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;
+
+ //0.5.0: unload old full size texture
+ if Button[Interaction].Texture.Name <> Skin.GetTextureFileName('SongCover') then
+ Texture.UnloadTexture(Button[Interaction].Texture.Name, false);
+
+ 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 > CatSongs.VisibleSongs-1 then begin
+ SongTarget := SongTarget - CatSongs.VisibleSongs;
+ SongCurrent := SongCurrent - CatSongs.VisibleSongs;
+ 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;
+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;
+
+ //0.5.0: unload old full size texture
+ if Button[Interaction].Texture.Name <> Skin.GetTextureFileName('SongCover') then
+ Texture.UnloadTexture(Button[Interaction].Texture.Name, false);
+
+ 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;
+
+procedure TScreenSong.UpdateLCD;
+begin
+ LCD.HideCursor;
+ LCD.Clear;
+ LCD.WriteText(1, Text[TextArtist].Text);
+ LCD.WriteText(2, Text[TextTitle].Text);
+end;
+
+procedure TScreenSong.SkipTo(Target: integer); // 0.5.0
+var
+ Skip: integer;
+ I: integer;
+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);
+
+ Interaction := 0;
+ SongTarget := 0;
+
+ for I := 2 to Target 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 := floor(92/Theme.Song.Equalizer.Bands);//How much channels are used for one Band
+ //Change Lengths
+ for I := 0 to 92 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 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
+ 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);
+
+ Music.Close;
+ if Music.Open(CatSongs.Song[Interaction].Path + CatSongs.Song[Interaction].Mp3) then begin
+ Music.MoveTo(Music.Length / 4);
+ Music.Play;
+ end;
+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;
+
+//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.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;
+
+procedure TScreenSong.Refresh;
+begin {
+CatSongs.Refresh;
+CatSongs.ShowCategoryList;
+Interaction := 0;
+SelectNext;
+FixSelected; }
+
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenSongMenu.dcu b/Game/Code/Screens/UScreenSongMenu.dcu
new file mode 100644
index 00000000..634a217a
--- /dev/null
+++ b/Game/Code/Screens/UScreenSongMenu.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenSongMenu.pas b/Game/Code/Screens/UScreenSongMenu.pas
new file mode 100644
index 00000000..2a03a7c2
--- /dev/null
+++ b/Game/Code/Screens/UScreenSongMenu.pas
@@ -0,0 +1,355 @@
+unit UScreenSongMenu;
+
+interface
+
+uses
+ UMenu, SDL, UDisplay, UMusic, UPliki, 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_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;
+
+function TScreenSongMenu.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+ function IsVisible: Boolean;
+ begin
+ Result := True;
+ if (Interactions[Interaction].Typ = 0) then
+ begin
+ Result := Button[Interactions[Interaction].Num].Visible;
+ end
+ else if (Interactions[Interaction].Typ = 1) then
+ begin
+ //Result := Selects[Interactions[Interaction].Num].Visible;
+ end
+ else if (Interactions[Interaction].Typ = 3) then
+ begin
+ Result := SelectsS[Interactions[Interaction].Num].Visible;
+ end;
+ end;
+
+ Procedure SelectNext;
+ begin
+ repeat
+ InteractNext;
+ until IsVisible;
+ end;
+
+ Procedure SelectPrev;
+ begin
+ repeat
+ InteractPrev;
+ until IsVisible;
+ end;
+begin
+ Result := true;
+ If (PressedDown) Then
+ begin // Key Down
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+
+ SDLK_ESCAPE :
+ begin
+ Music.PlayBack;
+ Visible := False;
+ end;
+
+ SDLK_RETURN:
+ begin
+ HandleReturn;
+ 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: SelectNext;
+ SDLK_UP: SelectPrev;
+
+ SDLK_RIGHT:
+ begin
+ if (Interaction=3) then
+ InteractInc;
+ end;
+ SDLK_LEFT:
+ begin
+ if (Interaction=3) then
+ InteractDec;
+ end;
+ end;
+ end
+ else // Key Up
+ case PressedKey of
+ SDLK_RETURN :
+ begin
+ end;
+ end;
+end;
+
+constructor TScreenSongMenu.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+ SetLength(ISelections, 1);
+ ISelections[0] := 'Dummy';
+
+ AddBackground(Theme.SongMenu.Background.Tex);
+
+ 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');
+
+ AddText(Theme.SongMenu.TextMenu);
+
+ for I := 0 to High(Theme.SongMenu.Static) do
+ AddStatic(Theme.SongMenu.Static[I]);
+
+ for I := 0 to High(Theme.SongMenu.Text) do
+ AddText(Theme.SongMenu.Text[I]);
+
+ 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
+ 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_EDIT');
+ Button[2].Text[0].Text := Language.Translate('SONG_MENU_PLAYMODI');
+ Button[3].Text[0].Text := Language.Translate('SONG_MENU_CANCEL');
+ end;
+
+ SM_PlayList:
+ begin
+ CurMenu := sMenu;
+ Text[0].Text := Language.Translate('SONG_MENU_NAME_PLAYLIST');
+
+ 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_PLAYLIST_ADD');
+ Button[1].Text[0].Text := '';
+ Button[2].Text[0].Text := '';
+ 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');
+ end;
+ end;
+end;
+
+procedure TScreenSongMenu.HandleReturn;
+begin
+ Case CurMenu of
+ SM_Main:
+ begin
+ Visible := False;
+ Case Interaction of
+ 0: //Button 1
+ begin
+ ScreenSong.StartSong;
+ end;
+
+ 1: //Button 2
+ begin
+ ScreenSong.OpenEditor;
+ end;
+
+ 2: //Button 3
+ begin
+ //Todo: Add SingleRound Modi Support
+ end;
+
+ 3: //SelectSlide 3
+ begin
+ //Dummy
+ end;
+
+ 4: //Button 4
+ begin
+ //Cancel... (Do Nothing)
+ end;
+ end;
+ end;
+
+ SM_PlayList:
+ begin
+ Visible := False;
+ Case Interaction of
+ 0: //Button 1
+ begin
+ //
+ end;
+
+ 1: //Button 2
+ begin
+ //
+ end;
+
+ 2: //Button 3
+ begin
+ //Todo
+ end;
+
+ 3: //SelectSlide 3
+ begin
+ //Dummy
+ end;
+
+ 4: //Button 4
+ begin
+ //
+ 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.
+ \ No newline at end of file
diff --git a/Game/Code/Screens/UScreenTop5.dcu b/Game/Code/Screens/UScreenTop5.dcu
new file mode 100644
index 00000000..c6db07d0
--- /dev/null
+++ b/Game/Code/Screens/UScreenTop5.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenTop5.pas b/Game/Code/Screens/UScreenTop5.pas
new file mode 100644
index 00000000..41f96281
--- /dev/null
+++ b/Game/Code/Screens/UScreenTop5.pas
@@ -0,0 +1,166 @@
+unit UScreenTop5;
+
+interface
+
+uses
+ UMenu, SDL, SysUtils, UDisplay, UMusic, USongs, UThemes, ULCD;
+
+type
+ TScreenTop5 = class(TMenu)
+ public
+ TextLevel: integer;
+ TextArtistTitle: integer;
+
+ StaticNumber: array[1..5] of integer;
+ TextNumber: array[1..5] of integer;
+ TextName: array[1..5] of integer;
+ TextScore: array[1..5] of integer;
+
+ Fadeout: boolean;
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ procedure onShow; override;
+ function Draw: boolean; override;
+ end;
+
+implementation
+
+uses UGraphic, UScores, UMain, UIni;
+
+function TScreenTop5.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then begin
+ case PressedKey of
+ SDLK_Q:
+ begin
+ Result := false;
+ end;
+
+ SDLK_ESCAPE, SDLK_RETURN:
+ begin
+ if (not Fadeout) then begin
+ FadeTo(@ScreenSong);
+ Fadeout := true;
+ end;
+ end;
+ SDLK_SYSREQ:
+ begin
+ Display.PrintScreen;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenTop5.Create;
+var
+ I: integer;
+begin
+ inherited Create;
+
+ AddBackground(Theme.Top5.Background.Tex);
+
+ for I := 0 to High(Theme.Top5.Static) do
+ AddStatic(Theme.Top5.Static[I]);
+
+ for I := 0 to High(Theme.Top5.Text) do
+ AddText(Theme.Top5.Text[I]);
+
+
+ TextLevel := AddText(Theme.Top5.TextLevel);
+ TextArtistTitle := AddText(Theme.Top5.TextArtistTitle);
+
+ for I := 0 to 4 do
+ StaticNumber[I+1] := AddStatic(Theme.Top5.StaticNumber[I]);
+
+ for I := 0 to 4 do
+ TextNumber[I+1] := AddText(Theme.Top5.TextNumber[I]);
+ for I := 0 to 4 do
+ TextName[I+1] := AddText(Theme.Top5.TextName[I]);
+ for I := 0 to 4 do
+ TextScore[I+1] := AddText(Theme.Top5.TextScore[I]);
+
+end;
+
+procedure TScreenTop5.onShow;
+var
+ I: integer;
+ PMax: integer;
+begin
+ Fadeout := false;
+
+ //ReadScore(AktSong);
+
+ PMax := Ini.Players;
+ if Ini.Players = 4 then Ini.Players := 5;
+ for I := 0 to PMax do
+ AddScore(AktSong, Ini.Difficulty, Ini.Name[I], Round(Player[I].ScoreTotalI));
+
+ //WriteScore(AktSong);
+ ReadScore(AktSong);
+
+ Text[TextArtistTitle].Text := AktSong.Artist + ' - ' + AktSong.Title;
+
+ for I := 1 to Length(AktSong.Score[Ini.Difficulty]) do begin
+ Static[StaticNumber[I]].Visible := true;
+ Text[TextNumber[I]].Visible := true;
+ Text[TextName[I]].Visible := true;
+ Text[TextScore[I]].Visible := true;
+
+ Text[TextName[I]].Text := AktSong.Score[Ini.Difficulty, I-1].Name;
+ Text[TextScore[I]].Text := IntToStr(AktSong.Score[Ini.Difficulty, I-1].Score);
+ end;
+
+ for I := Length(AktSong.Score[Ini.Difficulty])+1 to 5 do begin
+ Static[StaticNumber[I]].Visible := false;
+ Text[TextNumber[I]].Visible := false;
+ Text[TextName[I]].Visible := false;
+ Text[TextScore[I]].Visible := false;
+ end;
+
+ Text[TextLevel].Text := IDifficulty[Ini.Difficulty];
+end;
+
+function TScreenTop5.Draw: boolean;
+//var
+{ Min: real;
+ Max: real;
+ Wsp: real;
+ Wsp2: real;
+ Pet: integer;}
+
+{ Item: integer;
+ P: integer;
+ C: integer;}
+begin
+ // Singstar - let it be...... with 6 statics
+{ if PlayersPlay = 6 then begin
+ for Item := 4 to 6 do begin
+ if ScreenAct = 1 then P := Item-4;
+ if ScreenAct = 2 then P := Item-1;
+
+ FillPlayer(Item, P);
+
+{ if ScreenAct = 1 then begin
+ LoadColor(
+ Static[StaticBoxLightest[Item]].Texture.ColR,
+ Static[StaticBoxLightest[Item]].Texture.ColG,
+ Static[StaticBoxLightest[Item]].Texture.ColB,
+ 'P1Dark');
+ end;
+
+ if ScreenAct = 2 then begin
+ LoadColor(
+ Static[StaticBoxLightest[Item]].Texture.ColR,
+ Static[StaticBoxLightest[Item]].Texture.ColG,
+ Static[StaticBoxLightest[Item]].Texture.ColB,
+ 'P4Dark');
+ end;}
+
+{ end;
+ end;}
+
+ inherited Draw;
+end;
+
+end.
diff --git a/Game/Code/Screens/UScreenWelcome.dcu b/Game/Code/Screens/UScreenWelcome.dcu
new file mode 100644
index 00000000..196b04be
--- /dev/null
+++ b/Game/Code/Screens/UScreenWelcome.dcu
Binary files differ
diff --git a/Game/Code/Screens/UScreenWelcome.pas b/Game/Code/Screens/UScreenWelcome.pas
new file mode 100644
index 00000000..de3b50f4
--- /dev/null
+++ b/Game/Code/Screens/UScreenWelcome.pas
@@ -0,0 +1,117 @@
+unit UScreenWelcome;
+
+interface
+
+uses
+ UMenu, SDL, SysUtils, UThemes;
+
+type
+ TScreenWelcome = class(TMenu)
+ public
+ Animation: real;
+ Fadeout: boolean;
+ constructor Create; override;
+ function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
+ function Draw: boolean; override;
+ procedure onShow; override;
+ end;
+
+implementation
+
+uses UGraphic, UTime;
+
+function TScreenWelcome.ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean;
+begin
+ Result := true;
+ If (PressedDown) Then begin
+ case PressedKey of
+ SDLK_ESCAPE :
+ begin
+ Result := False;
+ end;
+ SDLK_RETURN:
+ begin
+ FadeTo(@ScreenMain);
+ Fadeout := true;
+ end;
+ end;
+ end;
+end;
+
+constructor TScreenWelcome.Create;
+begin
+ inherited Create;
+{ AddStatic(-10, -10, 0, 0, 1, 1, 1, Skin.Star, 'BMP', 'Transparent');
+ AddStatic(-500, 440, 200, 5, 0, 0, 0, Skin.Line, 'JPG', 'Font Black');
+ AddStatic(-500, 472, 200, 5, 0, 0, 0, Skin.Line, 'JPG', 'Font Black');
+ AddStatic(-500, 504, 200, 5, 0, 0, 0, Skin.Line, 'JPG', 'Font Black');
+ AddStatic(-500, 536, 200, 5, 0, 0, 0, Skin.Line, 'JPG', 'Font Black');
+ AddStatic(-500, 568, 200, 5, 0, 0, 0, Skin.Line, 'JPG', 'Font Black');
+ Animation := 0;
+ Fadeout := false;}
+end;
+
+procedure TScreenWelcome.onShow;
+begin
+ CountSkipTimeSet;
+end;
+
+function TScreenWelcome.Draw: boolean;
+var
+ Min: real;
+ Max: real;
+ Wsp: real;
+ Pet: integer;
+begin
+ // star animation
+ Animation := Animation + TimeSkip*1000;
+
+ // draw nothing
+ Min := 0; Max := 1000;
+ if (Animation >= Min) and (Animation < Max) then begin
+ end;
+
+ // popup
+ Min := 1000; Max := 1120;
+ if (Animation >= Min) and (Animation < Max) then begin
+ Wsp := (Animation - Min) / (Max - Min);
+ Static[0].Texture.X := 600;
+ Static[0].Texture.Y := 600 - Wsp * 230;
+ Static[0].Texture.W := 200;
+ Static[0].Texture.H := Wsp * 230;
+ end;
+
+ // bounce
+ Min := 1120; Max := 1200;
+ if (Animation >= Min) and (Animation < Max) then begin
+ Wsp := (Animation - Min) / (Max - Min);
+ Static[0].Texture.Y := 370 + Wsp * 50;
+ Static[0].Texture.H := 230 - Wsp * 50;
+ end;
+
+ // run
+ Min := 1500; Max := 3500;
+ if (Animation >= Min) and (Animation < Max) then begin
+ Wsp := (Animation - Min) / (Max - Min);
+
+ Static[0].Texture.X := 600 - Wsp * 1400;
+ Static[0].Texture.H := 180;
+
+
+ for Pet := 1 to 5 do begin
+ Static[Pet].Texture.X := 770 - Wsp * 1400;
+ Static[Pet].Texture.W := 150 + Wsp * 200;
+ Static[Pet].Texture.Alpha := Wsp * 0.5;
+ end;
+ end;
+
+ Min := 3500;
+ if (Animation >= Min) and (not Fadeout) then begin
+ FadeTo(@ScreenMain);
+ Fadeout := true;
+ end;
+
+ inherited Draw;
+end;
+
+end.
diff --git a/Game/Code/UltraStar.RES b/Game/Code/UltraStar.RES
new file mode 100644
index 00000000..fcaa4576
--- /dev/null
+++ b/Game/Code/UltraStar.RES
Binary files differ
diff --git a/Game/Code/UltraStar.bdsproj b/Game/Code/UltraStar.bdsproj
new file mode 100644
index 00000000..e11acf91
--- /dev/null
+++ b/Game/Code/UltraStar.bdsproj
@@ -0,0 +1,168 @@
+ïŧŋ<?xml version="1.0" encoding="utf-8"?>
+<BorlandProject>
+ <PersonalityInfo>
+ <Option>
+ <Option Name="Personality">Delphi.Personality</Option>
+ <Option Name="ProjectType">VCLApplication</Option>
+ <Option Name="Version">1.0</Option>
+ <Option Name="GUID">{7B1672C4-0C19-46AC-846F-BFB7F7A093D8}</Option>
+ </Option>
+ </PersonalityInfo>
+ <Delphi.Personality>
+ <Source>
+ <Source Name="MainSource">UltraStar.dpr</Source>
+ </Source>
+ <FileVersion>
+ <FileVersion Name="Version">7.0</FileVersion>
+ </FileVersion>
+ <Compiler>
+ <Compiler Name="A">8</Compiler>
+ <Compiler Name="B">0</Compiler>
+ <Compiler Name="C">1</Compiler>
+ <Compiler Name="D">1</Compiler>
+ <Compiler Name="E">0</Compiler>
+ <Compiler Name="F">0</Compiler>
+ <Compiler Name="G">1</Compiler>
+ <Compiler Name="H">1</Compiler>
+ <Compiler Name="I">1</Compiler>
+ <Compiler Name="J">0</Compiler>
+ <Compiler Name="K">0</Compiler>
+ <Compiler Name="L">1</Compiler>
+ <Compiler Name="M">0</Compiler>
+ <Compiler Name="N">1</Compiler>
+ <Compiler Name="O">1</Compiler>
+ <Compiler Name="P">1</Compiler>
+ <Compiler Name="Q">0</Compiler>
+ <Compiler Name="R">0</Compiler>
+ <Compiler Name="S">0</Compiler>
+ <Compiler Name="T">0</Compiler>
+ <Compiler Name="U">0</Compiler>
+ <Compiler Name="V">1</Compiler>
+ <Compiler Name="W">0</Compiler>
+ <Compiler Name="X">1</Compiler>
+ <Compiler Name="Y">1</Compiler>
+ <Compiler Name="Z">1</Compiler>
+ <Compiler Name="ShowHints">True</Compiler>
+ <Compiler Name="ShowWarnings">False</Compiler>
+ <Compiler Name="UnitAliases">WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;</Compiler>
+ <Compiler Name="NamespacePrefix"></Compiler>
+ <Compiler Name="GenerateDocumentation">False</Compiler>
+ <Compiler Name="DefaultNamespace"></Compiler>
+ <Compiler Name="SymbolDeprecated">True</Compiler>
+ <Compiler Name="SymbolLibrary">True</Compiler>
+ <Compiler Name="SymbolPlatform">True</Compiler>
+ <Compiler Name="SymbolExperimental">True</Compiler>
+ <Compiler Name="UnitLibrary">True</Compiler>
+ <Compiler Name="UnitPlatform">True</Compiler>
+ <Compiler Name="UnitDeprecated">True</Compiler>
+ <Compiler Name="UnitExperimental">True</Compiler>
+ <Compiler Name="HResultCompat">True</Compiler>
+ <Compiler Name="HidingMember">True</Compiler>
+ <Compiler Name="HiddenVirtual">True</Compiler>
+ <Compiler Name="Garbage">True</Compiler>
+ <Compiler Name="BoundsError">True</Compiler>
+ <Compiler Name="ZeroNilCompat">True</Compiler>
+ <Compiler Name="StringConstTruncated">True</Compiler>
+ <Compiler Name="ForLoopVarVarPar">True</Compiler>
+ <Compiler Name="TypedConstVarPar">True</Compiler>
+ <Compiler Name="AsgToTypedConst">True</Compiler>
+ <Compiler Name="CaseLabelRange">True</Compiler>
+ <Compiler Name="ForVariable">True</Compiler>
+ <Compiler Name="ConstructingAbstract">True</Compiler>
+ <Compiler Name="ComparisonFalse">True</Compiler>
+ <Compiler Name="ComparisonTrue">True</Compiler>
+ <Compiler Name="ComparingSignedUnsigned">True</Compiler>
+ <Compiler Name="CombiningSignedUnsigned">True</Compiler>
+ <Compiler Name="UnsupportedConstruct">True</Compiler>
+ <Compiler Name="FileOpen">True</Compiler>
+ <Compiler Name="FileOpenUnitSrc">True</Compiler>
+ <Compiler Name="BadGlobalSymbol">True</Compiler>
+ <Compiler Name="DuplicateConstructorDestructor">True</Compiler>
+ <Compiler Name="InvalidDirective">True</Compiler>
+ <Compiler Name="PackageNoLink">True</Compiler>
+ <Compiler Name="PackageThreadVar">True</Compiler>
+ <Compiler Name="ImplicitImport">True</Compiler>
+ <Compiler Name="HPPEMITIgnored">True</Compiler>
+ <Compiler Name="NoRetVal">True</Compiler>
+ <Compiler Name="UseBeforeDef">True</Compiler>
+ <Compiler Name="ForLoopVarUndef">True</Compiler>
+ <Compiler Name="UnitNameMismatch">True</Compiler>
+ <Compiler Name="NoCFGFileFound">True</Compiler>
+ <Compiler Name="MessageDirective">True</Compiler>
+ <Compiler Name="ImplicitVariants">True</Compiler>
+ <Compiler Name="UnicodeToLocale">True</Compiler>
+ <Compiler Name="LocaleToUnicode">True</Compiler>
+ <Compiler Name="ImagebaseMultiple">True</Compiler>
+ <Compiler Name="SuspiciousTypecast">True</Compiler>
+ <Compiler Name="PrivatePropAccessor">True</Compiler>
+ <Compiler Name="UnsafeType">True</Compiler>
+ <Compiler Name="UnsafeCode">True</Compiler>
+ <Compiler Name="UnsafeCast">True</Compiler>
+ <Compiler Name="OptionTruncated">True</Compiler>
+ <Compiler Name="WideCharReduced">True</Compiler>
+ <Compiler Name="DuplicatesIgnored">True</Compiler>
+ </Compiler>
+ <Linker>
+ <Linker Name="MapFile">0</Linker>
+ <Linker Name="OutputObjs">0</Linker>
+ <Linker Name="ConsoleApp">1</Linker>
+ <Linker Name="DebugInfo">False</Linker>
+ <Linker Name="RemoteSymbols">False</Linker>
+ <Linker Name="GenerateDRC">False</Linker>
+ <Linker Name="MinStackSize">16384</Linker>
+ <Linker Name="MaxStackSize">1048576</Linker>
+ <Linker Name="ImageBase">4194304</Linker>
+ <Linker Name="ExeDescription"></Linker>
+ </Linker>
+ <Directories>
+ <Directories Name="OutputDir">E:\Projekte\Ultrastar</Directories>
+ <Directories Name="UnitOutputDir"></Directories>
+ <Directories Name="PackageDLLOutputDir"></Directories>
+ <Directories Name="PackageDCPOutputDir"></Directories>
+ <Directories Name="SearchPath">E:\Projekte\Ultrastar\Includes;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\smpeg\Pas;E:\Projekte\Ultrastar\Includes\midi</Directories>
+ <Directories Name="Packages">vcl;rtl;vclx;VclSmp;vclshlctrls;DelphiX_for6</Directories>
+ <Directories Name="Conditionals">TRANSLATE</Directories>
+ <Directories Name="DebugSourceDirs"></Directories>
+ <Directories Name="UsePackages">False</Directories>
+ </Directories>
+ <Parameters>
+ <Parameters Name="RunParams">-benchmark</Parameters>
+ <Parameters Name="HostApplication"></Parameters>
+ <Parameters Name="Launcher"></Parameters>
+ <Parameters Name="UseLauncher">False</Parameters>
+ <Parameters Name="DebugCWD"></Parameters>
+ <Parameters Name="RemoteHost"></Parameters>
+ <Parameters Name="RemotePath"></Parameters>
+ <Parameters Name="RemoteLauncher"></Parameters>
+ <Parameters Name="RemoteCWD"></Parameters>
+ <Parameters Name="RemoteDebug">False</Parameters>
+ </Parameters>
+ <VersionInfo>
+ <VersionInfo Name="IncludeVerInfo">False</VersionInfo>
+ <VersionInfo Name="AutoIncBuild">False</VersionInfo>
+ <VersionInfo Name="MajorVer">1</VersionInfo>
+ <VersionInfo Name="MinorVer">0</VersionInfo>
+ <VersionInfo Name="Release">0</VersionInfo>
+ <VersionInfo Name="Build">0</VersionInfo>
+ <VersionInfo Name="Debug">False</VersionInfo>
+ <VersionInfo Name="PreRelease">False</VersionInfo>
+ <VersionInfo Name="Special">False</VersionInfo>
+ <VersionInfo Name="Private">False</VersionInfo>
+ <VersionInfo Name="DLL">False</VersionInfo>
+ <VersionInfo Name="Locale">1045</VersionInfo>
+ <VersionInfo Name="CodePage">1250</VersionInfo>
+ </VersionInfo>
+ <VersionInfoKeys>
+ <VersionInfoKeys Name="CompanyName"></VersionInfoKeys>
+ <VersionInfoKeys Name="FileDescription"></VersionInfoKeys>
+ <VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
+ <VersionInfoKeys Name="InternalName"></VersionInfoKeys>
+ <VersionInfoKeys Name="LegalCopyright"></VersionInfoKeys>
+ <VersionInfoKeys Name="LegalTrademarks"></VersionInfoKeys>
+ <VersionInfoKeys Name="OriginalFilename"></VersionInfoKeys>
+ <VersionInfoKeys Name="ProductName"></VersionInfoKeys>
+ <VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
+ <VersionInfoKeys Name="Comments"></VersionInfoKeys>
+ </VersionInfoKeys>
+ </Delphi.Personality>
+</BorlandProject>
diff --git a/Game/Code/UltraStar.bdsproj.local b/Game/Code/UltraStar.bdsproj.local
new file mode 100644
index 00000000..d576f039
--- /dev/null
+++ b/Game/Code/UltraStar.bdsproj.local
@@ -0,0 +1,2 @@
+ïŧŋ<?xml version="1.0" encoding="utf-8"?>
+<BorlandProject/>
diff --git a/Game/Code/UltraStar.cfg b/Game/Code/UltraStar.cfg
new file mode 100644
index 00000000..5ade3beb
--- /dev/null
+++ b/Game/Code/UltraStar.cfg
@@ -0,0 +1,41 @@
+-$A8
+-$B-
+-$C+
+-$D+
+-$E-
+-$F-
+-$G+
+-$H+
+-$I+
+-$J-
+-$K-
+-$L+
+-$M-
+-$N+
+-$O+
+-$P+
+-$Q-
+-$R-
+-$S-
+-$T-
+-$U-
+-$V+
+-$W-
+-$X+
+-$YD
+-$Z1
+-cg
+-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
+-H+
+-W-
+-M
+-$M16384,1048576
+-K$00400000
+-E"E:\Projekte\Ultrastar\Bin"
+-LE"e:\programme\borland\delphi7\Projects\Bpl"
+-LN"e:\programme\borland\delphi7\Projects\Bpl"
+-U"E:\Projekte\Ultrastar\Includes\DelphiX\Source;E:\Projekte\Ultrastar\Includes;E:\Projekte\Ultrastar\Includes\midi;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Sound\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Net\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Mixer\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Image\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_ttf\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDLSpriteEngine\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SFont\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\smpeg\Pas;E:\Projekte\Ultrastar\Includes\Zlportio;E:\Projekte\Ultrastar\Includes\SQLite"
+-O"E:\Projekte\Ultrastar\Includes\DelphiX\Source;E:\Projekte\Ultrastar\Includes;E:\Projekte\Ultrastar\Includes\midi;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Sound\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Net\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Mixer\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Image\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_ttf\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDLSpriteEngine\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SFont\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\smpeg\Pas;E:\Projekte\Ultrastar\Includes\Zlportio;E:\Projekte\Ultrastar\Includes\SQLite"
+-I"E:\Projekte\Ultrastar\Includes\DelphiX\Source;E:\Projekte\Ultrastar\Includes;E:\Projekte\Ultrastar\Includes\midi;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Sound\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Net\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Mixer\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Image\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_ttf\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDLSpriteEngine\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SFont\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\smpeg\Pas;E:\Projekte\Ultrastar\Includes\Zlportio;E:\Projekte\Ultrastar\Includes\SQLite"
+-R"E:\Projekte\Ultrastar\Includes\DelphiX\Source;E:\Projekte\Ultrastar\Includes;E:\Projekte\Ultrastar\Includes\midi;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Sound\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Net\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Mixer\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Image\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_ttf\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDLSpriteEngine\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SFont\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\smpeg\Pas;E:\Projekte\Ultrastar\Includes\Zlportio;E:\Projekte\Ultrastar\Includes\SQLite"
+-DTRANSLATE
diff --git a/Game/Code/UltraStar.dof b/Game/Code/UltraStar.dof
new file mode 100644
index 00000000..174b4358
--- /dev/null
+++ b/Game/Code/UltraStar.dof
@@ -0,0 +1,148 @@
+[FileVersion]
+Version=7.0
+[Compiler]
+A=8
+B=0
+C=1
+D=1
+E=0
+F=0
+G=1
+H=1
+I=1
+J=0
+K=0
+L=1
+M=0
+N=1
+O=1
+P=1
+Q=0
+R=0
+S=0
+T=0
+U=0
+V=1
+W=0
+X=1
+Y=1
+Z=1
+ShowHints=1
+ShowWarnings=0
+UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
+NamespacePrefix=
+SymbolDeprecated=1
+SymbolLibrary=1
+SymbolPlatform=1
+UnitLibrary=1
+UnitPlatform=1
+UnitDeprecated=1
+HResultCompat=1
+HidingMember=1
+HiddenVirtual=1
+Garbage=1
+BoundsError=1
+ZeroNilCompat=1
+StringConstTruncated=1
+ForLoopVarVarPar=1
+TypedConstVarPar=1
+AsgToTypedConst=1
+CaseLabelRange=1
+ForVariable=1
+ConstructingAbstract=1
+ComparisonFalse=1
+ComparisonTrue=1
+ComparingSignedUnsigned=1
+CombiningSignedUnsigned=1
+UnsupportedConstruct=1
+FileOpen=1
+FileOpenUnitSrc=1
+BadGlobalSymbol=1
+DuplicateConstructorDestructor=1
+InvalidDirective=1
+PackageNoLink=1
+PackageThreadVar=1
+ImplicitImport=1
+HPPEMITIgnored=1
+NoRetVal=1
+UseBeforeDef=1
+ForLoopVarUndef=1
+UnitNameMismatch=1
+NoCFGFileFound=1
+MessageDirective=1
+ImplicitVariants=1
+UnicodeToLocale=1
+LocaleToUnicode=1
+ImagebaseMultiple=1
+SuspiciousTypecast=1
+PrivatePropAccessor=1
+UnsafeType=1
+UnsafeCode=1
+UnsafeCast=1
+[Linker]
+MapFile=0
+OutputObjs=0
+ConsoleApp=1
+DebugInfo=0
+RemoteSymbols=0
+MinStackSize=16384
+MaxStackSize=1048576
+ImageBase=4194304
+ExeDescription=Karaoke Software with rating
+[Directories]
+OutputDir=E:\Projekte\Ultrastar\Bin
+UnitOutputDir=
+PackageDLLOutputDir=
+PackageDCPOutputDir=
+SearchPath=E:\Projekte\Ultrastar\Includes\DelphiX\Source;E:\Projekte\Ultrastar\Includes;E:\Projekte\Ultrastar\Includes\midi;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Sound\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Net\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Mixer\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Image\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_ttf\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDLSpriteEngine\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SFont\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\smpeg\Pas;E:\Projekte\Ultrastar\Includes\Zlportio;E:\Projekte\Ultrastar\Includes\SQLite
+Packages=vcl;rtl;vclx;VclSmp;vclshlctrls;DelphiX_for6
+Conditionals=TRANSLATE
+DebugSourceDirs=
+UsePackages=0
+[Parameters]
+RunParams=-benchmark
+HostApplication=
+Launcher=
+UseLauncher=0
+DebugCWD=
+[Version Info]
+IncludeVerInfo=0
+AutoIncBuild=0
+MajorVer=1
+MinorVer=0
+Release=0
+Build=0
+Debug=0
+PreRelease=0
+Special=0
+Private=0
+DLL=0
+Locale=1045
+CodePage=1250
+[Version Info Keys]
+CompanyName=
+FileDescription=
+FileVersion=1.0.0.0
+InternalName=
+LegalCopyright=
+LegalTrademarks=
+OriginalFilename=
+ProductName=
+ProductVersion=1.0.0.0
+Comments=
+[HistoryLists\hlConditionals]
+Count=2
+Item0=TRANSLATE
+Item1=OGL
+[HistoryLists\hlUnitAliases]
+Count=1
+Item0=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE;
+[HistoryLists\hlSearchPath]
+Count=2
+Item0=E:\Projekte\Ultrastar\Includes\DelphiX\Source;E:\Projekte\Ultrastar\Includes;E:\Projekte\Ultrastar\Includes\midi;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Sound\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Net\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Mixer\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Image\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_ttf\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDLSpriteEngine\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SFont\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\smpeg\Pas;E:\Projekte\Ultrastar\Includes\Zlportio;E:\Projekte\Ultrastar\Includes\SQLite
+Item1=E:\Projekte\Ultrastar\Includes\DelphiX\Source;E:\Projekte\Ultrastar\Includes;E:\Projekte\Ultrastar\Includes\midi;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Sound\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Net\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Mixer\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_Image\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDL_ttf\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SDLSpriteEngine\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\SFont\Pas;E:\Projekte\Ultrastar\Includes\JEDI-SDL\smpeg\Pas
+[HistoryLists\hlOutputDirectorry]
+Count=3
+Item0=E:\Projekte\Ultrastar\Bin
+Item1=E:\Projekte\Ultrastar
+Item2=C:\UltraStar\Bin
diff --git a/Game/Code/UltraStar.dpr b/Game/Code/UltraStar.dpr
new file mode 100644
index 00000000..5c598eda
--- /dev/null
+++ b/Game/Code/UltraStar.dpr
@@ -0,0 +1,286 @@
+ program UltraStar;
+
+{$DEFINE TRANSLATE}
+//DEFINE THEMESAVE}
+
+{$R 'UltraStar.res' 'UltraStar.rc'}
+
+uses
+ {//Earlyer in Code Dir.. Now in SearchDir
+ DDKint in '..\ZLPortIO\ddkint.pas',
+ ZLPortIO in '..\ZLPortIO\zlportio.pas',
+ SQLiteTable3 in '..\SQLite\SQLiteTable3.pas',
+ SQLite3 in '..\SQLite\SQLite3.pas',}
+ Windows,
+ SDL,
+ SysUtils,
+
+ //Menu Objects
+ UDisplay in 'Menu\UDisplay.pas',
+ UMenu in 'Menu\UMenu.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',
+
+ //Classes
+ UGraphic in 'Classes\UGraphic.pas',
+ UTexture in 'Classes\UTexture.pas',
+ UMusic in 'Classes\UMusic.pas',
+ UPliki in 'Classes\UPliki.pas',
+ UMain in 'Classes\UMain.pas',
+ UDraw in 'Classes\UDraw.pas',
+ URecord in 'Classes\URecord.pas',
+ UTime in 'Classes\UTime.pas',
+ TextGL in 'Classes\TextGL.pas',
+ USongs in 'Classes\USongs.pas',
+ UIni in 'Classes\UIni.pas',
+ USmpeg in 'SMpeg\USmpeg.pas',
+ ULyrics in 'Classes\ULyrics.pas',
+ USkins in 'Classes\USkins.pas',
+ UThemes in 'Classes\UThemes.pas',
+ ULog in 'Classes\ULog.pas',
+ UJoystick in 'Classes\UJoystick.pas',
+ ULCD in 'Classes\ULCD.pas',
+ ULight in 'Classes\ULight.pas',
+ UScores in 'Classes\UScores.pas',
+ ULanguage in 'Classes\ULanguage.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',
+
+ //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',
+ 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',
+ //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',
+
+ //Modi SDK
+ ModiSDK in '..\..\Modis\SDK\ModiSDK.pas';
+
+const
+ Version = 'UltraStar Deluxe V 0.90 Beta';
+
+var
+ WndTitle: string;
+ hWnd: THandle;
+ I: Integer;
+
+begin
+ WndTitle := Version;
+
+ //Start more than One Time Prevention
+ hWnd:= FindWindow(nil, PChar(WndTitle));
+ //Programm already started
+ if (hWnd <> 0) then
+ begin
+ I := Messagebox(0, PChar('Another Instance of Ultrastar is already running. Contėnue ?'), PChar(WndTitle), MB_ICONWARNING or MB_YESNO);
+ if (I = IDYes) then
+ begin
+ I := 1;
+ repeat
+ Inc(I);
+ hWnd := FindWindow(nil, PChar(WndTitle + ' Instance ' + InttoStr(I)));
+ until (hWnd = 0);
+
+ WndTitle := WndTitle + ' Instance ' + InttoStr(I);
+ end
+ else
+ Exit;
+ end;
+
+
+
+ USTime := TTime.Create;
+
+ // Log + Benchmark
+ Log := TLog.Create;
+ Log.Title := WndTitle;
+ Log.BenchmarkStart(0);
+// Log.LogError(IntToStr(DayOfTheYear(Date)));
+
+ // Language
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Initialize Paths', 'Initialization'); InitializePaths;
+ Log.LogStatus('Load Language', 'Initialization'); Language := TLanguage.Create;
+ //Add Const Values:
+ Language.AddConst('US_VERSION', Version);
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Language', 1);
+
+ // SDL
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Initialize SDL', 'Initialization');
+ SDL_Init(SDL_INIT_VIDEO or SDL_INIT_AUDIO);
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Initializing SDL', 1);
+
+ // Skin
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Loading Skin List', 'Initialization'); Skin := TSkin.Create;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Skin List', 1);
+
+ //Log.LogBenchmark(inttostr(Skin.), 1);
+
+ // Sound Card List
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Loading Soundcard list', 'Initialization');
+ Recording := TRecord.Create;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Soundcard list', 1);
+
+ // Ini + Paths
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Load Ini', 'Initialization'); Ini := TIni.Create;
+ Ini.Load;
+ Language.ChangeLanguage(ILanguage[Ini.Language]);
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Ini', 1);
+
+ // LCD
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Load LCD', 'Initialization'); LCD := TLCD.Create;
+ if Ini.LPT = 1 then begin
+// LCD.HalfInterface := true;
+ LCD.Enable;
+ LCD.Clear;
+ LCD.WriteText(1, ' UltraStar ');
+ LCD.WriteText(2, ' Loading... ');
+ end;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading LCD', 1);
+
+ // Light
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Load Light', 'Initialization'); Light := TLight.Create;
+ if Ini.LPT = 2 then begin
+ Light.Enable;
+// Light.LightOne(0, 1000);
+ end;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Light', 1);
+
+ // Theme
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Load Themes', 'Initialization'); Theme := TTheme.Create('Themes\' + ITheme[Ini.Theme] + '.ini', Ini.Color);
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Themes', 1);
+
+ // Covers Cache
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Creating Covers Cache', 'Initialization'); Covers := TCovers.Create;
+ Log.LogBenchmark('Loading Covers Cache Array', 1);
+ Log.BenchmarkStart(1);
+
+ // Category Covers
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Creating Category Covers Array', 'Initialization');
+ CatCovers:= TCatCovers.Create;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Category Covers Array', 1);
+
+ // Songs
+ //Log.BenchmarkStart(1);
+ Log.LogStatus('Creating Song Array', 'Initialization'); Songs := TSongs.Create;
+ Songs.LoadSongList;
+ Log.LogStatus('Creating 2nd Song Array', 'Initialization'); CatSongs := TCatSongs.Create;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Songs', 1);
+
+ // PluginManager
+ Log.BenchmarkStart(1);
+ Log.LogStatus('PluginManager', 'Initialization');
+ DLLMan := TDLLMan.Create; //Load PluginList
+
+ Log.LogError(inttostr(Length(DLLMan.Plugins)) + ' Plugins Loaded');
+
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading PluginManager', 1);
+
+ // Party Mode Manager
+ Log.BenchmarkStart(1);
+ Log.LogStatus('PartySession Manager', 'Initialization');
+ PartySession := TParty_Session.Create; //Load PartySession
+
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading PartySession Manager', 1);
+
+ // Graphics
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Initialize 3D', 'Initialization'); Initialize3D(WndTitle);
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Initializing 3D', 1);
+
+ // Sound
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Initialize Sound', 'Initialization');
+ Log.LogStatus('Creating Music', 'InitializeSound'); Music := TMusic.Create;
+ InitializeSound;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Initializing Sound', 1);
+
+ // Score Saving System
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Score DB System', 'Initialization');
+ InitScore('Scores.db');
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Score DB System', 1);
+
+ // Joypad
+ if Ini.Joypad = 1 then begin
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Initialize Joystick', 'Initialization'); Joy := TJoy.Create;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Initializing Joystick', 1);
+ end;
+
+ Log.BenchmarkEnd(0);
+ Log.LogBenchmark('Loading Time', 0);
+
+
+// Music.SetLoop(true);
+// Music.SetVolume(50);
+// Music.Open(SkinPath + 'Menu Music 3.mp3');
+// Music.Play;
+ Log.LogStatus('Main Loop', 'Initialization'); MainLoop;
+
+// sleep(3000);
+
+ // finish
+ if Ini.LPT = 1 then LCD.Clear;
+ if Ini.LPT = 2 then Light.TurnOff;
+
+ Log.Free;
+end. \ No newline at end of file
diff --git a/Game/Code/UltraStar.identcache2 b/Game/Code/UltraStar.identcache2
new file mode 100644
index 00000000..a437aa7e
--- /dev/null
+++ b/Game/Code/UltraStar.identcache2
Binary files differ
diff --git a/Game/Code/UltraStar.rc b/Game/Code/UltraStar.rc
new file mode 100644
index 00000000..22ee2142
--- /dev/null
+++ b/Game/Code/UltraStar.rc
@@ -0,0 +1,15 @@
+Button JPG "..\Graphics\MusicWheelItem song.jpg"
+
+Font BMP "..\Fonts\Normal\Font Normal 16.bmp"
+Font FNT "..\Fonts\Normal\Font Normal.dat"
+
+FontB BMP "..\Fonts\Bold\Font 1024 Bold 16.bmp"
+FontB FNT "..\Fonts\Bold\Font 1024 Bold.dat"
+
+FontO BMP "..\Fonts\Outline 1\Outline 36 (1024) 16c.bmp"
+FontO FNT "..\Fonts\Outline 1\Outline 36 (1024).dat"
+
+FontO2 BMP "..\Fonts\Outline 2\5 - Outline Dark Edited 16c.bmp"
+FontO2 FNT "..\Fonts\Outline 2\Outline.dat"
+
+MAINICON ICON "..\Graphics\us.ico"
diff --git a/Game/Code/UltraStar.~dpr b/Game/Code/UltraStar.~dpr
new file mode 100644
index 00000000..a27201e9
--- /dev/null
+++ b/Game/Code/UltraStar.~dpr
@@ -0,0 +1,285 @@
+ program UltraStar;
+
+{$DEFINE TRANSLATE}
+//DEFINE THEMESAVE}
+
+{$R 'UltraStar.res' 'UltraStar.rc'}
+
+uses
+ {//Earlyer in Code Dir.. Now in SearchDir
+ DDKint in '..\ZLPortIO\ddkint.pas',
+ ZLPortIO in '..\ZLPortIO\zlportio.pas',
+ SQLiteTable3 in '..\SQLite\SQLiteTable3.pas',
+ SQLite3 in '..\SQLite\SQLite3.pas',}
+ Windows,
+ SDL,
+
+ //Menu Objects
+ UDisplay in 'Menu\UDisplay.pas',
+ UMenu in 'Menu\UMenu.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',
+
+ //Classes
+ UGraphic in 'Classes\UGraphic.pas',
+ UTexture in 'Classes\UTexture.pas',
+ UMusic in 'Classes\UMusic.pas',
+ UPliki in 'Classes\UPliki.pas',
+ UMain in 'Classes\UMain.pas',
+ UDraw in 'Classes\UDraw.pas',
+ URecord in 'Classes\URecord.pas',
+ UTime in 'Classes\UTime.pas',
+ TextGL in 'Classes\TextGL.pas',
+ USongs in 'Classes\USongs.pas',
+ UIni in 'Classes\UIni.pas',
+ USmpeg in 'SMpeg\USmpeg.pas',
+ ULyrics in 'Classes\ULyrics.pas',
+ USkins in 'Classes\USkins.pas',
+ UThemes in 'Classes\UThemes.pas',
+ ULog in 'Classes\ULog.pas',
+ UJoystick in 'Classes\UJoystick.pas',
+ ULCD in 'Classes\ULCD.pas',
+ ULight in 'Classes\ULight.pas',
+ UScores in 'Classes\UScores.pas',
+ ULanguage in 'Classes\ULanguage.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',
+
+ //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',
+ 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',
+ //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',
+
+ //Modi SDK
+ ModiSDK in '..\..\Modis\SDK\ModiSDK.pas';
+
+const
+ Version = 'UltraStar Deluxe V 0.90 Beta';
+
+var
+ WndTitle: string;
+ hWnd: THandle;
+ I: Integer;
+
+begin
+ WndTitle := Version;
+
+ //Start more than One Time Prevention
+ hWnd:= FindWindow(nil, PChar(WndTitle));
+ //Programm already started
+ if (hWnd <> 0) then
+ begin
+ I := Messagebox(0, PChar('Another Instance of Ultrastar is already running. Contėnue ?'), PChar(WndTitle), MB_ICONWARNING or MB_YESNO);
+ if (I = IDYes) then
+ begin
+ I := 1;
+ repeat
+ Inc(I);
+ hWnd := FindWindow(nil, PChar(WndTitle + ' Instance ' + InttoStr(I)));
+ until (hWnd = 0);
+
+ WndTitle := WndTitle + ' Instance ' + InttoStr(I);
+ end
+ else
+ Exit;
+ end;
+
+
+
+ USTime := TTime.Create;
+
+ // Log + Benchmark
+ Log := TLog.Create;
+ Log.Title := WndTitle;
+ Log.BenchmarkStart(0);
+// Log.LogError(IntToStr(DayOfTheYear(Date)));
+
+ // Language
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Initialize Paths', 'Initialization'); InitializePaths;
+ Log.LogStatus('Load Language', 'Initialization'); Language := TLanguage.Create;
+ //Add Const Values:
+ Language.AddConst('US_VERSION', Version);
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Language', 1);
+
+ // SDL
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Initialize SDL', 'Initialization');
+ SDL_Init(SDL_INIT_VIDEO or SDL_INIT_AUDIO);
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Initializing SDL', 1);
+
+ // Skin
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Loading Skin List', 'Initialization'); Skin := TSkin.Create;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Skin List', 1);
+
+ //Log.LogBenchmark(inttostr(Skin.), 1);
+
+ // Sound Card List
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Loading Soundcard list', 'Initialization');
+ Recording := TRecord.Create;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Soundcard list', 1);
+
+ // Ini + Paths
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Load Ini', 'Initialization'); Ini := TIni.Create;
+ Ini.Load;
+ Language.ChangeLanguage(ILanguage[Ini.Language]);
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Ini', 1);
+
+ // LCD
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Load LCD', 'Initialization'); LCD := TLCD.Create;
+ if Ini.LPT = 1 then begin
+// LCD.HalfInterface := true;
+ LCD.Enable;
+ LCD.Clear;
+ LCD.WriteText(1, ' UltraStar ');
+ LCD.WriteText(2, ' Loading... ');
+ end;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading LCD', 1);
+
+ // Light
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Load Light', 'Initialization'); Light := TLight.Create;
+ if Ini.LPT = 2 then begin
+ Light.Enable;
+// Light.LightOne(0, 1000);
+ end;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Light', 1);
+
+ // Theme
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Load Themes', 'Initialization'); Theme := TTheme.Create('Themes\' + ITheme[Ini.Theme] + '.ini', Ini.Color);
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Themes', 1);
+
+ // Covers Cache
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Creating Covers Cache', 'Initialization'); Covers := TCovers.Create;
+ Log.LogBenchmark('Loading Covers Cache Array', 1);
+ Log.BenchmarkStart(1);
+
+ // Category Covers
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Creating Category Covers Array', 'Initialization');
+ CatCovers:= TCatCovers.Create;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Category Covers Array', 1);
+
+ // Songs
+ //Log.BenchmarkStart(1);
+ Log.LogStatus('Creating Song Array', 'Initialization'); Songs := TSongs.Create;
+ Songs.LoadSongList;
+ Log.LogStatus('Creating 2nd Song Array', 'Initialization'); CatSongs := TCatSongs.Create;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Songs', 1);
+
+ // PluginManager
+ Log.BenchmarkStart(1);
+ Log.LogStatus('PluginManager', 'Initialization');
+ DLLMan := TDLLMan.Create; //Load PluginList
+
+ Log.LogError(inttostr(Length(DLLMan.Plugins)) + ' Plugins Loaded');
+
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading PluginManager', 1);
+
+ // Party Mode Manager
+ Log.BenchmarkStart(1);
+ Log.LogStatus('PartySession Manager', 'Initialization');
+ PartySession := TParty_Session.Create; //Load PartySession
+
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading PartySession Manager', 1);
+
+ // Graphics
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Initialize 3D', 'Initialization'); Initialize3D(WndTitle);
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Initializing 3D', 1);
+
+ // Sound
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Initialize Sound', 'Initialization');
+ Log.LogStatus('Creating Music', 'InitializeSound'); Music := TMusic.Create;
+ InitializeSound;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Initializing Sound', 1);
+
+ // Score Saving System
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Score DB System', 'Initialization');
+ InitScore('Scores.db');
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Loading Score DB System', 1);
+
+ // Joypad
+ if Ini.Joypad = 1 then begin
+ Log.BenchmarkStart(1);
+ Log.LogStatus('Initialize Joystick', 'Initialization'); Joy := TJoy.Create;
+ Log.BenchmarkEnd(1);
+ Log.LogBenchmark('Initializing Joystick', 1);
+ end;
+
+ Log.BenchmarkEnd(0);
+ Log.LogBenchmark('Loading Time', 0);
+
+
+// Music.SetLoop(true);
+// Music.SetVolume(50);
+// Music.Open(SkinPath + 'Menu Music 3.mp3');
+// Music.Play;
+ Log.LogStatus('Main Loop', 'Initialization'); MainLoop;
+
+// sleep(3000);
+
+ // finish
+ if Ini.LPT = 1 then LCD.Clear;
+ if Ini.LPT = 2 then Light.TurnOff;
+
+ Log.Free;
+end. \ No newline at end of file
diff --git a/Game/Code/rccompillieren.bat b/Game/Code/rccompillieren.bat
new file mode 100644
index 00000000..4e2f2584
--- /dev/null
+++ b/Game/Code/rccompillieren.bat
@@ -0,0 +1 @@
+BRC32 -r UltraStar.RC \ No newline at end of file
diff --git a/Game/Fonts/512x512 Normal.dat b/Game/Fonts/512x512 Normal.dat
new file mode 100644
index 00000000..52666d1a
--- /dev/null
+++ b/Game/Fonts/512x512 Normal.dat
Binary files differ
diff --git a/Game/Fonts/Backup/Bold/Font 1024 Bold 16.bmp b/Game/Fonts/Backup/Bold/Font 1024 Bold 16.bmp
new file mode 100644
index 00000000..d485567d
--- /dev/null
+++ b/Game/Fonts/Backup/Bold/Font 1024 Bold 16.bmp
Binary files differ
diff --git a/Game/Fonts/Backup/Bold/Font 1024 Bold.dat b/Game/Fonts/Backup/Bold/Font 1024 Bold.dat
new file mode 100644
index 00000000..ac64a71a
--- /dev/null
+++ b/Game/Fonts/Backup/Bold/Font 1024 Bold.dat
Binary files differ
diff --git a/Game/Fonts/Backup/Bold/Thumbs.db b/Game/Fonts/Backup/Bold/Thumbs.db
new file mode 100644
index 00000000..a445e690
--- /dev/null
+++ b/Game/Fonts/Backup/Bold/Thumbs.db
Binary files differ
diff --git a/Game/Fonts/Backup/Normal/Font Normal 16.bmp b/Game/Fonts/Backup/Normal/Font Normal 16.bmp
new file mode 100644
index 00000000..725f05bd
--- /dev/null
+++ b/Game/Fonts/Backup/Normal/Font Normal 16.bmp
Binary files differ
diff --git a/Game/Fonts/Backup/Normal/Font Normal.dat b/Game/Fonts/Backup/Normal/Font Normal.dat
new file mode 100644
index 00000000..5f69cfc8
--- /dev/null
+++ b/Game/Fonts/Backup/Normal/Font Normal.dat
Binary files differ
diff --git a/Game/Fonts/Backup/Normal/Thumbs.db b/Game/Fonts/Backup/Normal/Thumbs.db
new file mode 100644
index 00000000..469eaf5c
--- /dev/null
+++ b/Game/Fonts/Backup/Normal/Thumbs.db
Binary files differ
diff --git a/Game/Fonts/Backup/Outline 1/Outline 36 (1024) 16c.bmp b/Game/Fonts/Backup/Outline 1/Outline 36 (1024) 16c.bmp
new file mode 100644
index 00000000..893725d4
--- /dev/null
+++ b/Game/Fonts/Backup/Outline 1/Outline 36 (1024) 16c.bmp
Binary files differ
diff --git a/Game/Fonts/Backup/Outline 1/Outline 36 (1024).dat b/Game/Fonts/Backup/Outline 1/Outline 36 (1024).dat
new file mode 100644
index 00000000..e9fb10fa
--- /dev/null
+++ b/Game/Fonts/Backup/Outline 1/Outline 36 (1024).dat
Binary files differ
diff --git a/Game/Fonts/Backup/Outline 1/Thumbs.db b/Game/Fonts/Backup/Outline 1/Thumbs.db
new file mode 100644
index 00000000..94e6c896
--- /dev/null
+++ b/Game/Fonts/Backup/Outline 1/Thumbs.db
Binary files differ
diff --git a/Game/Fonts/Backup/Outline 2/5 - Outline dark edited 16c.bmp b/Game/Fonts/Backup/Outline 2/5 - Outline dark edited 16c.bmp
new file mode 100644
index 00000000..b7285946
--- /dev/null
+++ b/Game/Fonts/Backup/Outline 2/5 - Outline dark edited 16c.bmp
Binary files differ
diff --git a/Game/Fonts/Backup/Outline 2/Outline.dat b/Game/Fonts/Backup/Outline 2/Outline.dat
new file mode 100644
index 00000000..16ca7fd7
--- /dev/null
+++ b/Game/Fonts/Backup/Outline 2/Outline.dat
Binary files differ
diff --git a/Game/Fonts/Backup/Outline 2/Thumbs.db b/Game/Fonts/Backup/Outline 2/Thumbs.db
new file mode 100644
index 00000000..685a4ee5
--- /dev/null
+++ b/Game/Fonts/Backup/Outline 2/Thumbs.db
Binary files differ
diff --git a/Game/Fonts/Bold/Font 1024 Bold 16.bmp b/Game/Fonts/Bold/Font 1024 Bold 16.bmp
new file mode 100644
index 00000000..f0611a53
--- /dev/null
+++ b/Game/Fonts/Bold/Font 1024 Bold 16.bmp
Binary files differ
diff --git a/Game/Fonts/Bold/Font 1024 Bold 16.old.bmp b/Game/Fonts/Bold/Font 1024 Bold 16.old.bmp
new file mode 100644
index 00000000..d485567d
--- /dev/null
+++ b/Game/Fonts/Bold/Font 1024 Bold 16.old.bmp
Binary files differ
diff --git a/Game/Fonts/Bold/Font 1024 Bold.dat b/Game/Fonts/Bold/Font 1024 Bold.dat
new file mode 100644
index 00000000..280a6cb4
--- /dev/null
+++ b/Game/Fonts/Bold/Font 1024 Bold.dat
Binary files differ
diff --git a/Game/Fonts/Bold/Thumbs.db b/Game/Fonts/Bold/Thumbs.db
new file mode 100644
index 00000000..a445e690
--- /dev/null
+++ b/Game/Fonts/Bold/Thumbs.db
Binary files differ
diff --git a/Game/Fonts/Normal/Font Normal 16.bmp b/Game/Fonts/Normal/Font Normal 16.bmp
new file mode 100644
index 00000000..6534d9c3
--- /dev/null
+++ b/Game/Fonts/Normal/Font Normal 16.bmp
Binary files differ
diff --git a/Game/Fonts/Normal/Font Normal 16.old.bmp b/Game/Fonts/Normal/Font Normal 16.old.bmp
new file mode 100644
index 00000000..725f05bd
--- /dev/null
+++ b/Game/Fonts/Normal/Font Normal 16.old.bmp
Binary files differ
diff --git a/Game/Fonts/Normal/Font Normal.dat b/Game/Fonts/Normal/Font Normal.dat
new file mode 100644
index 00000000..1b517a0e
--- /dev/null
+++ b/Game/Fonts/Normal/Font Normal.dat
Binary files differ
diff --git a/Game/Fonts/Normal/Thumbs.db b/Game/Fonts/Normal/Thumbs.db
new file mode 100644
index 00000000..2cad5e2b
--- /dev/null
+++ b/Game/Fonts/Normal/Thumbs.db
Binary files differ
diff --git a/Game/Fonts/Outline 1/Outline 36 (1024) 16c.bmp b/Game/Fonts/Outline 1/Outline 36 (1024) 16c.bmp
new file mode 100644
index 00000000..25b03a57
--- /dev/null
+++ b/Game/Fonts/Outline 1/Outline 36 (1024) 16c.bmp
Binary files differ
diff --git a/Game/Fonts/Outline 1/Outline 36 (1024).dat b/Game/Fonts/Outline 1/Outline 36 (1024).dat
new file mode 100644
index 00000000..280a6cb4
--- /dev/null
+++ b/Game/Fonts/Outline 1/Outline 36 (1024).dat
Binary files differ
diff --git a/Game/Fonts/Outline 1/Photoshop.psd b/Game/Fonts/Outline 1/Photoshop.psd
new file mode 100644
index 00000000..d7d0e99d
--- /dev/null
+++ b/Game/Fonts/Outline 1/Photoshop.psd
Binary files differ
diff --git a/Game/Fonts/Outline 1/Thumbs.db b/Game/Fonts/Outline 1/Thumbs.db
new file mode 100644
index 00000000..b6e96879
--- /dev/null
+++ b/Game/Fonts/Outline 1/Thumbs.db
Binary files differ
diff --git a/Game/Fonts/Outline 2/5 - Outline dark edited 16c.bmp b/Game/Fonts/Outline 2/5 - Outline dark edited 16c.bmp
new file mode 100644
index 00000000..6d78ba77
--- /dev/null
+++ b/Game/Fonts/Outline 2/5 - Outline dark edited 16c.bmp
Binary files differ
diff --git a/Game/Fonts/Outline 2/Outline.dat b/Game/Fonts/Outline 2/Outline.dat
new file mode 100644
index 00000000..9f1042e6
--- /dev/null
+++ b/Game/Fonts/Outline 2/Outline.dat
Binary files differ
diff --git a/Game/Fonts/Outline 2/Thumbs.db b/Game/Fonts/Outline 2/Thumbs.db
new file mode 100644
index 00000000..685a4ee5
--- /dev/null
+++ b/Game/Fonts/Outline 2/Thumbs.db
Binary files differ
diff --git a/Game/Graphics/MusicWheelItem song.jpg b/Game/Graphics/MusicWheelItem song.jpg
new file mode 100644
index 00000000..87671377
--- /dev/null
+++ b/Game/Graphics/MusicWheelItem song.jpg
Binary files differ
diff --git a/Game/Graphics/Thumbs.db b/Game/Graphics/Thumbs.db
new file mode 100644
index 00000000..901e717c
--- /dev/null
+++ b/Game/Graphics/Thumbs.db
Binary files differ
diff --git a/Game/Graphics/us.ico b/Game/Graphics/us.ico
new file mode 100644
index 00000000..e21ed5e8
--- /dev/null
+++ b/Game/Graphics/us.ico
Binary files differ