diff options
author | jaybinks <jaybinks@b956fd51-792f-4845-bead-9b4dfca2ff2c> | 2007-10-02 04:39:22 +0000 |
---|---|---|
committer | jaybinks <jaybinks@b956fd51-792f-4845-bead-9b4dfca2ff2c> | 2007-10-02 04:39:22 +0000 |
commit | b29759fbfdd8a013e3d0a85b578934ebec028c41 (patch) | |
tree | db75c93eea11c5e9f7d477be4f94b5dfe7559626 /Game/Code | |
parent | bcf55203a81aef383d0a7123996e872fa3a297dc (diff) | |
download | usdx-b29759fbfdd8a013e3d0a85b578934ebec028c41.tar.gz usdx-b29759fbfdd8a013e3d0a85b578934ebec028c41.tar.xz usdx-b29759fbfdd8a013e3d0a85b578934ebec028c41.zip |
Fixed linux compilation.
Linux is now running in the main loop fine.
* no audio playback or input yet...
* Timing hack inplace.. that must be replace
* bunch of textures not working..
however the play screen is looking similar to windows builds.
I hope this dosnt break windows builds to much.
git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@460 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to 'Game/Code')
-rw-r--r-- | Game/Code/Classes/TextGL.pas | 1108 | ||||
-rw-r--r-- | Game/Code/Classes/UCommon.pas | 341 | ||||
-rw-r--r-- | Game/Code/Classes/UGraphic.pas | 1391 | ||||
-rw-r--r-- | Game/Code/Classes/UIni.pas | 22 | ||||
-rw-r--r-- | Game/Code/Classes/ULyrics.pas | 1094 | ||||
-rw-r--r-- | Game/Code/Classes/UMain.pas | 1584 | ||||
-rw-r--r-- | Game/Code/Classes/UMusic.pas | 1473 | ||||
-rw-r--r-- | Game/Code/Classes/USkins.pas | 345 | ||||
-rw-r--r-- | Game/Code/Classes/UTexture.pas | 2249 | ||||
-rw-r--r-- | Game/Code/Classes/UThemes.pas | 4412 | ||||
-rw-r--r-- | Game/Code/Classes/UTime.pas | 6 | ||||
-rw-r--r-- | Game/Code/Menu/UDisplay.pas | 90 | ||||
-rw-r--r-- | Game/Code/Menu/UMenu.pas | 3073 | ||||
-rw-r--r-- | Game/Code/Screens/UScreenOptionsRecord.pas | 270 | ||||
-rw-r--r-- | Game/Code/Screens/UScreenScore.pas | 1335 | ||||
-rw-r--r-- | Game/Code/Screens/UScreenTop5.pas | 336 | ||||
-rw-r--r-- | Game/Code/UltraStar.lpr | 856 | ||||
-rw-r--r-- | Game/Code/UltraStar.rc | 22 | ||||
-rw-r--r-- | Game/Code/lib/requirements.txt | 4 |
19 files changed, 10093 insertions, 9918 deletions
diff --git a/Game/Code/Classes/TextGL.pas b/Game/Code/Classes/TextGL.pas index 9b125812..fbe9a050 100644 --- a/Game/Code/Classes/TextGL.pas +++ b/Game/Code/Classes/TextGL.pas @@ -1,554 +1,554 @@ -unit TextGL;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-
-uses OpenGL12,
- SDL,
- UTexture,
- Classes,
- dialogs,
- SDL_ttf,
- 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);
-
-// Start of SDL_ttf
-function NextPowerOfTwo(Value: Integer): Integer;
-//Checks if the ttf exists, if yes then a SDL_ttf is returned
-function LoadFont(FileName: PAnsiChar; PointSize: integer):PTTF_Font;
-
-// Does the renderstuff, color is in $ffeecc style
-function RenderText(font: PTTF_Font; Text:PAnsiChar; Color: Cardinal):PSDL_Surface;
-procedure printrandomtext();
-// End of SDL_ttf
-
-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,
- UCommon,
- {$IFDEF win32}
- windows,
- {$ELSE}
- lclintf,
- lcltype,
- {$ENDIF}
- SysUtils,
- {$IFDEF FPC}
- LResources,
- {$ENDIF}
- UGraphic;
-
-procedure BuildFont; // Build Our Bitmap Font
-
- procedure loadfont( aID : integer; aType, aResourceName : String);
- {$IFDEF FPC}
- var
- lLazRes : TLResource;
- lResData : TStringStream;
- begin
- try
- lLazRes := LazFindResource( aResourceName, aType );
- if lLazRes <> nil then
- begin
- lResData := TStringStream.create( lLazRes.value );
- try
- lResData.position := 0;
- lResData.Read(Fonts[ aID ].Width, 256);
- finally
- freeandnil( lResData );
- end;
- end;
-
- {$ELSE}
- var
- Rejestr: TResourceStream;
- begin
- try
- Rejestr := TResourceStream.Create(HInstance, aResourceName , pchar( aType ) );
- try
- Rejestr.Read(Fonts[ aID ].Width, 256);
- finally
- Rejestr.Free;
- end;
- {$ENDIF}
-
- except
- Log.LogStatus( 'Could not load font : loadfont( '+ inttostr( aID ) +' , '+aType+' )' , 'ERROR');
- end;
- end;
-
-var
- font: HFONT; // Windows Font ID
- h_dc: hdc;
- Pet: integer;
-begin
- ActFont := 0;
-
- Log.LogStatus( '' , '---------------------------');
-
- Log.LogStatus( 'Font' , '---------------------------');
- SetLength(Fonts, 5);
- Fonts[0].Tex := Texture.LoadTexture(true, 'Font', 'PNG', 'Font', 0);
- Fonts[0].Tex.H := 30;
- Fonts[0].AspectW := 0.9;
- Fonts[0].Done := -1;
- Fonts[0].Outline := 0;
-
- Log.LogStatus( 'FontB' , '---------------------------');
-
- Fonts[1].Tex := Texture.LoadTexture(true, 'FontB', 'PNG', 'Font', 0);
- Fonts[1].Tex.H := 30;
- Fonts[1].AspectW := 1;
- Fonts[1].Done := -1;
- Fonts[1].Outline := 0;
-
- Log.LogStatus( 'FontO' , '---------------------------');
- Fonts[2].Tex := Texture.LoadTexture(true, 'FontO', 'PNG', 'Font Outline', 0);
- Fonts[2].Tex.H := 30;
- Fonts[2].AspectW := 0.95;
- Fonts[2].Done := -1;
- Fonts[2].Outline := 5;
-
- Log.LogStatus( 'FontO2' , '---------------------------');
- Fonts[3].Tex := Texture.LoadTexture(true, 'FontO2', 'PNG', 'Font Outline 2', 0);
- Fonts[3].Tex.H := 30;
- Fonts[3].AspectW := 0.95;
- Fonts[3].Done := -1;
- Fonts[3].Outline := 4;
-
-{ Fonts[4].Tex := Texture.LoadTexture('FontO', 'BMP', 'Arrow', 0); // for score screen
- Fonts[4].Tex.H := 30;
- Fonts[4].AspectW := 0.95;
- Fonts[4].Done := -1;
- Fonts[4].Outline := 5;}
-
-
-
- loadfont( 0, 'FNT', 'Font' );
- loadfont( 1, 'FNT', 'FontB' );
- loadfont( 2, 'FNT', 'FontO' );
- loadfont( 3, 'FNT', 'FontO2' );
-
-{ 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_COLOR, GL_ONE_MINUS_SRC_COLOR);
- glBindTexture(GL_TEXTURE_2D, TexNum);
-
- glBegin(GL_QUADS);
- try
- 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);
- finally
- glEnd;
- end;
-
- 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_COLOR, GL_ONE_MINUS_SRC_COLOR);
- 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;
- iPos : Integer;
-
-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
-*)
-
- // This code is better, because doing a Copy of for every
- // letter in a string is a waste of CPU & Memory resources.
- // Copy operations are quite memory intensive, and this simple
- // code achieves the same result.
- for iPos := 0 to length( text ) - 1 do
- begin
- glPrintLetter( Text[iPos] );
- end;
-
-end;
-
-function NextPowerOfTwo(Value: Integer): Integer;
-// tyty to Asphyre
-begin
- Result:= 1;
- asm
- xor ecx, ecx
- bsr ecx, Value
- inc ecx
- shl Result, cl
- end;
-end;
-
-function LoadFont(FileName: PAnsiChar; PointSize: integer):PTTF_Font;
-begin
- if (FileExists(FileName)) then
- begin
- Result := TTF_OpenFont( FileName, PointSize );
- end
- else
- begin
- Log.LogStatus('ERROR Could not find font in ' + FileName , '');
- ShowMessage( 'ERROR Could not find font in ' + FileName );
- end;
-end;
-
-function RenderText(font: PTTF_Font; Text:PAnsiChar; Color: Cardinal): PSDL_Surface;
-var
- clr : TSDL_color;
-begin
- clr.r := ((Color and $ff0000) shr 16 ) div 255;
- clr.g := ((Color and $ff00 ) shr 8 ) div 255;
- clr.b := ( Color and $ff ) div 255 ;
-
- result := TTF_RenderText_Blended( font, text, cLr);
-end;
-
-procedure printrandomtext();
-var
- stext,intermediary : PSDL_surface;
- clrFg, clrBG : TSDL_color;
- texture : Gluint;
- font : PTTF_Font;
- w,h : integer;
-begin
-
-font := LoadFont('fonts\comicbd.ttf', 42);
-
-clrFg.r := 255;
-clrFg.g := 255;
-clrFg.b := 255;
-clrFg.unused := 255;
-
-clrBg.r := 255;
-clrbg.g := 0;
-clrbg.b := 255;
-clrbg.unused := 0;
-
- sText := RenderText(font, 'katzeeeeeee', $fe198e);
-//sText := TTF_RenderText_Blended( font, 'huuuuuuuuuund', clrFG);
-
- // Convert the rendered text to a known format
- w := nextpoweroftwo(sText.w);
- h := nextpoweroftwo(sText.h);
-
-intermediary := SDL_CreateRGBSurface(0, w, h, 32,
- $000000ff, $0000ff00, $00ff0000, $ff000000);
-
- SDL_SetAlpha(intermediary, 0, 255);
- SDL_SetAlpha(sText, 0, 255);
- SDL_BlitSurface(sText, 0, intermediary, 0);
-
- glGenTextures(1, texture);
-
- glBindTexture(GL_TEXTURE_2D, texture);
-
- glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, intermediary.pixels);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
-
-
-
-
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glBindTexture(GL_TEXTURE_2D, texture);
- glColor4f(1, 0, 1, 1);
-
- glbegin(gl_quads);
- glTexCoord2f(0,0); glVertex2f(200, 300);
- glTexCoord2f(0,sText.h/h); glVertex2f(200 , 300 + sText.h);
- glTexCoord2f(sText.w/w,sText.h/h); glVertex2f(200 + sText.w, 300 + sText.h);
- glTexCoord2f(sText.w/w,0); glVertex2f(200 + sText.w, 300);
- glEnd;
- glfinish();
- glDisable(GL_BLEND);
- gldisable(gl_texture_2d);
-
-
-
-
-SDL_FreeSurface( sText );
-SDL_FreeSurface( intermediary );
-glDeleteTextures(1, @texture);
-TTF_CloseFont( font );
-
-end;
-
-procedure glPrintCut(text: pchar);
-var
- Letter: char;
- PToDo: real;
- PTotWidth: real;
- PDoingNow: real;
- S: string;
-begin
- if (Text = '') then // If There's No Text
- Exit; // Do Nothing
-
- PTotWidth := glTextWidth(Text);
- PToDo := Fonts[ActFont].Done;
-
- while (length(text) > 0) do begin
- // cut
- Letter := Text[0];
- Text := pchar(Copy(Text, 2, Length(Text)-1));
-
- // analyze
- S := Letter;
- PDoingNow := glTextWidth(pchar(S)) / PTotWidth;
-
- // drawing
- if (PToDo > 0) and (PDoingNow <= PToDo) then
- glPrintLetter(Letter);
-
- if (PToDo > 0) and (PDoingNow > PToDo) then begin
- glPrintLetterCut(Letter, 0, PToDo / PDoingNow);
- glColor3f(PColR, PColG, PColB);
- glPrintLetterCut(Letter, PToDo / PDoingNow, 1);
- end;
-
- if (PToDo <= 0) then
- glPrintLetter(Letter);
-
- PToDo := PToDo - PDoingNow;
-
- end; // while
-end;
-
-
-procedure SetFontPos(X, Y: real);
-begin
- Fonts[ActFont].Tex.X := X;
- Fonts[ActFont].Tex.Y := Y;
-end;
-
-procedure SetFontSize(Size: real);
-begin
- Fonts[ActFont].Tex.H := 30 * (Size/10);
-end;
-
-procedure SetFontStyle(Style: integer);
-begin
- ActFont := Style;
-end;
-
-procedure SetFontItalic(Enable: boolean);
-begin
- Fonts[ActFont].Italic := Enable;
-end;
-
-procedure SetFontAspectW(Aspect: real);
-begin
- Fonts[ActFont].AspectW := Aspect;
-end;
-
-
-{$IFDEF FPC}
-{$IFDEF win32}
-initialization
- {$I UltraStar.lrs}
-{$ENDIF}
-{$ENDIF}
-
-
-end.
-
-
+unit TextGL; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + + +uses OpenGL12, + SDL, + UTexture, + Classes, + dialogs, + SDL_ttf, + 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); + +// Start of SDL_ttf +function NextPowerOfTwo(Value: Integer): Integer; +//Checks if the ttf exists, if yes then a SDL_ttf is returned +function LoadFont(FileName: PAnsiChar; PointSize: integer):PTTF_Font; + +// Does the renderstuff, color is in $ffeecc style +function RenderText(font: PTTF_Font; Text:PAnsiChar; Color: Cardinal):PSDL_Surface; +procedure printrandomtext(); +// End of SDL_ttf + +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, + UCommon, + {$IFDEF win32} + windows, + {$ELSE} + lclintf, + lcltype, + {$ENDIF} + SysUtils, + {$IFDEF FPC} + LResources, + {$ENDIF} + UGraphic; + +procedure BuildFont; // Build Our Bitmap Font + + procedure loadfont( aID : integer; aType, aResourceName : String); + {$IFDEF FPC} + var + lLazRes : TLResource; + lResData : TStringStream; + begin + try + lLazRes := LazFindResource( aResourceName, aType ); + if lLazRes <> nil then + begin + lResData := TStringStream.create( lLazRes.value ); + try + lResData.position := 0; + lResData.Read(Fonts[ aID ].Width, 256); + finally + freeandnil( lResData ); + end; + end; + + {$ELSE} + var + Rejestr: TResourceStream; + begin + try + Rejestr := TResourceStream.Create(HInstance, aResourceName , pchar( aType ) ); + try + Rejestr.Read(Fonts[ aID ].Width, 256); + finally + Rejestr.Free; + end; + {$ENDIF} + + except + Log.LogStatus( 'Could not load font : loadfont( '+ inttostr( aID ) +' , '+aType+' )' , 'ERROR'); + end; + end; + +var + font: HFONT; // Windows Font ID + h_dc: hdc; + Pet: integer; +begin + ActFont := 0; + + Log.LogStatus( '' , '---------------------------'); + + Log.LogStatus( 'Font' , '---------------------------'); + SetLength(Fonts, 5); + Fonts[0].Tex := Texture.LoadTexture(true, 'Font', 'PNG', 'Font', 0); + Fonts[0].Tex.H := 30; + Fonts[0].AspectW := 0.9; + Fonts[0].Done := -1; + Fonts[0].Outline := 0; + + Log.LogStatus( 'FontB' , '---------------------------'); + + Fonts[1].Tex := Texture.LoadTexture(true, 'FontB', 'PNG', 'Font', 0); + Fonts[1].Tex.H := 30; + Fonts[1].AspectW := 1; + Fonts[1].Done := -1; + Fonts[1].Outline := 0; + + Log.LogStatus( 'FontO' , '---------------------------'); + Fonts[2].Tex := Texture.LoadTexture(true, 'FontO', 'PNG', 'Font Outline', 0); + Fonts[2].Tex.H := 30; + Fonts[2].AspectW := 0.95; + Fonts[2].Done := -1; + Fonts[2].Outline := 5; + + Log.LogStatus( 'FontO2' , '---------------------------'); + Fonts[3].Tex := Texture.LoadTexture(true, 'FontO2', 'PNG', 'Font Outline 2', 0); + Fonts[3].Tex.H := 30; + Fonts[3].AspectW := 0.95; + Fonts[3].Done := -1; + Fonts[3].Outline := 4; + +{ Fonts[4].Tex := Texture.LoadTexture('FontO', 'BMP', 'Arrow', 0); // for score screen + Fonts[4].Tex.H := 30; + Fonts[4].AspectW := 0.95; + Fonts[4].Done := -1; + Fonts[4].Outline := 5;} + + + + loadfont( 0, 'FNT', 'Font' ); + loadfont( 1, 'FNT', 'FontB' ); + loadfont( 2, 'FNT', 'FontO' ); + loadfont( 3, 'FNT', 'FontO2' ); + +{ 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_COLOR, GL_ONE_MINUS_SRC_COLOR); + glBindTexture(GL_TEXTURE_2D, TexNum); + + glBegin(GL_QUADS); + try + 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); + finally + glEnd; + end; + + 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_COLOR, GL_ONE_MINUS_SRC_COLOR); + 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; + iPos : Integer; + +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 +*) + + // This code is better, because doing a Copy of for every + // letter in a string is a waste of CPU & Memory resources. + // Copy operations are quite memory intensive, and this simple + // code achieves the same result. + for iPos := 0 to length( text ) - 1 do + begin + glPrintLetter( Text[iPos] ); + end; + +end; + +function NextPowerOfTwo(Value: Integer): Integer; +// tyty to Asphyre +begin + Result:= 1; + asm + xor ecx, ecx + bsr ecx, Value + inc ecx + shl Result, cl + end; +end; + +function LoadFont(FileName: PAnsiChar; PointSize: integer):PTTF_Font; +begin + if (FileExists(FileName)) then + begin + Result := TTF_OpenFont( FileName, PointSize ); + end + else + begin + Log.LogStatus('ERROR Could not find font in ' + FileName , ''); + ShowMessage( 'ERROR Could not find font in ' + FileName ); + end; +end; + +function RenderText(font: PTTF_Font; Text:PAnsiChar; Color: Cardinal): PSDL_Surface; +var + clr : TSDL_color; +begin + clr.r := ((Color and $ff0000) shr 16 ) div 255; + clr.g := ((Color and $ff00 ) shr 8 ) div 255; + clr.b := ( Color and $ff ) div 255 ; + + result := TTF_RenderText_Blended( font, text, cLr); +end; + +procedure printrandomtext(); +var + stext,intermediary : PSDL_surface; + clrFg, clrBG : TSDL_color; + texture : Gluint; + font : PTTF_Font; + w,h : integer; +begin + +font := LoadFont('fonts\comicbd.ttf', 42); + +clrFg.r := 255; +clrFg.g := 255; +clrFg.b := 255; +clrFg.unused := 255; + +clrBg.r := 255; +clrbg.g := 0; +clrbg.b := 255; +clrbg.unused := 0; + + sText := RenderText(font, 'katzeeeeeee', $fe198e); +//sText := TTF_RenderText_Blended( font, 'huuuuuuuuuund', clrFG); + + // Convert the rendered text to a known format + w := nextpoweroftwo(sText.w); + h := nextpoweroftwo(sText.h); + +intermediary := SDL_CreateRGBSurface(0, w, h, 32, + $000000ff, $0000ff00, $00ff0000, $ff000000); + + SDL_SetAlpha(intermediary, 0, 255); + SDL_SetAlpha(sText, 0, 255); + SDL_BlitSurface(sText, 0, intermediary, 0); + + glGenTextures(1, @texture); + + glBindTexture(GL_TEXTURE_2D, texture); + + glTexImage2D(GL_TEXTURE_2D, 0, 4, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, intermediary.pixels); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + + + + glEnable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glBindTexture(GL_TEXTURE_2D, texture); + glColor4f(1, 0, 1, 1); + + glbegin(gl_quads); + glTexCoord2f(0,0); glVertex2f(200, 300); + glTexCoord2f(0,sText.h/h); glVertex2f(200 , 300 + sText.h); + glTexCoord2f(sText.w/w,sText.h/h); glVertex2f(200 + sText.w, 300 + sText.h); + glTexCoord2f(sText.w/w,0); glVertex2f(200 + sText.w, 300); + glEnd; + glfinish(); + glDisable(GL_BLEND); + gldisable(gl_texture_2d); + + + + +SDL_FreeSurface( sText ); +SDL_FreeSurface( intermediary ); +glDeleteTextures(1, @texture); +TTF_CloseFont( font ); + +end; + +procedure glPrintCut(text: pchar); +var + Letter: char; + PToDo: real; + PTotWidth: real; + PDoingNow: real; + S: string; +begin + if (Text = '') then // If There's No Text + Exit; // Do Nothing + + PTotWidth := glTextWidth(Text); + PToDo := Fonts[ActFont].Done; + + while (length(text) > 0) do begin + // cut + Letter := Text[0]; + Text := pchar(Copy(Text, 2, Length(Text)-1)); + + // analyze + S := Letter; + PDoingNow := glTextWidth(pchar(S)) / PTotWidth; + + // drawing + if (PToDo > 0) and (PDoingNow <= PToDo) then + glPrintLetter(Letter); + + if (PToDo > 0) and (PDoingNow > PToDo) then begin + glPrintLetterCut(Letter, 0, PToDo / PDoingNow); + glColor3f(PColR, PColG, PColB); + glPrintLetterCut(Letter, PToDo / PDoingNow, 1); + end; + + if (PToDo <= 0) then + glPrintLetter(Letter); + + PToDo := PToDo - PDoingNow; + + end; // while +end; + + +procedure SetFontPos(X, Y: real); +begin + Fonts[ActFont].Tex.X := X; + Fonts[ActFont].Tex.Y := Y; +end; + +procedure SetFontSize(Size: real); +begin + Fonts[ActFont].Tex.H := 30 * (Size/10); +end; + +procedure SetFontStyle(Style: integer); +begin + ActFont := Style; +end; + +procedure SetFontItalic(Enable: boolean); +begin + Fonts[ActFont].Italic := Enable; +end; + +procedure SetFontAspectW(Aspect: real); +begin + Fonts[ActFont].AspectW := Aspect; +end; + + +{$IFDEF FPC} +{$IFDEF win32} +initialization + {$I UltraStar.lrs} +{$ENDIF} +{$ENDIF} + + +end. + + diff --git a/Game/Code/Classes/UCommon.pas b/Game/Code/Classes/UCommon.pas index 8089f28c..7337751a 100644 --- a/Game/Code/Classes/UCommon.pas +++ b/Game/Code/Classes/UCommon.pas @@ -1,158 +1,183 @@ -unit UCommon;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-uses
-{$IFDEF FPC}
- lResources,
-{$ENDIF}
- ULog,
-{$IFDEF win32}
- windows;
-{$ELSE}
- lcltype,
- messages;
-{$ENDIF}
-
-{$IFNDEF win32}
-type
- hStream = THandle;
- HGLRC = THandle;
- TLargeInteger = Int64;
- TWin32FindData = LongInt;
-{$ENDIF}
-
-{$IFDEF FPC}
-
-type
- TWndMethod = procedure(var Message: TMessage) of object;
-
-function LazFindResource( const aName, aType : String ): TLResource;
-
-function RandomRange(aMin: Integer; aMax: Integer) : Integer;
-
-function MaxValue(const Data: array of Double): Double;
-function MinValue(const Data: array of Double): Double;
-
-{$IFDEF Win32}
-function AllocateHWnd(Method: TWndMethod): HWND;
-procedure DeallocateHWnd(Wnd: HWND);
-{$ENDIF}
-
-{$ENDIF}
-
-{$IFNDEF win32}
-(*
- function QueryPerformanceCounter(lpPerformanceCount:TLARGEINTEGER):Bool;
- function QueryPerformanceFrequency(lpFrequency:TLARGEINTEGER):Bool;
-*)
- procedure ZeroMemory( Destination: Pointer; Length: DWORD );
-{$ENDIF}
-
-implementation
-
-{$IFNDEF win32}
-procedure ZeroMemory( Destination: Pointer; Length: DWORD );
-begin
- FillChar( Destination^, Length, 0 );
-end; //ZeroMemory
-
-(*
-function QueryPerformanceCounter(lpPerformanceCount:TLARGEINTEGER):Bool;
-
- // From http://en.wikipedia.org/wiki/RDTSC
- function RDTSC: Int64; register;
- asm
- rdtsc
- end;
-
-begin
- // Use clock_gettime here maybe ... from libc
- lpPerformanceCount := RDTSC();
- result := true;
-end;
-
-function QueryPerformanceFrequency(lpFrequency:TLARGEINTEGER):Bool;
-begin
- lpFrequency := 0;
- result := true;
-end;
-*)
-{$ENDIF}
-
-
-{$IFDEF FPC}
-
-function LazFindResource( const aName, aType : String ): TLResource;
-var
- iCount : Integer;
-begin
- result := nil;
-
- for iCount := 0 to LazarusResources.count -1 do
- begin
- if ( LazarusResources.items[ iCount ].Name = aName ) AND
- ( LazarusResources.items[ iCount ].ValueType = aType ) THEN
- begin
- result := LazarusResources.items[ iCount ];
- exit;
- end;
- end;
-end;
-
-function MaxValue(const Data: array of Double): Double;
-var
- I: Integer;
-begin
- Result := Data[Low(Data)];
- for I := Low(Data) + 1 to High(Data) do
- if Result < Data[I] then
- Result := Data[I];
-end;
-
-function MinValue(const Data: array of Double): Double;
-var
- I: Integer;
-begin
- Result := Data[Low(Data)];
- for I := Low(Data) + 1 to High(Data) do
- if Result > Data[I] then
- Result := Data[I];
-end;
-
-function RandomRange(aMin: Integer; aMax: Integer) : Integer;
-begin
-RandomRange := Random(aMax-aMin) + aMin ;
-end;
-
-
-// NOTE !!!!!!!!!!
-// AllocateHWnd is in lclintfh.inc
-
-{$IFDEF Win32}
-// TODO : JB this is dodgey and bad... find a REAL solution !
-function AllocateHWnd(Method: TWndMethod): HWND;
-var
- TempClass: TWndClass;
- ClassRegistered: Boolean;
-begin
- Result := CreateWindowEx(WS_EX_TOOLWINDOW, '', '', WS_POPUP , 0, 0, 0, 0, 0, 0, HInstance, nil);
-end;
-
-procedure DeallocateHWnd(Wnd: HWND);
-var
- Instance: Pointer;
-begin
- Instance := Pointer(GetWindowLong(Wnd, GWL_WNDPROC));
- DestroyWindow(Wnd);
-end;
-{$ENDIF}
-
-{$ENDIF}
-
-
-end.
+unit UCommon; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +uses + SysUtils, +{$IFDEF FPC} + lResources, +{$ENDIF} + ULog, +{$IFDEF win32} + windows; +{$ELSE} + lcltype, + messages; +{$ENDIF} + +{$IFNDEF win32} +type + hStream = THandle; + HGLRC = THandle; + TLargeInteger = Int64; + TWin32FindData = LongInt; +{$ENDIF} + +{$IFDEF FPC} + +type + TWndMethod = procedure(var Message: TMessage) of object; + +function StringReplaceW(text, search, rep: WideString):WideString; +function AdaptFilePaths( const aPath : widestring ): widestring; + +function LazFindResource( const aName, aType : String ): TLResource; + +function RandomRange(aMin: Integer; aMax: Integer) : Integer; + +function MaxValue(const Data: array of Double): Double; +function MinValue(const Data: array of Double): Double; + +{$IFDEF Win32} +function AllocateHWnd(Method: TWndMethod): HWND; +procedure DeallocateHWnd(Wnd: HWND); +{$ENDIF} + +{$ENDIF} + +{$IFNDEF win32} +(* + function QueryPerformanceCounter(lpPerformanceCount:TLARGEINTEGER):Bool; + function QueryPerformanceFrequency(lpFrequency:TLARGEINTEGER):Bool; +*) + procedure ZeroMemory( Destination: Pointer; Length: DWORD ); +{$ENDIF} + +implementation + +function StringReplaceW(text, search, rep: WideString):WideString; +var + iPos : integer; + sTemp : WideString; +begin + result := text; + iPos := Pos(search, result); + while (iPos > 0) do + begin + sTEmp := copy(result, iPos + length(search), length(result)); + result := copy(result, 1, iPos - 1) + rep + sTEmp; + iPos := Pos(search, result); + end; +end; + +function AdaptFilePaths( const aPath : widestring ): widestring; +begin + result := StringReplaceW( aPath, '\', PathDelim );//, [rfReplaceAll] ); +end; + + +{$IFNDEF win32} +procedure ZeroMemory( Destination: Pointer; Length: DWORD ); +begin + FillChar( Destination^, Length, 0 ); +end; //ZeroMemory + +(* +function QueryPerformanceCounter(lpPerformanceCount:TLARGEINTEGER):Bool; + + // From http://en.wikipedia.org/wiki/RDTSC + function RDTSC: Int64; register; + asm + rdtsc + end; + +begin + // Use clock_gettime here maybe ... from libc + lpPerformanceCount := RDTSC(); + result := true; +end; + +function QueryPerformanceFrequency(lpFrequency:TLARGEINTEGER):Bool; +begin + lpFrequency := 0; + result := true; +end; +*) +{$ENDIF} + + +{$IFDEF FPC} + +function LazFindResource( const aName, aType : String ): TLResource; +var + iCount : Integer; +begin + result := nil; + + for iCount := 0 to LazarusResources.count -1 do + begin + if ( LazarusResources.items[ iCount ].Name = aName ) AND + ( LazarusResources.items[ iCount ].ValueType = aType ) THEN + begin + result := LazarusResources.items[ iCount ]; + exit; + end; + end; +end; + +function MaxValue(const Data: array of Double): Double; +var + I: Integer; +begin + Result := Data[Low(Data)]; + for I := Low(Data) + 1 to High(Data) do + if Result < Data[I] then + Result := Data[I]; +end; + +function MinValue(const Data: array of Double): Double; +var + I: Integer; +begin + Result := Data[Low(Data)]; + for I := Low(Data) + 1 to High(Data) do + if Result > Data[I] then + Result := Data[I]; +end; + +function RandomRange(aMin: Integer; aMax: Integer) : Integer; +begin +RandomRange := Random(aMax-aMin) + aMin ; +end; + + +// NOTE !!!!!!!!!! +// AllocateHWnd is in lclintfh.inc + +{$IFDEF Win32} +// TODO : JB this is dodgey and bad... find a REAL solution ! +function AllocateHWnd(Method: TWndMethod): HWND; +var + TempClass: TWndClass; + ClassRegistered: Boolean; +begin + Result := CreateWindowEx(WS_EX_TOOLWINDOW, '', '', WS_POPUP , 0, 0, 0, 0, 0, 0, HInstance, nil); +end; + +procedure DeallocateHWnd(Wnd: HWND); +var + Instance: Pointer; +begin + Instance := Pointer(GetWindowLong(Wnd, GWL_WNDPROC)); + DestroyWindow(Wnd); +end; +{$ENDIF} + +{$ENDIF} + + +end. diff --git a/Game/Code/Classes/UGraphic.pas b/Game/Code/Classes/UGraphic.pas index 44c068a0..5847e41c 100644 --- a/Game/Code/Classes/UGraphic.pas +++ b/Game/Code/Classes/UGraphic.pas @@ -1,688 +1,703 @@ -unit UGraphic;
-
-interface
-
-{$I switches.inc}
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-uses
- SDL,
- OpenGL12,
- UTexture,
- TextGL,
- ULog,
- SysUtils,
- ULyrics,
- UScreenLoading,
- UScreenWelcome,
- UScreenMain,
- UScreenName,
- UScreenLevel,
- UScreenOptions,
- UScreenOptionsGame,
- UScreenOptionsGraphics,
- UScreenOptionsSound,
- UScreenOptionsLyrics,
- UScreenOptionsThemes,
- UScreenOptionsRecord,
- UScreenOptionsAdvanced,
- UScreenSong,
- UScreenSing,
- UScreenScore,
- UScreenTop5,
- UScreenEditSub,
- UScreenEdit,
- UScreenEditConvert,
- UScreenEditHeader,
- UScreenOpen,
- UThemes,
- USkins,
- UScreenSongMenu,
- UScreenSongJumpto,
- {Party Screens}
- UScreenSingModi,
- UScreenPartyNewRound,
- UScreenPartyScore,
- UScreenPartyOptions,
- UScreenPartyWin,
- UScreenPartyPlayer,
- {Stats Screens}
- UScreenStatMain,
- UScreenStatDetail,
- {CreditsScreen}
- UScreenCredits,
- {Popup for errors, etc.}
- UScreenPopup;
-
-type
- TRecR = record
- Top: real;
- Left: real;
- Right: real;
- Bottom: real;
- end;
-
-var
- Screen: PSDL_Surface;
- LoadingThread: PSDL_Thread;
- Mutex: PSDL_Mutex;
-
- RenderW: integer;
- RenderH: integer;
- ScreenW: integer;
- ScreenH: integer;
- Screens: integer;
- ScreenAct: integer;
- ScreenX: integer;
-
- ScreenLoading: TScreenLoading;
- ScreenWelcome: TScreenWelcome;
- ScreenMain: TScreenMain;
- ScreenName: TScreenName;
- ScreenLevel: TScreenLevel;
- ScreenSong: TScreenSong;
- ScreenSing: TScreenSing;
- ScreenScore: TScreenScore;
- ScreenTop5: TScreenTop5;
- ScreenOptions: TScreenOptions;
- ScreenOptionsGame: TScreenOptionsGame;
- ScreenOptionsGraphics: TScreenOptionsGraphics;
- ScreenOptionsSound: TScreenOptionsSound;
- ScreenOptionsLyrics: TScreenOptionsLyrics;
- ScreenOptionsThemes: TScreenOptionsThemes;
- ScreenOptionsRecord: TScreenOptionsRecord;
- ScreenOptionsAdvanced: TScreenOptionsAdvanced;
- ScreenEditSub: TScreenEditSub;
- ScreenEdit: TScreenEdit;
- ScreenEditConvert: TScreenEditConvert;
- ScreenEditHeader: TScreenEditHeader;
- ScreenOpen: TScreenOpen;
-
- ScreenSongMenu: TScreenSongMenu;
- ScreenSongJumpto: TScreenSongJumpto;
-
- //Party Screens
- ScreenSingModi: TScreenSingModi;
- ScreenPartyNewRound: TScreenPartyNewRound;
- ScreenPartyScore: TScreenPartyScore;
- ScreenPartyWin: TScreenPartyWin;
- ScreenPartyOptions: TScreenPartyOptions;
- ScreenPartyPlayer: TScreenPartyPlayer;
-
- //StatsScreens
- ScreenStatMain: TScreenStatMain;
- ScreenStatDetail: TScreenStatDetail;
-
- //CreditsScreen
- ScreenCredits: TScreenCredits;
-
- //popup mod
- ScreenPopupCheck: TScreenPopupCheck;
- ScreenPopupError: TScreenPopupError;
-
- //Notes
- Tex_Left: array[0..6] of TTexture; //rename to tex_note_left
- Tex_Mid: array[0..6] of TTexture; //rename to tex_note_mid
- Tex_Right: array[0..6] of TTexture; //rename to tex_note_right
-
- Tex_plain_Left: array[1..6] of TTexture; //rename to tex_notebg_left
- Tex_plain_Mid: array[1..6] of TTexture; //rename to tex_notebg_mid
- Tex_plain_Right: array[1..6] of TTexture; //rename to tex_notebg_right
-
- Tex_BG_Left: array[1..6] of TTexture; //rename to tex_noteglow_left
- Tex_BG_Mid: array[1..6] of TTexture; //rename to tex_noteglow_mid
- Tex_BG_Right: array[1..6] of TTexture; //rename to tex_noteglow_right
-
- Tex_Note_Star: TTexture;
- Tex_Note_Perfect_Star: TTexture;
-
-
- Tex_Ball: TTexture;
- Tex_Lyric_Help_Bar: TTexture;
- FullScreen: boolean;
-
- Tex_TimeProgress: TTexture;
-
- //Sing Bar Mod
- Tex_SingBar_Back: TTexture;
- Tex_SingBar_Bar: TTexture;
- Tex_SingBar_Front: TTexture;
- //end Singbar Mod
-
- //PhrasenBonus - Line Bonus Mod
- Tex_SingLineBonusBack: array[0..8] of TTexture;
- //End PhrasenBonus - Line Bonus Mod
-
- //ScoreBG Texs
- Tex_ScoreBG: array [0..5] of TTexture;
-
-const
- Skin_BGColorR = 1;
- Skin_BGColorG = 1;
- Skin_BGColorB = 1;
-
- Skin_SpectrumR = 0;
- Skin_SpectrumG = 0;
- Skin_SpectrumB = 0;
-
- Skin_Spectograph1R = 0.6;
- Skin_Spectograph1G = 0.8;
- Skin_Spectograph1B = 1;
-
- Skin_Spectograph2R = 0;
- Skin_Spectograph2G = 0;
- Skin_Spectograph2B = 0.2;
-
- Skin_SzczytR = 0.8;
- Skin_SzczytG = 0;
- Skin_SzczytB = 0;
-
- Skin_SzczytLimitR = 0;
- Skin_SzczytLimitG = 0.8;
- Skin_SzczytLimitB = 0;
-
- Skin_FontR = 0;
- Skin_FontG = 0;
- Skin_FontB = 0;
-
- Skin_FontHighlightR = 0.3; // 0.3
- Skin_FontHighlightG = 0.3; // 0.3
- Skin_FontHighlightB = 1; // 1
-
- Skin_TimeR = 0.25; //0,0,0
- Skin_TimeG = 0.25;
- Skin_TimeB = 0.25;
-
- Skin_OscR = 0;
- Skin_OscG = 0;
- Skin_OscB = 0;
-
- Skin_LyricsT = 494; // 500 / 510 / 400
- Skin_SpectrumT = 470;
- Skin_SpectrumBot = 570;
- Skin_SpectrumH = 100;
-
- Skin_P1_LinesR = 0.5; // 0.6 0.6 1
- Skin_P1_LinesG = 0.5;
- Skin_P1_LinesB = 0.5;
-
- Skin_P2_LinesR = 0.5; // 1 0.6 0.6
- Skin_P2_LinesG = 0.5;
- Skin_P2_LinesB = 0.5;
-
- Skin_P1_NotesB = 250;
- Skin_P2_NotesB = 430; // 430 / 300
-
- Skin_P1_ScoreT = 50;
- Skin_P1_ScoreL = 20;
-
- Skin_P2_ScoreT = 50;
- Skin_P2_ScoreL = 640;
-
-procedure Initialize3D (Title: string);
-procedure Reinitialize3D;
-procedure SwapBuffers;
-
-procedure LoadTextures;
-procedure InitializeScreen;
-procedure LoadLoadingScreen;
-procedure LoadScreens;
-
-function LoadingThreadFunction: integer;
-
-
-implementation
-
-uses UMain,
- UIni,
- UDisplay,
- UCommandLine,
- {$IFNDEF FPC}
- Graphics,
- {$ENDIF}
- {$IFDEF win32}
- windows,
- {$ENDIF}
- Classes;
-
-procedure LoadFontTextures;
-begin
- Log.LogStatus('Building Fonts', 'LoadTextures');
- BuildFont;
-end;
-
-procedure LoadTextures;
-
-
-var
- P: integer;
- R, G, B: real;
- Col: integer;
-begin
- // zaladowanie tekstur
- Log.LogStatus('Loading Textures', 'LoadTextures');
-
- Tex_Left[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayLeft')), 'BMP', 'Transparent', 0); //brauch man die noch?
- Tex_Mid[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayMid')), 'BMP', 'Plain', 0); //brauch man die noch?
- Tex_Right[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayRight')), 'BMP', 'Transparent', 0); //brauch man die noch?
-
- Log.LogStatus('Loading Textures - A', 'LoadTextures');
-
- // P1-6
- // TODO... do it once for each player... this is a bit crappy !!
- // can we make it any better !?
- for P := 1 to 6 do
- begin
- LoadColor(R, G, B, 'P' + IntToStr(P) + 'Light');
- Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
-
- Tex_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayLeft')), 'PNG', 'Colorized', Col);
- Tex_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayMid')), 'PNG', 'Colorized', Col);
- Tex_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayRight')), 'PNG', 'Colorized', Col);
-
- Tex_plain_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainLeft')), 'PNG', 'Colorized', Col);
- Tex_plain_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainMid')), 'PNG', 'Colorized', Col);
- Tex_plain_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainRight')), 'PNG', 'Colorized', Col);
-
- Tex_BG_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGLeft')), 'PNG', 'Colorized', Col);
- Tex_BG_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGMid')), 'PNG', 'Colorized', Col);
- Tex_BG_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGRight')), 'PNG', 'Colorized', Col);
- end;
-
- Log.LogStatus('Loading Textures - B', 'LoadTextures');
-
- Tex_Note_Perfect_Star := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePerfectStar')), 'JPG', 'Font Black', 0);
- Tex_Note_Star := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteStar')) , 'JPG', 'Alpha Black Colored', $FFFFFF);
- Tex_Ball := Texture.LoadTexture(pchar(Skin.GetTextureFileName('Ball')), 'BMP', 'Transparent', $FF00FF);
- Tex_Lyric_Help_Bar := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LyricHelpBar')), 'BMP', 'Transparent', $FF00FF);
-
-
- //TimeBar mod
- Tex_TimeProgress := Texture.LoadTexture(pchar(Skin.GetTextureFileName('TimeBar')));
- //eoa TimeBar mod
-
- //SingBar Mod
- Tex_SingBar_Back := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarBack')), 'JPG', 'Plain', 0);
- Tex_SingBar_Bar := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarBar')), 'JPG', 'Plain', 0);
- Tex_SingBar_Front := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarFront')), 'JPG', 'Font', 0);
- //end Singbar Mod
-
- Log.LogStatus('Loading Textures - C', 'LoadTextures');
-
- //Line Bonus PopUp
- for P := 0 to 8 do
- begin
- Case P of
- 0: begin
- R := 1;
- G := 0;
- B := 0;
- end;
- 1..3: begin
- R := 1;
- G := (P * 0.25);
- B := 0;
- end;
- 4: begin
- R := 1;
- G := 1;
- B := 0;
- end;
- 5..7: begin
- R := 1-((P-4)*0.25);
- G := 1;
- B := 0;
- end;
- 8: begin
- R := 0;
- G := 1;
- B := 0;
- end;
- End;
-
- Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
- Tex_SingLineBonusBack[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LineBonusBack')), 'PNG', 'Colorized', Col);
- end;
-
- //Score BG Textures
- for P := 0 to 5 do begin
- LoadColor(R, G, B, 'P' + IntToStr(P+1) + 'Light');
- Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255);
- Tex_ScoreBG[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreBG')), 'PNG', 'Colorized', Col);
- end;
-
- Log.LogStatus('Loading Textures - D', 'LoadTextures');
-end;
-
-procedure Initialize3D (Title: string);
-var
-// Icon: TIcon;
-// Res: TResourceStream;
- ISurface: PSDL_Surface;
- Pixel: PByteArray;
- I: Integer;
-begin
- Log.LogStatus('LoadOpenGL', 'UGraphic.Initialize3D');
-// Log.BenchmarkStart(2);
-
- LoadOpenGL;
-
- Log.LogStatus('SDL_Init', 'UGraphic.Initialize3D');
- if ( SDL_Init(SDL_INIT_VIDEO or SDL_INIT_AUDIO)= -1 ) then
- begin
- Log.LogError('SDL_Init Failed', 'UGraphic.Initialize3D');
- exit;
- end;
-
- { //Load Icon
- Res := TResourceStream.CreateFromID(HInstance, 3, RT_ICON);
- Icon := TIcon.Create;
- Icon.LoadFromStream(Res);
- Res.Free;
- Icon.
- //Create icon Surface
- SDL_CreateRGBSurfaceFrom (
- SDL_SWSURFACE,
- Icon.Width,
- Icon.Height,
- 32,
- 128 or 64,
- 32 or 16,
- 8 or 4,
- 2 or 1);
- //SDL_BlitSurface(
-
-
- SDL_WM_SetIcon(SDL_LoadBMP('DEFAULT_WINDOW_ICON'), 0); //}
-
- SDL_WM_SetCaption(PChar(Title), nil);
-
- InitializeScreen;
-
-// Log.BenchmarkEnd(2);
-// Log.LogBenchmark('--> Setting Screen', 2);
-
- // ladowanie tekstur
-// Log.BenchmarkStart(2);
- Texture := TTextureUnit.Create;
- Texture.Limit := 1024*1024;
-
-// LoadTextures;
-// Log.BenchmarkEnd(2);
-// Log.LogBenchmark('--> Loading Textures', 2);
-
-{ Log.BenchmarkStart(2);
- Lyric:= TLyric.Create;
- Log.BenchmarkEnd(2);
- Log.LogBenchmark('--> Loading Fonts', 2);
-}
-
-// Log.BenchmarkStart(2);
- Display := TDisplay.Create;
- SDL_EnableUnicode(1);
-// Log.BenchmarkEnd(2); Log.LogBenchmark('====> Creating Display', 2);
-
-// Log.LogStatus('Loading Screens', 'Initialize3D');
-// Log.BenchmarkStart(3);
-
- Log.LogStatus('Loading Font Textures', 'UGraphic.Initialize3D');
- LoadFontTextures();
-
- // Show the Loading Screen -------------
- Log.LogStatus('Loading Loading Screen', 'UGraphic.Initialize3D');
- LoadLoadingScreen;
-
-
- Log.LogStatus(' Loading Textures', 'UGraphic.Initialize3D');
- LoadTextures; // jb
-
-
-
- // now that we have something to display while loading,
- // start thread that loads the rest of ultrastar
-// Mutex := SDL_CreateMutex;
-// SDL_UnLockMutex(Mutex);
-
- // funktioniert so noch nicht, da der ladethread unverändert auf opengl zugreifen will
- // siehe dazu kommentar unten
- //LoadingThread := SDL_CreateThread(@LoadingThread, nil);
-
- // das hier würde dann im ladethread ausgeführt
- Log.LogStatus(' Loading Screens', 'UGraphic.Initialize3D');
- LoadScreens;
-
-
- // TODO!!!!!!1
- // hier käme jetzt eine schleife, die
- // * den ladescreen malt (ab und zu)
- // * den "fortschritt" des ladescreens steuert
- // * zwischendrin schaut, ob der ladethread texturen geladen hat (mutex prüfen) und
- // * die texturen in die opengl lädt, sowie
- // * dem ladethread signalisiert, dass der speicher für die textur
- // zum laden der nächsten textur weiterverwendet werden kann (über weiteren mutex)
- // * über einen 3. mutex so lange läuft, bis der ladethread signalisiert,
- // dass er alles geladen hat fertig ist
- //
- // dafür muss loadtexture so umgeschrieben werden, dass es, statt selbst irgendwelche
- // opengl funktionen aufzurufen, entsprechend mutexe verändert
- // der hauptthread muss auch irgendwoher erfahren, was an opengl funktionen auszuführen ist,
- // mit welchen parametern (texturtyp, entspr. texturobjekt, textur-zwischenspeicher-adresse, ...
-
-
- //wait for loading thread to finish
- // funktioniert so auch noch nicht
- //SDL_WaitThread(LoadingThread, I);
-// SDL_DestroyMutex(Mutex);
-
- Display.ActualScreen^.FadeTo( @ScreenMain );
-
- Log.BenchmarkEnd(2);
- Log.LogBenchmark('--> Loading Screens', 2);
-
- Log.LogStatus('Finish', 'Initialize3D');
-end;
-
-procedure SwapBuffers;
-begin
- SDL_GL_SwapBuffers;
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity;
- glOrtho(0, RenderW, RenderH, 0, -1, 100);
- glMatrixMode(GL_MODELVIEW);
-end;
-
-procedure Reinitialize3D;
-begin
-// InitializeScreen;
-// LoadTextures;
-// LoadScreens;
-end;
-
-procedure InitializeScreen;
-var
- S: string;
- I: integer;
- W, H: integer;
- Depth: Integer;
-begin
- if (Params.Screens <> -1) then
- Screens := Params.Screens + 1
- else
- Screens := Ini.Screens + 1;
-
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-
- // If there is a resolution in Parameters, use it, else use the Ini value
- I := Params.Resolution;
- if (I <> -1) then
- S := IResolution[I]
- else
- S := IResolution[Ini.Resolution];
-
- I := Pos('x', S);
- W := StrToInt(Copy(S, 1, I-1)) * Screens;
- H := StrToInt(Copy(S, I+1, 1000));
-
- {if ParamStr(1) = '-fsblack' then begin
- W := 800;
- H := 600;
- end;
- if ParamStr(1) = '-320x240' then begin
- W := 320;
- H := 240;
- end; }
-
- If (Params.Depth <> -1) then
- Depth := Params.Depth
- else
- Depth := Ini.Depth;
-
-
- Log.LogStatus('SDL_SetVideoMode', 'Initialize3D');
-
-// Okay it's possible to set the title bar / taskbar icon here
-// it's working this way, but just if the bmp is in your exe folder
- SDL_WM_SetIcon(SDL_LoadBMP('ustar-icon.bmp'), 0);
-
-// SDL_SetRefreshrate(85);
-// SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
- if (Ini.FullScreen = 0) and (Not Params.FullScreen) then
- begin
- screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL)
- end
- else
- begin
- screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN);
- SDL_ShowCursor(0);
- end;
-
- if (screen = nil) then
- begin
- Log.LogError('SDL_SetVideoMode Failed', 'Initialize3D');
- exit;
- end;
-
- // clear screen once window is being shown
- glClearColor(1, 1, 1, 1);
- glClear(GL_COLOR_BUFFER_BIT);
- SwapBuffers;
-
- // zmienne
- RenderW := 800;
- RenderH := 600;
- ScreenW := W;
- ScreenH := H;
-end;
-
-procedure LoadLoadingScreen;
-begin
- ScreenLoading := TScreenLoading.Create;
- ScreenLoading.onShow;
-
- Display.ActualScreen := @ScreenLoading;
-
- swapbuffers;
-
- ScreenLoading.Draw;
- Display.Draw;
-
- SwapBuffers;
-end;
-
-procedure LoadScreens;
-begin
-{ ScreenLoading := TScreenLoading.Create;
- ScreenLoading.onShow;
- Display.ActualScreen := @ScreenLoading;
- ScreenLoading.Draw;
- Display.Draw;
- SwapBuffers;
-}
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Loading', 3); Log.BenchmarkStart(3);
-{ ScreenWelcome := TScreenWelcome.Create; //'BG', 4, 3);
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Welcome', 3); Log.BenchmarkStart(3);}
- ScreenMain := TScreenMain.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Main', 3); Log.BenchmarkStart(3);
- ScreenName := TScreenName.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Name', 3); Log.BenchmarkStart(3);
- ScreenLevel := TScreenLevel.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Level', 3); Log.BenchmarkStart(3);
- ScreenSong := TScreenSong.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song', 3); Log.BenchmarkStart(3);
- ScreenSongMenu := TScreenSongMenu.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song Menu', 3); Log.BenchmarkStart(3);
- ScreenSing := TScreenSing.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing', 3); Log.BenchmarkStart(3);
- ScreenScore := TScreenScore.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Score', 3); Log.BenchmarkStart(3);
- ScreenTop5 := TScreenTop5.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Top5', 3); Log.BenchmarkStart(3);
- ScreenOptions := TScreenOptions.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options', 3); Log.BenchmarkStart(3);
- ScreenOptionsGame := TScreenOptionsGame.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Game', 3); Log.BenchmarkStart(3);
- ScreenOptionsGraphics := TScreenOptionsGraphics.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Graphics', 3); Log.BenchmarkStart(3);
- ScreenOptionsSound := TScreenOptionsSound.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Sound', 3); Log.BenchmarkStart(3);
- ScreenOptionsLyrics := TScreenOptionsLyrics.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Lyrics', 3); Log.BenchmarkStart(3);
- ScreenOptionsThemes := TScreenOptionsThemes.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Themes', 3); Log.BenchmarkStart(3);
- ScreenOptionsRecord := TScreenOptionsRecord.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Record', 3); Log.BenchmarkStart(3);
- ScreenOptionsAdvanced := TScreenOptionsAdvanced.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Advanced', 3); Log.BenchmarkStart(3);
- ScreenEditSub := TScreenEditSub.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Sub', 3); Log.BenchmarkStart(3);
- ScreenEdit := TScreenEdit.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit', 3); Log.BenchmarkStart(3);
- ScreenEditConvert := TScreenEditConvert.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen EditConvert', 3); Log.BenchmarkStart(3);
-// ScreenEditHeader := TScreenEditHeader.Create(Skin.ScoreBG);
-// Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Header', 3); Log.BenchmarkStart(3);
- ScreenOpen := TScreenOpen.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Open', 3); Log.BenchmarkStart(3);
- ScreenSingModi := TScreenSingModi.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing with Modi support', 3); Log.BenchmarkStart(3);
- ScreenSongMenu := TScreenSongMenu.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongMenu', 3); Log.BenchmarkStart(3);
- ScreenSongJumpto := TScreenSongJumpto.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongJumpto', 3); Log.BenchmarkStart(3);
- ScreenPopupCheck := TScreenPopupCheck.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Check)', 3); Log.BenchmarkStart(3);
- ScreenPopupError := TScreenPopupError.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Error)', 3); Log.BenchmarkStart(3);
- ScreenPartyNewRound := TScreenPartyNewRound.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyNewRound', 3); Log.BenchmarkStart(3);
- ScreenPartyScore := TScreenPartyScore.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyScore', 3); Log.BenchmarkStart(3);
- ScreenPartyWin := TScreenPartyWin.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyWin', 3); Log.BenchmarkStart(3);
- ScreenPartyOptions := TScreenPartyOptions.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyOptions', 3); Log.BenchmarkStart(3);
- ScreenPartyPlayer := TScreenPartyPlayer.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyPlayer', 3); Log.BenchmarkStart(3);
- ScreenStatMain := TScreenStatMain.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Main', 3); Log.BenchmarkStart(3);
- ScreenStatDetail := TScreenStatDetail.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Detail', 3); Log.BenchmarkStart(3);
- ScreenCredits := TScreenCredits.Create;
- Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Credits', 3); Log.BenchmarkStart(3);
-
- end;
-
-function LoadingThreadFunction: integer;
-begin
- LoadScreens;
- Result:= 1;
-end;
-
-end.
+unit UGraphic; + +interface + +{$I switches.inc} + +{$IFDEF FPC} + {$MODE DELPHI} +{$ENDIF} + +uses + SDL, + OpenGL12, + UTexture, + TextGL, + ULog, + SysUtils, + ULyrics, + UScreenLoading, + UScreenWelcome, + UScreenMain, + UScreenName, + UScreenLevel, + UScreenOptions, + UScreenOptionsGame, + UScreenOptionsGraphics, + UScreenOptionsSound, + UScreenOptionsLyrics, + UScreenOptionsThemes, + UScreenOptionsRecord, + UScreenOptionsAdvanced, + UScreenSong, + UScreenSing, + UScreenScore, + UScreenTop5, + UScreenEditSub, + UScreenEdit, + UScreenEditConvert, + UScreenEditHeader, + UScreenOpen, + UThemes, + USkins, + UScreenSongMenu, + UScreenSongJumpto, + {Party Screens} + UScreenSingModi, + UScreenPartyNewRound, + UScreenPartyScore, + UScreenPartyOptions, + UScreenPartyWin, + UScreenPartyPlayer, + {Stats Screens} + UScreenStatMain, + UScreenStatDetail, + {CreditsScreen} + UScreenCredits, + {Popup for errors, etc.} + UScreenPopup; + +type + TRecR = record + Top: real; + Left: real; + Right: real; + Bottom: real; + end; + +var + Screen: PSDL_Surface; + LoadingThread: PSDL_Thread; + Mutex: PSDL_Mutex; + + RenderW: integer; + RenderH: integer; + ScreenW: integer; + ScreenH: integer; + Screens: integer; + ScreenAct: integer; + ScreenX: integer; + + ScreenLoading: TScreenLoading; + ScreenWelcome: TScreenWelcome; + ScreenMain: TScreenMain; + ScreenName: TScreenName; + ScreenLevel: TScreenLevel; + ScreenSong: TScreenSong; + ScreenSing: TScreenSing; + ScreenScore: TScreenScore; + ScreenTop5: TScreenTop5; + ScreenOptions: TScreenOptions; + ScreenOptionsGame: TScreenOptionsGame; + ScreenOptionsGraphics: TScreenOptionsGraphics; + ScreenOptionsSound: TScreenOptionsSound; + ScreenOptionsLyrics: TScreenOptionsLyrics; + ScreenOptionsThemes: TScreenOptionsThemes; + ScreenOptionsRecord: TScreenOptionsRecord; + ScreenOptionsAdvanced: TScreenOptionsAdvanced; + ScreenEditSub: TScreenEditSub; + ScreenEdit: TScreenEdit; + ScreenEditConvert: TScreenEditConvert; + ScreenEditHeader: TScreenEditHeader; + ScreenOpen: TScreenOpen; + + ScreenSongMenu: TScreenSongMenu; + ScreenSongJumpto: TScreenSongJumpto; + + //Party Screens + ScreenSingModi: TScreenSingModi; + ScreenPartyNewRound: TScreenPartyNewRound; + ScreenPartyScore: TScreenPartyScore; + ScreenPartyWin: TScreenPartyWin; + ScreenPartyOptions: TScreenPartyOptions; + ScreenPartyPlayer: TScreenPartyPlayer; + + //StatsScreens + ScreenStatMain: TScreenStatMain; + ScreenStatDetail: TScreenStatDetail; + + //CreditsScreen + ScreenCredits: TScreenCredits; + + //popup mod + ScreenPopupCheck: TScreenPopupCheck; + ScreenPopupError: TScreenPopupError; + + //Notes + Tex_Left: array[0..6] of TTexture; //rename to tex_note_left + Tex_Mid: array[0..6] of TTexture; //rename to tex_note_mid + Tex_Right: array[0..6] of TTexture; //rename to tex_note_right + + Tex_plain_Left: array[1..6] of TTexture; //rename to tex_notebg_left + Tex_plain_Mid: array[1..6] of TTexture; //rename to tex_notebg_mid + Tex_plain_Right: array[1..6] of TTexture; //rename to tex_notebg_right + + Tex_BG_Left: array[1..6] of TTexture; //rename to tex_noteglow_left + Tex_BG_Mid: array[1..6] of TTexture; //rename to tex_noteglow_mid + Tex_BG_Right: array[1..6] of TTexture; //rename to tex_noteglow_right + + Tex_Note_Star: TTexture; + Tex_Note_Perfect_Star: TTexture; + + + Tex_Ball: TTexture; + Tex_Lyric_Help_Bar: TTexture; + FullScreen: boolean; + + Tex_TimeProgress: TTexture; + + //Sing Bar Mod + Tex_SingBar_Back: TTexture; + Tex_SingBar_Bar: TTexture; + Tex_SingBar_Front: TTexture; + //end Singbar Mod + + //PhrasenBonus - Line Bonus Mod + Tex_SingLineBonusBack: array[0..8] of TTexture; + //End PhrasenBonus - Line Bonus Mod + + //ScoreBG Texs + Tex_ScoreBG: array [0..5] of TTexture; + +const + Skin_BGColorR = 1; + Skin_BGColorG = 1; + Skin_BGColorB = 1; + + Skin_SpectrumR = 0; + Skin_SpectrumG = 0; + Skin_SpectrumB = 0; + + Skin_Spectograph1R = 0.6; + Skin_Spectograph1G = 0.8; + Skin_Spectograph1B = 1; + + Skin_Spectograph2R = 0; + Skin_Spectograph2G = 0; + Skin_Spectograph2B = 0.2; + + Skin_SzczytR = 0.8; + Skin_SzczytG = 0; + Skin_SzczytB = 0; + + Skin_SzczytLimitR = 0; + Skin_SzczytLimitG = 0.8; + Skin_SzczytLimitB = 0; + + Skin_FontR = 0; + Skin_FontG = 0; + Skin_FontB = 0; + + Skin_FontHighlightR = 0.3; // 0.3 + Skin_FontHighlightG = 0.3; // 0.3 + Skin_FontHighlightB = 1; // 1 + + Skin_TimeR = 0.25; //0,0,0 + Skin_TimeG = 0.25; + Skin_TimeB = 0.25; + + Skin_OscR = 0; + Skin_OscG = 0; + Skin_OscB = 0; + + Skin_LyricsT = 494; // 500 / 510 / 400 + Skin_SpectrumT = 470; + Skin_SpectrumBot = 570; + Skin_SpectrumH = 100; + + Skin_P1_LinesR = 0.5; // 0.6 0.6 1 + Skin_P1_LinesG = 0.5; + Skin_P1_LinesB = 0.5; + + Skin_P2_LinesR = 0.5; // 1 0.6 0.6 + Skin_P2_LinesG = 0.5; + Skin_P2_LinesB = 0.5; + + Skin_P1_NotesB = 250; + Skin_P2_NotesB = 430; // 430 / 300 + + Skin_P1_ScoreT = 50; + Skin_P1_ScoreL = 20; + + Skin_P2_ScoreT = 50; + Skin_P2_ScoreL = 640; + +procedure Initialize3D (Title: string); +procedure Reinitialize3D; +procedure SwapBuffers; + +procedure LoadTextures; +procedure InitializeScreen; +procedure LoadLoadingScreen; +procedure LoadScreens; + +function LoadingThreadFunction: integer; + + +implementation + +uses UMain, + UIni, + UDisplay, + UCommandLine, + {$IFNDEF FPC} + Graphics, + {$ENDIF} + {$IFDEF win32} + windows, + {$ENDIF} + Classes; + +procedure LoadFontTextures; +begin + Log.LogStatus('Building Fonts', 'LoadTextures'); + BuildFont; +end; + +procedure LoadTextures; + + +var + P: integer; + R, G, B: real; + Col: integer; +begin + // zaladowanie tekstur + Log.LogStatus('Loading Textures', 'LoadTextures'); + + Tex_Left[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayLeft')), 'BMP', 'Transparent', 0); //brauch man die noch? + Tex_Mid[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayMid')), 'BMP', 'Plain', 0); //brauch man die noch? + Tex_Right[0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayRight')), 'BMP', 'Transparent', 0); //brauch man die noch? + + Log.LogStatus('Loading Textures - A', 'LoadTextures'); + + // P1-6 + // TODO... do it once for each player... this is a bit crappy !! + // can we make it any better !? + for P := 1 to 6 do + begin + LoadColor(R, G, B, 'P' + IntToStr(P) + 'Light'); + Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255); + + Tex_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayLeft')), 'PNG', 'Colorized', Col); + Tex_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayMid')), 'PNG', 'Colorized', Col); + Tex_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('GrayRight')), 'PNG', 'Colorized', Col); + + Tex_plain_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainLeft')), 'PNG', 'Colorized', Col); + Tex_plain_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainMid')), 'PNG', 'Colorized', Col); + Tex_plain_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePlainRight')), 'PNG', 'Colorized', Col); + + Tex_BG_Left[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGLeft')), 'PNG', 'Colorized', Col); + Tex_BG_Mid[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGMid')), 'PNG', 'Colorized', Col); + Tex_BG_Right[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteBGRight')), 'PNG', 'Colorized', Col); + end; + + Log.LogStatus('Loading Textures - B', 'LoadTextures'); + + Tex_Note_Perfect_Star := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NotePerfectStar')), 'JPG', 'Font Black', 0); + Tex_Note_Star := Texture.LoadTexture(pchar(Skin.GetTextureFileName('NoteStar')) , 'JPG', 'Alpha Black Colored', $FFFFFF); + Tex_Ball := Texture.LoadTexture(pchar(Skin.GetTextureFileName('Ball')), 'BMP', 'Transparent', $FF00FF); + Tex_Lyric_Help_Bar := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LyricHelpBar')), 'BMP', 'Transparent', $FF00FF); + + + //TimeBar mod + Tex_TimeProgress := Texture.LoadTexture(pchar(Skin.GetTextureFileName('TimeBar'))); + //eoa TimeBar mod + + //SingBar Mod + Tex_SingBar_Back := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarBack')), 'JPG', 'Plain', 0); + Tex_SingBar_Bar := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarBar')), 'JPG', 'Plain', 0); + Tex_SingBar_Front := Texture.LoadTexture(pchar(Skin.GetTextureFileName('SingBarFront')), 'JPG', 'Font', 0); + //end Singbar Mod + + Log.LogStatus('Loading Textures - C', 'LoadTextures'); + + //Line Bonus PopUp + for P := 0 to 8 do + begin + Case P of + 0: begin + R := 1; + G := 0; + B := 0; + end; + 1..3: begin + R := 1; + G := (P * 0.25); + B := 0; + end; + 4: begin + R := 1; + G := 1; + B := 0; + end; + 5..7: begin + R := 1-((P-4)*0.25); + G := 1; + B := 0; + end; + 8: begin + R := 0; + G := 1; + B := 0; + end; + End; + + Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255); + Tex_SingLineBonusBack[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LineBonusBack')), 'PNG', 'Colorized', Col); + end; + + //Score BG Textures + for P := 0 to 5 do begin + LoadColor(R, G, B, 'P' + IntToStr(P+1) + 'Light'); + Col := $10000 * Round(R*255) + $100 * Round(G*255) + Round(B*255); + Tex_ScoreBG[P] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('ScoreBG')), 'PNG', 'Colorized', Col); + end; + + Log.LogStatus('Loading Textures - D', 'LoadTextures'); +end; + +procedure Initialize3D (Title: string); +var +// Icon: TIcon; +// Res: TResourceStream; + ISurface: PSDL_Surface; + Pixel: PByteArray; + I: Integer; +begin + Log.LogStatus('LoadOpenGL', 'UGraphic.Initialize3D'); +// Log.BenchmarkStart(2); + + LoadOpenGL; + + Log.LogStatus('SDL_Init', 'UGraphic.Initialize3D'); + if ( SDL_Init(SDL_INIT_VIDEO or SDL_INIT_AUDIO)= -1 ) then + begin + Log.LogError('SDL_Init Failed', 'UGraphic.Initialize3D'); + exit; + end; + + { //Load Icon + Res := TResourceStream.CreateFromID(HInstance, 3, RT_ICON); + Icon := TIcon.Create; + Icon.LoadFromStream(Res); + Res.Free; + Icon. + //Create icon Surface + SDL_CreateRGBSurfaceFrom ( + SDL_SWSURFACE, + Icon.Width, + Icon.Height, + 32, + 128 or 64, + 32 or 16, + 8 or 4, + 2 or 1); + //SDL_BlitSurface( + + + SDL_WM_SetIcon(SDL_LoadBMP('DEFAULT_WINDOW_ICON'), 0); //} + + SDL_WM_SetCaption(PChar(Title), nil); + + InitializeScreen; + +// Log.BenchmarkEnd(2); +// Log.LogBenchmark('--> Setting Screen', 2); + + // ladowanie tekstur +// Log.BenchmarkStart(2); + Texture := TTextureUnit.Create; + Texture.Limit := 1024*1024; + +// LoadTextures; +// Log.BenchmarkEnd(2); +// Log.LogBenchmark('--> Loading Textures', 2); + +{ Log.BenchmarkStart(2); + Lyric:= TLyric.Create; + Log.BenchmarkEnd(2); + Log.LogBenchmark('--> Loading Fonts', 2); +} + +// Log.BenchmarkStart(2); + + Log.LogStatus('TDisplay.Create', 'UGraphic.Initialize3D'); + Display := TDisplay.Create; + + Log.LogStatus('SDL_EnableUnicode', 'UGraphic.Initialize3D'); + SDL_EnableUnicode(1); +// Log.BenchmarkEnd(2); Log.LogBenchmark('====> Creating Display', 2); + +// Log.LogStatus('Loading Screens', 'Initialize3D'); +// Log.BenchmarkStart(3); + + Log.LogStatus('Loading Font Textures', 'UGraphic.Initialize3D'); + LoadFontTextures(); + + // Show the Loading Screen ------------- + Log.LogStatus('Loading Loading Screen', 'UGraphic.Initialize3D'); + LoadLoadingScreen; + + + Log.LogStatus(' Loading Textures', 'UGraphic.Initialize3D'); + LoadTextures; // jb + + + + // now that we have something to display while loading, + // start thread that loads the rest of ultrastar +// Mutex := SDL_CreateMutex; +// SDL_UnLockMutex(Mutex); + + // funktioniert so noch nicht, da der ladethread unverändert auf opengl zugreifen will + // siehe dazu kommentar unten + //LoadingThread := SDL_CreateThread(@LoadingThread, nil); + + // das hier würde dann im ladethread ausgeführt + Log.LogStatus(' Loading Screens', 'UGraphic.Initialize3D'); + LoadScreens; + + + // TODO!!!!!!1 + // hier käme jetzt eine schleife, die + // * den ladescreen malt (ab und zu) + // * den "fortschritt" des ladescreens steuert + // * zwischendrin schaut, ob der ladethread texturen geladen hat (mutex prüfen) und + // * die texturen in die opengl lädt, sowie + // * dem ladethread signalisiert, dass der speicher für die textur + // zum laden der nächsten textur weiterverwendet werden kann (über weiteren mutex) + // * über einen 3. mutex so lange läuft, bis der ladethread signalisiert, + // dass er alles geladen hat fertig ist + // + // dafür muss loadtexture so umgeschrieben werden, dass es, statt selbst irgendwelche + // opengl funktionen aufzurufen, entsprechend mutexe verändert + // der hauptthread muss auch irgendwoher erfahren, was an opengl funktionen auszuführen ist, + // mit welchen parametern (texturtyp, entspr. texturobjekt, textur-zwischenspeicher-adresse, ... + + + //wait for loading thread to finish + // funktioniert so auch noch nicht + //SDL_WaitThread(LoadingThread, I); +// SDL_DestroyMutex(Mutex); + + Display.ActualScreen^.FadeTo( @ScreenMain ); + + Log.BenchmarkEnd(2); + Log.LogBenchmark('--> Loading Screens', 2); + + Log.LogStatus('Finish', 'Initialize3D'); +end; + +procedure SwapBuffers; +begin + SDL_GL_SwapBuffers; + glMatrixMode(GL_PROJECTION); + glLoadIdentity; + glOrtho(0, RenderW, RenderH, 0, -1, 100); + glMatrixMode(GL_MODELVIEW); +end; + +procedure Reinitialize3D; +begin +// InitializeScreen; +// LoadTextures; +// LoadScreens; +end; + +procedure InitializeScreen; +var + S: string; + I: integer; + W, H: integer; + Depth: Integer; +begin + if (Params.Screens <> -1) then + Screens := Params.Screens + 1 + else + Screens := Ini.Screens + 1; + + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + + // If there is a resolution in Parameters, use it, else use the Ini value + I := Params.Resolution; + if (I <> -1) then + S := IResolution[I] + else + S := IResolution[Ini.Resolution]; + + I := Pos('x', S); + W := StrToInt(Copy(S, 1, I-1)) * Screens; + H := StrToInt(Copy(S, I+1, 1000)); + + {if ParamStr(1) = '-fsblack' then begin + W := 800; + H := 600; + end; + if ParamStr(1) = '-320x240' then begin + W := 320; + H := 240; + end; } + + If (Params.Depth <> -1) then + Depth := Params.Depth + else + Depth := Ini.Depth; + + + Log.LogStatus('SDL_SetVideoMode', 'Set Window Icon'); + +// Okay it's possible to set the title bar / taskbar icon here +// it's working this way, but just if the bmp is in your exe folder + SDL_WM_SetIcon(SDL_LoadBMP('ustar-icon.bmp'), 0); + + Log.LogStatus('SDL_SetVideoMode', 'Initialize3D'); +// SDL_SetRefreshrate(85); +// SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 ); + + {$ifndef win32} + // Todo : jb_linux remove this for linux... but helps for debugging + Ini.FullScreen := 0; + W := 800; + H := 600; + {$endif} + + if (Ini.FullScreen = 0) and (Not Params.FullScreen) then + begin + Log.LogStatus('SDL_SetVideoMode', 'Set Video Mode... Windowed'); + screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL) + end + else + begin + Log.LogStatus('SDL_SetVideoMode', 'Set Video Mode... Full Screen'); + screen := SDL_SetVideoMode(W, H, (Depth+1) * 16, SDL_OPENGL or SDL_FULLSCREEN); + SDL_ShowCursor(0); + end; + + if (screen = nil) then + begin + Log.LogError('SDL_SetVideoMode Failed', 'Initialize3D'); + exit; + end; + + // clear screen once window is being shown + glClearColor(1, 1, 1, 1); + glClear(GL_COLOR_BUFFER_BIT); + SwapBuffers; + + // zmienne + RenderW := 800; + RenderH := 600; + ScreenW := W; + ScreenH := H; +end; + +procedure LoadLoadingScreen; +begin + ScreenLoading := TScreenLoading.Create; + ScreenLoading.onShow; + + Display.ActualScreen := @ScreenLoading; + + swapbuffers; + + ScreenLoading.Draw; + Display.Draw; + + SwapBuffers; +end; + +procedure LoadScreens; +begin +{ ScreenLoading := TScreenLoading.Create; + ScreenLoading.onShow; + Display.ActualScreen := @ScreenLoading; + ScreenLoading.Draw; + Display.Draw; + SwapBuffers; +} + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Loading', 3); Log.BenchmarkStart(3); +{ ScreenWelcome := TScreenWelcome.Create; //'BG', 4, 3); + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Welcome', 3); Log.BenchmarkStart(3);} + ScreenMain := TScreenMain.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Main', 3); Log.BenchmarkStart(3); + ScreenName := TScreenName.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Name', 3); Log.BenchmarkStart(3); + ScreenLevel := TScreenLevel.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Level', 3); Log.BenchmarkStart(3); + ScreenSong := TScreenSong.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song', 3); Log.BenchmarkStart(3); + ScreenSongMenu := TScreenSongMenu.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Song Menu', 3); Log.BenchmarkStart(3); + ScreenSing := TScreenSing.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing', 3); Log.BenchmarkStart(3); + ScreenScore := TScreenScore.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Score', 3); Log.BenchmarkStart(3); + ScreenTop5 := TScreenTop5.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Top5', 3); Log.BenchmarkStart(3); + ScreenOptions := TScreenOptions.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options', 3); Log.BenchmarkStart(3); + ScreenOptionsGame := TScreenOptionsGame.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Game', 3); Log.BenchmarkStart(3); + ScreenOptionsGraphics := TScreenOptionsGraphics.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Graphics', 3); Log.BenchmarkStart(3); + ScreenOptionsSound := TScreenOptionsSound.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Sound', 3); Log.BenchmarkStart(3); + ScreenOptionsLyrics := TScreenOptionsLyrics.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Lyrics', 3); Log.BenchmarkStart(3); + ScreenOptionsThemes := TScreenOptionsThemes.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Themes', 3); Log.BenchmarkStart(3); + ScreenOptionsRecord := TScreenOptionsRecord.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Record', 3); Log.BenchmarkStart(3); + ScreenOptionsAdvanced := TScreenOptionsAdvanced.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Options Advanced', 3); Log.BenchmarkStart(3); + ScreenEditSub := TScreenEditSub.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Sub', 3); Log.BenchmarkStart(3); + ScreenEdit := TScreenEdit.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit', 3); Log.BenchmarkStart(3); + ScreenEditConvert := TScreenEditConvert.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen EditConvert', 3); Log.BenchmarkStart(3); +// ScreenEditHeader := TScreenEditHeader.Create(Skin.ScoreBG); +// Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Edit Header', 3); Log.BenchmarkStart(3); + ScreenOpen := TScreenOpen.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Open', 3); Log.BenchmarkStart(3); + ScreenSingModi := TScreenSingModi.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Sing with Modi support', 3); Log.BenchmarkStart(3); + ScreenSongMenu := TScreenSongMenu.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongMenu', 3); Log.BenchmarkStart(3); + ScreenSongJumpto := TScreenSongJumpto.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen SongJumpto', 3); Log.BenchmarkStart(3); + ScreenPopupCheck := TScreenPopupCheck.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Check)', 3); Log.BenchmarkStart(3); + ScreenPopupError := TScreenPopupError.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Popup (Error)', 3); Log.BenchmarkStart(3); + ScreenPartyNewRound := TScreenPartyNewRound.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyNewRound', 3); Log.BenchmarkStart(3); + ScreenPartyScore := TScreenPartyScore.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyScore', 3); Log.BenchmarkStart(3); + ScreenPartyWin := TScreenPartyWin.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyWin', 3); Log.BenchmarkStart(3); + ScreenPartyOptions := TScreenPartyOptions.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyOptions', 3); Log.BenchmarkStart(3); + ScreenPartyPlayer := TScreenPartyPlayer.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen PartyPlayer', 3); Log.BenchmarkStart(3); + ScreenStatMain := TScreenStatMain.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Main', 3); Log.BenchmarkStart(3); + ScreenStatDetail := TScreenStatDetail.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Stat Detail', 3); Log.BenchmarkStart(3); + ScreenCredits := TScreenCredits.Create; + Log.BenchmarkEnd(3); Log.LogBenchmark('====> Screen Credits', 3); Log.BenchmarkStart(3); + + end; + +function LoadingThreadFunction: integer; +begin + LoadScreens; + Result:= 1; +end; + +end. diff --git a/Game/Code/Classes/UIni.pas b/Game/Code/Classes/UIni.pas index 5d599eab..6b7f3cea 100644 --- a/Game/Code/Classes/UIni.pas +++ b/Game/Code/Classes/UIni.pas @@ -260,12 +260,22 @@ begin for Pet := 0 to High(IScreens) do if Tekst = IScreens[Pet] then Ini.Screens := Pet; + // FullScreen + Tekst := IniFile.ReadString('Graphics', 'FullScreen', 'On'); + for Pet := 0 to High(IFullScreen) do + if Tekst = IFullScreen[Pet] then Ini.FullScreen := Pet; + + // Resolution SetLength(IResolution, 0); Modes := SDL_ListModes(nil, SDL_OPENGL or SDL_FULLSCREEN); // Check if there are any modes available repeat SetLength(IResolution, Length(IResolution) + 1); IResolution[High(IResolution)] := IntToStr(Modes^.w) + 'x' + IntToStr(Modes^.h); + Tekst := IniFile.ReadString('Graphics', 'Screens', IScreens[0]); + + Log.LogStatus('SDL_ListModes Res : ' + IResolution[High(IResolution)], 'Graphics - Resolutions'); + Inc(Modes); until Modes^ = nil; @@ -274,8 +284,12 @@ begin // THANKS : linnex at users.sourceforge.net if Length(IResolution) < 1 then begin - SetLength(IResolution, Length(IResolution) + 1);
- IResolution[High(IResolution)] := IntToStr(800) + 'x' + IntToStr(600);
+ SetLength(IResolution, Length(IResolution) + 1); + IResolution[High(IResolution)] := IntToStr(800) + 'x' + IntToStr(600); + Log.LogStatus('SDL_ListModes Defaulted Res To : ' + IResolution[High(IResolution)] , 'Graphics - Resolutions'); + + // Default to fullscreen OFF, in this case ! + Ini.FullScreen := 0; end; // reverse order @@ -289,10 +303,6 @@ begin 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'); diff --git a/Game/Code/Classes/ULyrics.pas b/Game/Code/Classes/ULyrics.pas index 1c2795ce..4fd360b7 100644 --- a/Game/Code/Classes/ULyrics.pas +++ b/Game/Code/Classes/ULyrics.pas @@ -1,544 +1,550 @@ -unit ULyrics;
-
-interface
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses OpenGL12, UTexture, UThemes, UMusic;
-
-type
- TLyricWord = record
- X: Real; //X Pos of the Word
- Width: Real; //Width of the Text
- TexPos: Real; //Pos of the Word (0 to 1) in the Sentence Texture
- TexWidth: Real; //width of the Word in Sentence Texture (0 to 1)
- Start: Cardinal; //Start of the Words in Quarters (Beats)
- Length: Cardinal; //Length of the Word in Quarters
- Text: String; //Text of this Word
- Freestyle: Boolean; //Is this Word Freestyle
- end;
- ALyricWord = array of TLyricWord;
-
- PLyricLine = ^TLyricLine;
- TLyricLine = record
- Text: String; //Text of the Line
- Tex: glUInt; //Texture of the Text from this Line
- Width: Real; //Width of the Lyricline in Tex
- Size: Byte; //Size of the Font in the Texture
- Words: ALyricWord; //Words from this Line
- Start: Cardinal; //Start in Quarters of teh Line
- Length: Cardinal; //Length in Quarters (From Start of First Note to the End of Last Note)
- Freestyle: Boolean; //Complete Line is Freestyle ?
- Players: Byte; //Which Players Sing this Line (1: Player1; 2: Player2; 4: Player3; [..])
- Done: Boolean; //Is Sentence Sung
- end;
-
- TLyricEngine = class
- private
- EoLastSentence: Real; //When did the Last Sentence End (in Beats)
- UpperLine: TLyricLine; //Line in the Upper Part of the Lyric Display
- LowerLine: TLyricLine; //Line in the Lower Part of teh Lyric Display
- QueueLine: TLyricLine; //Line that is in Queue and will be added when next Line is Finished
- PUpperLine, PLowerLine, PQueueLine: PLyricLine;
-
- IndicatorTex: TTexture; //Texture for Lyric Indikator(Bar that indicates when the Line start)
- BallTex: TTexture; //Texture of the Ball for cur. Word hover in Ballmode
- PlayerIconTex: array[0..5] of //Textures for PlayerIcon Index: Playernum; Index2: Enabled/Disabled
- array [0..1] of
- TTexture;
-
- inQueue: Boolean;
- LCounter: Word;
-
- //Some helper Procedures for Lyric Drawing
- procedure DrawLyrics (Beat: Real);
- procedure DrawLyricsLine(const X, W, Y: Real; Size: Byte; const Line: TLyricLine; Beat: Real);
- procedure DrawPlayerIcon(const Player: Byte; const Enabled: Boolean; const X, Y, Size, Alpha: Real);
- public
- //Positions, Line specific Settings
- UpperLineX: Real; //X Start Pos of UpperLine
- UpperLineW: Real; //Width of UpperLine with Icon(s) and Text
- UpperLineY: Real; //Y Start Pos of UpperLine
- UpperLineSize: Byte; //Max Size of Lyrics Text in UpperLine
-
- LowerLineX: Real; //X Start Pos of LowerLine
- LowerLineW: Real; //Width of LowerLine with Icon(s) and Text
- LowerLineY: Real; //Y Start Pos of LowerLine
- LowerLineSize: Byte; //Max Size of Lyrics Text in LowerLine
-
- //Display Propertys
- LineColor_en: TRGBA; //Color of Words in an Enabled Line
- LineColor_dis: TRGBA; //Color of Words in a Disabled Line
- LineColor_akt: TRGBA; //Color of teh active Word
- FontStyle: Byte; //Font for the Lyric Text
- FontReSize: Boolean; //ReSize Lyrics if they don't fit Screen
-
- HoverEffekt: Byte; //Effekt of Hovering active Word: 0 - one selection, 1 - long selection, 2 - one selection with fade to normal text, 3 - long selection with fade with color from left
- FadeInEffekt: Byte; //Effekt for Line Fading in: 0: No Effekt; 1: Fade Effekt; 2: Move Upwards from Bottom to Pos
- FadeOutEffekt: Byte; //Effekt for Line Fading out: 0: No Effekt; 1: Fade Effekt; 2: Move Upwards
-
- UseLinearFilter:Boolean; //Should Linear Tex Filter be used
-
- //Song specific Settings
- BPM: Real;
- Resolution: Integer;
-
-
- //properties to easily update this Class within other Parts of Code
- property LineinQueue: Boolean read inQueue; //True when there is a Line in Queue
- property LineCounter: Word read LCounter; //Lines that was Progressed so far (after last Clear)
-
- Constructor Create; overload; //Constructor, just get Memory
- Constructor Create(ULX,ULY,ULW,ULS,LLX,LLY,LLW,LLS:Real); overload;
- Procedure LoadTextures; //Load Player Textures and Create
-
- Procedure AddLine(Line: PLine); //Adds a Line to the Queue if there is Space
- Procedure Draw (Beat: Real); //Procedure Draws Lyrics; Beat is curent Beat in Quarters
- Procedure Clear (const cBPM: Real = 0; const cResolution: Integer = 0); //Clears all cached Song specific Information
-
- Destructor Free; //Frees Memory
- end;
-
-const LyricTexStart = 2/512;
-
-implementation
-uses SysUtils, USkins, TextGL, UGraphic, UDisplay, dialogs;
-
-//-----------
-//Helper procs to use TRGB in Opengl ...maybe this should be somewhere else
-//-----------
-procedure glColorRGB(Color: TRGB); overload;
-begin
- glColor3f(Color.R, Color.G, Color.B);
-end;
-
-procedure glColorRGB(Color: TRGBA); overload;
-begin
- glColor4f(Color.R, Color.G, Color.B, Color.A);
-end;
-
-
-
-//---------------
-// Create - Constructor, just get Memory
-//---------------
-Constructor TLyricEngine.Create;
-begin
- BPM := 0;
- Resolution := 0;
- LCounter := 0;
- inQueue := False;
-
- UpperLine.Done := True;
- LowerLine.Done := True;
- QueueLine.Done := True;
- PUpperline:=@UpperLine;
- PLowerLine:=@LowerLine;
- PQueueLine:=@QueueLine;
-
- UseLinearFilter := True;
-end;
-
-Constructor TLyricEngine.Create(ULX,ULY,ULW,ULS,LLX,LLY,LLW,LLS:Real);
-begin
- Create;
- UpperLineX := ULX;
- UpperLineW := ULW;
- UpperLineY := ULY;
- UpperLineSize := Trunc(ULS);
-
- LowerLineX := LLX;
- LowerLineW := LLW;
- LowerLineY := LLY;
- LowerLineSize := Trunc(LLS);
- LoadTextures;
-end;
-
-
-//---------------
-// Free - Frees Memory
-//---------------
-Destructor TLyricEngine.Free;
-begin
-
-end;
-
-//---------------
-// Clear - Clears all cached Song specific Information
-//---------------
-Procedure TLyricEngine.Clear (const cBPM: Real; const cResolution: Integer);
-begin
- BPM := cBPM;
- Resolution := cResolution;
- LCounter := 0;
- inQueue := False;
-
- UpperLine.Done := True;
- LowerLine.Done := True;
- QueueLine.Done := True;
-
- PUpperline:=@UpperLine;
- PLowerLine:=@LowerLine;
- PQueueLine:=@QueueLine;
-end;
-
-
-//---------------
-// LoadTextures - Load Player Textures and Create Lyric Textures
-//---------------
-Procedure TLyricEngine.LoadTextures;
-var
- I: Integer;
- PTexData: Pointer;
-
- function CreateLineTex: glUint;
- begin
- GetMem(pTexData, 1024*128*4); //get Memory to save Tex in
-
- //generate and bind Texture
- glGenTextures(1, Result);
- glBindTexture(GL_TEXTURE_2D, Result);
-
- //Get Memory
- glTexImage2D(GL_TEXTURE_2D, 0, 4, 1024, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, pTexData);
-
- if UseLinearFilter then
- begin
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- end;
-
- //Free now unused Memory
- FreeMem(pTexData);
- end;
-begin
- //Load Texture for Lyric Indikator(Bar that indicates when the Line start)
- IndicatorTex := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LyricHelpBar')), 'BMP', 'Transparent', $FF00FF);
-
- //Load Texture of the Ball for cur. Word hover in Ballmode
- BallTex := Texture.LoadTexture(pchar(Skin.GetTextureFileName('Ball')), 'BMP', 'Transparent', $FF00FF);
-
- //Load PlayerTexs
- For I := 0 to 1 do
- begin
- PlayerIconTex[I][0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LyricIcon_P' + InttoStr(I+1))), 'PNG', 'Transparent', 0);
- PlayerIconTex[I][1] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LyricIconD_P' + InttoStr(I+1))), 'PNG', 'Transparent', 0);
- end;
-
- //atm just unset other texs
- For I := 2 to 5 do
- begin
- PlayerIconTex[I][0].TexNum := high(Cardinal); //Set to C's -1
- PlayerIconTex[I][1].TexNum := high(Cardinal);
- end;
-
- //Create LineTexs
- UpperLine.Tex := CreateLineTex;
- LowerLine.Tex := CreateLineTex;
- QueueLine.Tex := CreateLineTex;
-end;
-
-
-//---------------
-// AddLine - Adds LyricLine to queue
-//---------------
-Procedure TLyricEngine.AddLine(Line: PLine);
-var
- LyricLine: PLyricLine;
- I: Integer;
- countNotes: Cardinal;
- PosX: Real;
- Viewport: Array[0..3] of Integer;
-begin
- //Only Add Lines if there is enough space
- If not LineinQueue then
- begin
- //Set Pointer to Line to Write
- If (LineCounter = 0) then
- LyricLine := PUpperLine //Set Upper Line
- else if (LineCounter = 1) then
- LyricLine := PLowerLine //Set Lower Line
- else
- begin
- LyricLine := PQueueLine; //Set Queue Line
- inQueue := True; //now there is a Queued Line
- end;
- end
- else
- begin
- LyricLine:=PUpperLine;
- PUpperLine:=PLowerLine;
- PLowerLine:=PQueueLine;
- PQueueLine:=LyricLine;
- end;
-
- //Check if Sentence has Notes
- If (Length(Line.Nuta) > 0) then
- begin
- //Copy Values from SongLine to LyricLine
- CountNotes := high(Line.Nuta);
- LyricLine.Start := Line.Nuta[0].Start;
- LyricLine.Length := Line.Nuta[CountNotes].Start + Line.Nuta[CountNotes].Dlugosc - LyricLine.Start;
- LyricLine.Freestyle := True; //is set by And Notes Freestyle while copying Notes
- LyricLine.Text := ''; //Also Set while copying Notes
- LyricLine.Players := 127; //All Players for now, no Duett Mode available
- //Copy Words
- SetLength(LyricLine.Words, CountNotes + 1);
- For I := 0 to CountNotes do
- begin
- LyricLine.Freestyle := LyricLine.Freestyle AND Line.Nuta[I].FreeStyle;
- LyricLine.Words[I].Start := Line.Nuta[I].Start;
- LyricLine.Words[I].Length := Line.Nuta[I].Dlugosc;
- LyricLine.Words[I].Text := Line.Nuta[I].Tekst;
- LyricLine.Words[I].Freestyle := Line.Nuta[I].FreeStyle;
- LyricLine.Text := LyricLine.Text + LyricLine.Words[I].Text
- end;
-
- //Set Font Params
- SetFontStyle(FontStyle);
- SetFontPos(0, 0);
- LyricLine.Size := UpperLineSize;
- SetFontSize(LyricLine.Size);
- SetFontItalic(False);
- glColor4f(1, 1, 1, 1);
-
- //Change Fontsize to Fit the Screen
- While (LyricLine.Width > 508) do
- begin
- Dec(LyricLine.Size);
-
- if (LyricLine.Size <=1) then
- Break;
-
- SetFontSize(LyricLine.Size);
- LyricLine.Width := glTextWidth(PChar(LyricLine.Text));
- end;
-
- //Set Word Positions and Line Size
- PosX := 2 {LowerLineX + LowerLineW/2 + 80 - LyricLine.Width/2};
- For I := 0 to High(LyricLine.Words) do
- begin
- LyricLine.Words[I].X := PosX;
- LyricLine.Words[I].Width := glTextWidth(PChar(LyricLine.Words[I].Text));
- LyricLine.Words[I].TexPos := PosX / 512;
- LyricLine.Words[I].TexWidth := LyricLine.Words[I].TexWidth / 512;
-
- PosX := PosX + LyricLine.Words[I].Width;
- end;
-
- //Create LyricTexture
- //Prepare Ogl
- glGetIntegerv(GL_VIEWPORT, @ViewPort);
- glClearColor(0.0,0.0,0.0,0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
- {glMatrixMode(GL_PROJECTION);
- glLoadIdentity;
- glOrtho(0, 1024, 64, 0, -1, 100);
- glMatrixMode(GL_MODELVIEW);}
- glViewport(0, 0, 512, 512);
-
- //Draw Lyrics
- SetFontPos(0, 0);
- glPrint(PChar(LyricLine.Text));
-
- Display.ScreenShot;
- //Copy to Texture
- glBindTexture(GL_TEXTURE_2D, LyricLine.Tex);
- glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 448, 512, 64, 0);
-
- //Clear Buffer
- glClearColor(0,0,0,0);
- glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
-
- glViewPort(ViewPort[0], ViewPort[1], ViewPort[2], ViewPort[3]);
- {glMatrixMode(GL_PROJECTION);
- glLoadIdentity;
- glOrtho(0, RenderW, RenderH, 0, -1, 100);
- glMatrixMode(GL_MODELVIEW); }
- end;
-
- //Increase the Counter
- Inc(LCounter);
-end;
-
-
-//---------------
-// Draw - Procedure Draws Lyrics; Beat is curent Beat in Quarters
-// Draw just manage the Lyrics, drawing is done by a call of DrawLyrics
-//---------------
-Procedure TLyricEngine.Draw (Beat: Real);
-begin
-
- DrawLyrics(Beat);
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_Alpha {GL_ONE_MINUS_SRC_COLOR}, GL_ONE_MINUS_SRC_Alpha);
- glBindTexture(GL_TEXTURE_2D, PUpperLine^.Tex);
-
- glColor4f(1,1,0,1);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 1); glVertex2f(100, 100);
- glTexCoord2f(0, 0); glVertex2f(100, 200);
- glTexCoord2f(1, 0); glVertex2f(612, 200);
- glTexCoord2f(1, 1); glVertex2f(612, 100);
- glEnd;
-
- glBindTexture(GL_TEXTURE_2D, PLowerLine^.Tex);
-
- glColor4f(1,0,1,1);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 1); glVertex2f(100, 200);
- glTexCoord2f(0, 0); glVertex2f(100, 300);
- glTexCoord2f(1, 0); glVertex2f(612, 300);
- glTexCoord2f(1, 1); glVertex2f(612, 200);
- glEnd;
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-
-end;
-
-//---------------
-// DrawLyrics(private) - Helper for Draw; main Drawing procedure
-//---------------
-procedure TLyricEngine.DrawLyrics (Beat: Real);
-begin
- DrawLyricsLine(UpperLineX, UpperLineW, UpperlineY, 15, Upperline, Beat);
- DrawLyricsLine(LowerLineX, LowerLineW, LowerlineY, 15, Lowerline, Beat);
-end;
-
-//---------------
-// DrawPlayerIcon(private) - Helper for Draw; Draws a Playericon
-//---------------
-procedure TLyricEngine.DrawPlayerIcon(const Player: Byte; const Enabled: Boolean; const X, Y, Size, Alpha: Real);
-var IEnabled: Byte;
-begin
- Case Enabled of
- True: IEnabled := 0;
- False: IEnabled:= 1;
- end;
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glBindTexture(GL_TEXTURE_2D, PlayerIconTex[Player][IEnabled].TexNum);
-
- glColor4f(1,1,1,Alpha);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(X, Y);
- glTexCoord2f(0, 1); glVertex2f(X, Y + Size);
- glTexCoord2f(1, 1); glVertex2f(X + Size, Y + Size);
- glTexCoord2f(1, 0); glVertex2f(X + Size, Y);
- glEnd;
-
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
-end;
-//---------------
-// DrawLyricsLine(private) - Helper for Draw; Draws one LyricLine
-//---------------
-procedure TLyricEngine.DrawLyricsLine(const X, W, Y: Real; Size: Byte; const Line: TLyricLine; Beat: Real);
-var
- I: Integer;
- CurWord: Integer;
- Progress: Real;
- LyricX: Real; //Left Corner on X Axis
- LyricX2: Real;//Right Corner " "
- LyricScale: Real; //Up or Downscale the Lyrics need
- IconSize: Real;
- IconAlpha: Real;
-begin
-
-{ For I := 0 to High(Line.Words) do
- begin
- //Set Font Params
- SetFontStyle(FontStyle);
- SetFontSize(Size);
- SetFontItalic(Line.Words[I].Freestyle);
- glColor4f(1, 1, 1, 1);
-
- SetFontPos(Line.Words[I].X, Y);
-
- glPrint(PChar(Line.Words[I].Text));
- end; }
-
- LyricScale := Size / Line.Size;
-
- //Draw Icons
- IconSize := (2 * Size);
- //IconAlpha := 1;
- IconAlpha := Frac(Beat/(Resolution*4));
-
- {DrawPlayerIcon (0, True, X, Y, IconSize, IconAlpha);
- DrawPlayerIcon (1, True, X + IconSize + 1, Y, IconSize, IconAlpha);
- DrawPlayerIcon (2, True, X + (IconSize + 1)*2, Y, IconSize, IconAlpha);}
-
- //Check if a Word in the Sentence is active
- if ((Line.Start > Beat) AND (Line.Start + Line.Length < Beat)) then
- begin
- //Get Start Position:
- { Start of Line - Width of all Icons + LineWidth/2 (Center}
- LyricX := X + (W - ((IconSize + 1) * 6))/2 + ((IconSize + 1) * 3);
-
- LyricX2 := LyricX + Line.Width;
-
- //Draw complete Sentence
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_COLOR {GL_ONE_MINUS_SRC_COLOR}, GL_ONE_MINUS_SRC_COLOR);
- glBindTexture(GL_TEXTURE_2D, Line.Tex);
-
- glColorRGB(LineColor_en);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 1); glVertex2f(LyricX, Y);
- glTexCoord2f(0, 0); glVertex2f(LyricX, Y + 64 * W / 512);
- glTexCoord2f(1, 0); glVertex2f(LyricX + LyricX2, Y + 64 * W / 512);
- glTexCoord2f(1, 1); glVertex2f(LyricX + LyricX2, Y);
- glEnd;
-
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);
- end
- else
- begin
-
- end;
-
- {//Search for active Word
- For I := 0 to High(Line.Words) do
- if (Line.Words[I].Start < Beat) then
- begin
- CurWord := I - 1;
- end;
-
- if (CurWord < 0) then Exit;
-
- //Draw Part until cur Word
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_COLOR {GL_ONE_MINUS_SRC_COLOR}{, GL_ONE_MINUS_SRC_COLOR);
- glBindTexture(GL_TEXTURE_2D, Line.Tex);
-
- glColorRGB(LineColor_en);
- glBegin(GL_QUADS);
- glTexCoord2f(0, 1); glVertex2f(X, Y);
- glTexCoord2f(0, 0); glVertex2f(X, Y + 64 * W / 512);
- glTexCoord2f(Line.Words[CurWord].TexPos, 0); glVertex2f(X + W, Y + 64 * W / 512);
- glTexCoord2f(Line.Words[CurWord].TexPos, 1); glVertex2f(X + W, Y);
- glEnd;
-
-
- glDisable(GL_BLEND);
- glDisable(GL_TEXTURE_2D);}
-end;
-
-
-end.
-
+unit ULyrics; + +interface + +{$IFDEF FPC} + {$MODE DELPHI} +{$ENDIF} + +{$I switches.inc} + +uses OpenGL12, UTexture, UThemes, UMusic; + +type + TLyricWord = record + X: Real; //X Pos of the Word + Width: Real; //Width of the Text + TexPos: Real; //Pos of the Word (0 to 1) in the Sentence Texture + TexWidth: Real; //width of the Word in Sentence Texture (0 to 1) + Start: Cardinal; //Start of the Words in Quarters (Beats) + Length: Cardinal; //Length of the Word in Quarters + Text: String; //Text of this Word + Freestyle: Boolean; //Is this Word Freestyle + end; + ALyricWord = array of TLyricWord; + + PLyricLine = ^TLyricLine; + TLyricLine = record + Text: String; //Text of the Line + Tex: glUInt; //Texture of the Text from this Line + Width: Real; //Width of the Lyricline in Tex + Size: Byte; //Size of the Font in the Texture + Words: ALyricWord; //Words from this Line + Start: Cardinal; //Start in Quarters of teh Line + Length: Cardinal; //Length in Quarters (From Start of First Note to the End of Last Note) + Freestyle: Boolean; //Complete Line is Freestyle ? + Players: Byte; //Which Players Sing this Line (1: Player1; 2: Player2; 4: Player3; [..]) + Done: Boolean; //Is Sentence Sung + end; + + TLyricEngine = class + private + EoLastSentence: Real; //When did the Last Sentence End (in Beats) + UpperLine: TLyricLine; //Line in the Upper Part of the Lyric Display + LowerLine: TLyricLine; //Line in the Lower Part of teh Lyric Display + QueueLine: TLyricLine; //Line that is in Queue and will be added when next Line is Finished + PUpperLine, PLowerLine, PQueueLine: PLyricLine; + + IndicatorTex: TTexture; //Texture for Lyric Indikator(Bar that indicates when the Line start) + BallTex: TTexture; //Texture of the Ball for cur. Word hover in Ballmode + PlayerIconTex: array[0..5] of //Textures for PlayerIcon Index: Playernum; Index2: Enabled/Disabled + array [0..1] of + TTexture; + + inQueue: Boolean; + LCounter: Word; + + //Some helper Procedures for Lyric Drawing + procedure DrawLyrics (Beat: Real); + procedure DrawLyricsLine(const X, W, Y: Real; Size: Byte; const Line: TLyricLine; Beat: Real); + procedure DrawPlayerIcon(const Player: Byte; const Enabled: Boolean; const X, Y, Size, Alpha: Real); + public + //Positions, Line specific Settings + UpperLineX: Real; //X Start Pos of UpperLine + UpperLineW: Real; //Width of UpperLine with Icon(s) and Text + UpperLineY: Real; //Y Start Pos of UpperLine + UpperLineSize: Byte; //Max Size of Lyrics Text in UpperLine + + LowerLineX: Real; //X Start Pos of LowerLine + LowerLineW: Real; //Width of LowerLine with Icon(s) and Text + LowerLineY: Real; //Y Start Pos of LowerLine + LowerLineSize: Byte; //Max Size of Lyrics Text in LowerLine + + //Display Propertys + LineColor_en: TRGBA; //Color of Words in an Enabled Line + LineColor_dis: TRGBA; //Color of Words in a Disabled Line + LineColor_akt: TRGBA; //Color of teh active Word + FontStyle: Byte; //Font for the Lyric Text + FontReSize: Boolean; //ReSize Lyrics if they don't fit Screen + + HoverEffekt: Byte; //Effekt of Hovering active Word: 0 - one selection, 1 - long selection, 2 - one selection with fade to normal text, 3 - long selection with fade with color from left + FadeInEffekt: Byte; //Effekt for Line Fading in: 0: No Effekt; 1: Fade Effekt; 2: Move Upwards from Bottom to Pos + FadeOutEffekt: Byte; //Effekt for Line Fading out: 0: No Effekt; 1: Fade Effekt; 2: Move Upwards + + UseLinearFilter:Boolean; //Should Linear Tex Filter be used + + //Song specific Settings + BPM: Real; + Resolution: Integer; + + + //properties to easily update this Class within other Parts of Code + property LineinQueue: Boolean read inQueue; //True when there is a Line in Queue + property LineCounter: Word read LCounter; //Lines that was Progressed so far (after last Clear) + + Constructor Create; overload; //Constructor, just get Memory + Constructor Create(ULX,ULY,ULW,ULS,LLX,LLY,LLW,LLS:Real); overload; + Procedure LoadTextures; //Load Player Textures and Create + + Procedure AddLine(Line: PLine); //Adds a Line to the Queue if there is Space + Procedure Draw (Beat: Real); //Procedure Draws Lyrics; Beat is curent Beat in Quarters + Procedure Clear (const cBPM: Real = 0; const cResolution: Integer = 0); //Clears all cached Song specific Information + + Destructor Free; //Frees Memory + end; + +const LyricTexStart = 2/512; + +implementation + +uses SysUtils, + USkins, + TextGL, + UGraphic, + UDisplay, + dialogs; + +//----------- +//Helper procs to use TRGB in Opengl ...maybe this should be somewhere else +//----------- +procedure glColorRGB(Color: TRGB); overload; +begin + glColor3f(Color.R, Color.G, Color.B); +end; + +procedure glColorRGB(Color: TRGBA); overload; +begin + glColor4f(Color.R, Color.G, Color.B, Color.A); +end; + + + +//--------------- +// Create - Constructor, just get Memory +//--------------- +Constructor TLyricEngine.Create; +begin + BPM := 0; + Resolution := 0; + LCounter := 0; + inQueue := False; + + UpperLine.Done := True; + LowerLine.Done := True; + QueueLine.Done := True; + PUpperline:=@UpperLine; + PLowerLine:=@LowerLine; + PQueueLine:=@QueueLine; + + UseLinearFilter := True; +end; + +Constructor TLyricEngine.Create(ULX,ULY,ULW,ULS,LLX,LLY,LLW,LLS:Real); +begin + Create; + UpperLineX := ULX; + UpperLineW := ULW; + UpperLineY := ULY; + UpperLineSize := Trunc(ULS); + + LowerLineX := LLX; + LowerLineW := LLW; + LowerLineY := LLY; + LowerLineSize := Trunc(LLS); + LoadTextures; +end; + + +//--------------- +// Free - Frees Memory +//--------------- +Destructor TLyricEngine.Free; +begin + +end; + +//--------------- +// Clear - Clears all cached Song specific Information +//--------------- +Procedure TLyricEngine.Clear (const cBPM: Real; const cResolution: Integer); +begin + BPM := cBPM; + Resolution := cResolution; + LCounter := 0; + inQueue := False; + + UpperLine.Done := True; + LowerLine.Done := True; + QueueLine.Done := True; + + PUpperline:=@UpperLine; + PLowerLine:=@LowerLine; + PQueueLine:=@QueueLine; +end; + + +//--------------- +// LoadTextures - Load Player Textures and Create Lyric Textures +//--------------- +Procedure TLyricEngine.LoadTextures; +var + I: Integer; + PTexData: Pointer; + + function CreateLineTex: glUint; + begin + GetMem(pTexData, 1024*128*4); //get Memory to save Tex in + + //generate and bind Texture + glGenTextures(1, @Result); + glBindTexture(GL_TEXTURE_2D, Result); + + //Get Memory + glTexImage2D(GL_TEXTURE_2D, 0, 4, 1024, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE, pTexData); + + if UseLinearFilter then + begin + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + end; + + //Free now unused Memory + FreeMem(pTexData); + end; +begin + //Load Texture for Lyric Indikator(Bar that indicates when the Line start) + IndicatorTex := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LyricHelpBar')), 'BMP', 'Transparent', $FF00FF); + + //Load Texture of the Ball for cur. Word hover in Ballmode + BallTex := Texture.LoadTexture(pchar(Skin.GetTextureFileName('Ball')), 'BMP', 'Transparent', $FF00FF); + + //Load PlayerTexs + For I := 0 to 1 do + begin + PlayerIconTex[I][0] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LyricIcon_P' + InttoStr(I+1))), 'PNG', 'Transparent', 0); + PlayerIconTex[I][1] := Texture.LoadTexture(pchar(Skin.GetTextureFileName('LyricIconD_P' + InttoStr(I+1))), 'PNG', 'Transparent', 0); + end; + + //atm just unset other texs + For I := 2 to 5 do + begin + PlayerIconTex[I][0].TexNum := high(Cardinal); //Set to C's -1 + PlayerIconTex[I][1].TexNum := high(Cardinal); + end; + + //Create LineTexs + UpperLine.Tex := CreateLineTex; + LowerLine.Tex := CreateLineTex; + QueueLine.Tex := CreateLineTex; +end; + + +//--------------- +// AddLine - Adds LyricLine to queue +//--------------- +Procedure TLyricEngine.AddLine(Line: PLine); +var + LyricLine: PLyricLine; + I: Integer; + countNotes: Cardinal; + PosX: Real; + Viewport: Array[0..3] of Integer; +begin + //Only Add Lines if there is enough space + If not LineinQueue then + begin + //Set Pointer to Line to Write + If (LineCounter = 0) then + LyricLine := PUpperLine //Set Upper Line + else if (LineCounter = 1) then + LyricLine := PLowerLine //Set Lower Line + else + begin + LyricLine := PQueueLine; //Set Queue Line + inQueue := True; //now there is a Queued Line + end; + end + else + begin + LyricLine:=PUpperLine; + PUpperLine:=PLowerLine; + PLowerLine:=PQueueLine; + PQueueLine:=LyricLine; + end; + + //Check if Sentence has Notes + If (Length(Line.Nuta) > 0) then + begin + //Copy Values from SongLine to LyricLine + CountNotes := high(Line.Nuta); + LyricLine.Start := Line.Nuta[0].Start; + LyricLine.Length := Line.Nuta[CountNotes].Start + Line.Nuta[CountNotes].Dlugosc - LyricLine.Start; + LyricLine.Freestyle := True; //is set by And Notes Freestyle while copying Notes + LyricLine.Text := ''; //Also Set while copying Notes + LyricLine.Players := 127; //All Players for now, no Duett Mode available + //Copy Words + SetLength(LyricLine.Words, CountNotes + 1); + For I := 0 to CountNotes do + begin + LyricLine.Freestyle := LyricLine.Freestyle AND Line.Nuta[I].FreeStyle; + LyricLine.Words[I].Start := Line.Nuta[I].Start; + LyricLine.Words[I].Length := Line.Nuta[I].Dlugosc; + LyricLine.Words[I].Text := Line.Nuta[I].Tekst; + LyricLine.Words[I].Freestyle := Line.Nuta[I].FreeStyle; + LyricLine.Text := LyricLine.Text + LyricLine.Words[I].Text + end; + + //Set Font Params + SetFontStyle(FontStyle); + SetFontPos(0, 0); + LyricLine.Size := UpperLineSize; + SetFontSize(LyricLine.Size); + SetFontItalic(False); + glColor4f(1, 1, 1, 1); + + //Change Fontsize to Fit the Screen + While (LyricLine.Width > 508) do + begin + Dec(LyricLine.Size); + + if (LyricLine.Size <=1) then + Break; + + SetFontSize(LyricLine.Size); + LyricLine.Width := glTextWidth(PChar(LyricLine.Text)); + end; + + //Set Word Positions and Line Size + PosX := 2 {LowerLineX + LowerLineW/2 + 80 - LyricLine.Width/2}; + For I := 0 to High(LyricLine.Words) do + begin + LyricLine.Words[I].X := PosX; + LyricLine.Words[I].Width := glTextWidth(PChar(LyricLine.Words[I].Text)); + LyricLine.Words[I].TexPos := PosX / 512; + LyricLine.Words[I].TexWidth := LyricLine.Words[I].TexWidth / 512; + + PosX := PosX + LyricLine.Words[I].Width; + end; + + //Create LyricTexture + //Prepare Ogl + glGetIntegerv(GL_VIEWPORT, @ViewPort); + glClearColor(0.0,0.0,0.0,0); + glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); + {glMatrixMode(GL_PROJECTION); + glLoadIdentity; + glOrtho(0, 1024, 64, 0, -1, 100); + glMatrixMode(GL_MODELVIEW);} + glViewport(0, 0, 512, 512); + + //Draw Lyrics + SetFontPos(0, 0); + glPrint(PChar(LyricLine.Text)); + + Display.ScreenShot; + //Copy to Texture + glBindTexture(GL_TEXTURE_2D, LyricLine.Tex); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 448, 512, 64, 0); + + //Clear Buffer + glClearColor(0,0,0,0); + glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); + + glViewPort(ViewPort[0], ViewPort[1], ViewPort[2], ViewPort[3]); + {glMatrixMode(GL_PROJECTION); + glLoadIdentity; + glOrtho(0, RenderW, RenderH, 0, -1, 100); + glMatrixMode(GL_MODELVIEW); } + end; + + //Increase the Counter + Inc(LCounter); +end; + + +//--------------- +// Draw - Procedure Draws Lyrics; Beat is curent Beat in Quarters +// Draw just manage the Lyrics, drawing is done by a call of DrawLyrics +//--------------- +Procedure TLyricEngine.Draw (Beat: Real); +begin + + DrawLyrics(Beat); + + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_Alpha {GL_ONE_MINUS_SRC_COLOR}, GL_ONE_MINUS_SRC_Alpha); + glBindTexture(GL_TEXTURE_2D, PUpperLine^.Tex); + + glColor4f(1,1,0,1); + glBegin(GL_QUADS); + glTexCoord2f(0, 1); glVertex2f(100, 100); + glTexCoord2f(0, 0); glVertex2f(100, 200); + glTexCoord2f(1, 0); glVertex2f(612, 200); + glTexCoord2f(1, 1); glVertex2f(612, 100); + glEnd; + + glBindTexture(GL_TEXTURE_2D, PLowerLine^.Tex); + + glColor4f(1,0,1,1); + glBegin(GL_QUADS); + glTexCoord2f(0, 1); glVertex2f(100, 200); + glTexCoord2f(0, 0); glVertex2f(100, 300); + glTexCoord2f(1, 0); glVertex2f(612, 300); + glTexCoord2f(1, 1); glVertex2f(612, 200); + glEnd; + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + +end; + +//--------------- +// DrawLyrics(private) - Helper for Draw; main Drawing procedure +//--------------- +procedure TLyricEngine.DrawLyrics (Beat: Real); +begin + DrawLyricsLine(UpperLineX, UpperLineW, UpperlineY, 15, Upperline, Beat); + DrawLyricsLine(LowerLineX, LowerLineW, LowerlineY, 15, Lowerline, Beat); +end; + +//--------------- +// DrawPlayerIcon(private) - Helper for Draw; Draws a Playericon +//--------------- +procedure TLyricEngine.DrawPlayerIcon(const Player: Byte; const Enabled: Boolean; const X, Y, Size, Alpha: Real); +var IEnabled: Byte; +begin + Case Enabled of + True: IEnabled := 0; + False: IEnabled:= 1; + end; + + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, PlayerIconTex[Player][IEnabled].TexNum); + + glColor4f(1,1,1,Alpha); + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(X, Y); + glTexCoord2f(0, 1); glVertex2f(X, Y + Size); + glTexCoord2f(1, 1); glVertex2f(X + Size, Y + Size); + glTexCoord2f(1, 0); glVertex2f(X + Size, Y); + glEnd; + + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); +end; +//--------------- +// DrawLyricsLine(private) - Helper for Draw; Draws one LyricLine +//--------------- +procedure TLyricEngine.DrawLyricsLine(const X, W, Y: Real; Size: Byte; const Line: TLyricLine; Beat: Real); +var + I: Integer; + CurWord: Integer; + Progress: Real; + LyricX: Real; //Left Corner on X Axis + LyricX2: Real;//Right Corner " " + LyricScale: Real; //Up or Downscale the Lyrics need + IconSize: Real; + IconAlpha: Real; +begin + +{ For I := 0 to High(Line.Words) do + begin + //Set Font Params + SetFontStyle(FontStyle); + SetFontSize(Size); + SetFontItalic(Line.Words[I].Freestyle); + glColor4f(1, 1, 1, 1); + + SetFontPos(Line.Words[I].X, Y); + + glPrint(PChar(Line.Words[I].Text)); + end; } + + LyricScale := Size / Line.Size; + + //Draw Icons + IconSize := (2 * Size); + //IconAlpha := 1; + IconAlpha := Frac(Beat/(Resolution*4)); + + {DrawPlayerIcon (0, True, X, Y, IconSize, IconAlpha); + DrawPlayerIcon (1, True, X + IconSize + 1, Y, IconSize, IconAlpha); + DrawPlayerIcon (2, True, X + (IconSize + 1)*2, Y, IconSize, IconAlpha);} + + //Check if a Word in the Sentence is active + if ((Line.Start > Beat) AND (Line.Start + Line.Length < Beat)) then + begin + //Get Start Position: + { Start of Line - Width of all Icons + LineWidth/2 (Center} + LyricX := X + (W - ((IconSize + 1) * 6))/2 + ((IconSize + 1) * 3); + + LyricX2 := LyricX + Line.Width; + + //Draw complete Sentence + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_COLOR {GL_ONE_MINUS_SRC_COLOR}, GL_ONE_MINUS_SRC_COLOR); + glBindTexture(GL_TEXTURE_2D, Line.Tex); + + glColorRGB(LineColor_en); + glBegin(GL_QUADS); + glTexCoord2f(0, 1); glVertex2f(LyricX, Y); + glTexCoord2f(0, 0); glVertex2f(LyricX, Y + 64 * W / 512); + glTexCoord2f(1, 0); glVertex2f(LyricX + LyricX2, Y + 64 * W / 512); + glTexCoord2f(1, 1); glVertex2f(LyricX + LyricX2, Y); + glEnd; + + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + end + else + begin + + end; + + {//Search for active Word + For I := 0 to High(Line.Words) do + if (Line.Words[I].Start < Beat) then + begin + CurWord := I - 1; + end; + + if (CurWord < 0) then Exit; + + //Draw Part until cur Word + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_COLOR {GL_ONE_MINUS_SRC_COLOR}{, GL_ONE_MINUS_SRC_COLOR); + glBindTexture(GL_TEXTURE_2D, Line.Tex); + + glColorRGB(LineColor_en); + glBegin(GL_QUADS); + glTexCoord2f(0, 1); glVertex2f(X, Y); + glTexCoord2f(0, 0); glVertex2f(X, Y + 64 * W / 512); + glTexCoord2f(Line.Words[CurWord].TexPos, 0); glVertex2f(X + W, Y + 64 * W / 512); + glTexCoord2f(Line.Words[CurWord].TexPos, 1); glVertex2f(X + W, Y); + glEnd; + + + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D);} +end; + + +end. + diff --git a/Game/Code/Classes/UMain.pas b/Game/Code/Classes/UMain.pas index 66e1d07e..aa4bc639 100644 --- a/Game/Code/Classes/UMain.pas +++ b/Game/Code/Classes/UMain.pas @@ -1,791 +1,793 @@ -unit UMain;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
- SDL,
- UGraphic,
- UMusic,
- URecord,
- UTime,
- SysUtils,
- UDisplay,
- UIni,
- ULog,
- ULyrics,
- UScreenSing,
- OpenGL12,
- {$IFDEF UseSerialPort}
- zlportio {you can disable it and all PortWriteB calls},
- {$ENDIF}
- ULCD,
- ULight,
- UThemes;
-
-type
- TPlayer = record
- Name: string;
-
- Score: real;
- ScoreLine: real;
- ScoreGolden: real;
-
- ScoreI: integer;
- ScoreLineI: integer;
- ScoreGoldenI: integer;
- ScoreTotalI: integer;
-
-
-
- //LineBonus Mod
- ScoreLast: Real;//Last Line Score
- {ScorePercent: integer;//Aktual Fillstate of the SingBar
- ScorePercentTarget: integer;//Target Fillstate of the SingBar
- //end Singbar Mod
-
- //PhrasenBonus - Line Bonus Mod
- LineBonus_PosX: Single;
- LineBonus_PosY: Single;
- LineBonus_Alpha: Single;
- LineBonus_Visible: boolean;
- LineBonus_Text: string;
- LineBonus_Color: TRGB;
- LineBonus_Age: Integer;
- LineBonus_Rating: Integer;
- //Variable vor Positioning -> Set on ScreenShow, different when Playercount Changes
- LineBonus_TargetX: integer;
- LineBonus_TargetY: integer;
- LineBonus_StartX: integer;
- LineBonus_StartY: integer;
- //PhrasenBonus - Line Bonus Mod End }
-
-
- //PerfectLineTwinkle Mod (effect)
- LastSentencePerfect: Boolean;
- //PerfectLineTwinkle Mod end
-
-
-// Meter: real;
-
- HighNut: integer;
- IlNut: integer;
- Nuta: array of record
- Start: integer;
- Dlugosc: integer;
- Detekt: real; // dokladne miejsce, w ktorym wykryto ta nute
- Ton: real;
- Perfect: boolean; // true if the note matches the original one, lit the star
-
-
-
- // Half size Notes Patch
- Hit: boolean; // true if the note Hits the Line
- //end Half size Notes Patch
-
-
-
- end;
- end;
-
-
-var
- //Absolute Paths
- GamePath: string;
- SoundPath: string;
- SongPath: string;
- LogPath: string;
- ThemePath: string;
- ScreenshotsPath: string;
- CoversPath: string;
- LanguagesPath: string;
- PluginPath: string;
- PlayListPath: string;
-
- OGL: Boolean;
- Done: Boolean;
- Event: TSDL_event;
- FileName: string;
- Restart: boolean;
-
- // gracz i jego nuty
- Player: array of TPlayer;
- PlayersPlay: integer;
-
-procedure InitializePaths;
-
-procedure MainLoop;
-procedure CheckEvents;
-procedure Sing(Sender: TScreenSing);
-procedure NewSentence(Sender: TScreenSing);
-procedure NewBeat(Sender: TScreenSing); // executed when on then new beat
-procedure NewBeatC(Sender: TScreenSing); // executed when on then new beat for click
-procedure NewBeatD(Sender: TScreenSing); // executed when on then new beat for detection
-//procedure NewHalf; // executed when in the half between beats
-procedure NewNote(Sender: TScreenSing); // detect note
-function GetMidBeat(Time: real): real;
-function GetTimeFromBeat(Beat: integer): real;
-procedure ClearScores(PlayerNum: integer);
-
-implementation
-uses USongs, UJoystick, math, UCommandLine;
-
-procedure MainLoop;
-var
- Delay: integer;
-begin
- SDL_EnableKeyRepeat(125, 125);
- While not Done do
- Begin
- // joypad
- if (Ini.Joypad = 1) OR (Params.Joypad) then
- Joy.Update;
-
- // keyboard events
- CheckEvents;
-
- // display
- done := not Display.Draw;
- SwapBuffers;
-
- // light
- Light.Refresh;
-
- // delay
- CountMidTime;
-// if 1000*TimeMid > 100 then beep;
- Delay := Floor(1000 / 100 - 1000 * TimeMid);
- if Delay >= 1 then
- SDL_Delay(Delay); // dynamic, maximum is 100 fps
- CountSkipTime;
-
- // reinitialization of graphics
- if Restart then begin
- Reinitialize3D;
- Restart := false;
- end;
-
- End;
- UnloadOpenGL;
-End;
-
-Procedure CheckEvents;
-//var
-// p: pointer;
-Begin
- if not Assigned(Display.NextScreen) then
- While SDL_PollEvent( @event ) = 1 Do
- Begin
-// beep;
- Case Event.type_ Of
- SDL_QUITEV: begin
- Display.Fade := 0;
- Display.NextScreenWithCheck := nil;
- Display.CheckOK := True;
- end;
-{ SDL_MOUSEBUTTONDOWN:
- With Event.button Do
- Begin
- If State = SDL_BUTTON_LEFT Then
- Begin
- //
- End;
- End; // With}
- SDL_KEYDOWN:
- begin
- //ScreenShot hack. If Print is pressed-> Make screenshot and Save to Screenshots Path
- if (Event.key.keysym.sym = SDLK_SYSREQ) then
- Display.ScreenShot
-
- // popup hack... if there is a visible popup then let it handle input instead of underlying screen
- // shoud be done in a way to be sure the topmost popup has preference (maybe error, then check)
- else if (ScreenPopupError <> NIL) and (ScreenPopupError.Visible) then
- done := not ScreenPopupError.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True)
- else if (ScreenPopupCheck <> NIL) AND (ScreenPopupCheck.Visible) then
- done := not ScreenPopupCheck.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True)
- // end of popup hack
-
- else
- begin
- // check for Screen want to Exit
- done := Not Display.ActualScreen^.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True);
-
- //If Screen wants to Exit
- if done then
- begin
- //If Question Option is enabled then Show Exit Popup
- if (Ini.AskbeforeDel = 1) then
- begin
- Display.ActualScreen^.CheckFadeTo(NIL,'MSG_QUIT_USDX');
- end
- else //When asking for exit is disabled then simply exit
- begin
- Display.Fade := 0;
- Display.NextScreenWithCheck := nil;
- Display.CheckOK := True;
- end;
- end;
-
- end; // if (Not Display.ActualScreen^.ParseInput(Event.key.keysym.scancode, True)) then
- end;
-// SDL_JOYAXISMOTION:
-// begin
-// beep
-// end;
- SDL_JOYBUTTONDOWN:
- begin
- beep
- end;
- End; // Case Event.type_
- End; // While
-End; // CheckEvents
-
-function GetTimeForBeats(BPM, Beats: real): real;
-begin
- Result := 60 / BPM * Beats;
-end;
-
-function GetBeats(BPM, msTime: real): real;
-begin
- Result := BPM * msTime / 60;
-end;
-
-procedure GetMidBeatSub(BPMNum: integer; var Time: real; var CurBeat: real);
-var
- NewTime: real;
-begin
- if High(AktSong.BPM) = BPMNum then begin
- // last BPM
- CurBeat := AktSong.BPM[BPMNum].StartBeat + GetBeats(AktSong.BPM[BPMNum].BPM, Time);
- Time := 0;
- end else begin
- // not last BPM
- // count how much time is it for start of the new BPM and store it in NewTime
- NewTime := GetTimeForBeats(AktSong.BPM[BPMNum].BPM, AktSong.BPM[BPMNum+1].StartBeat - AktSong.BPM[BPMNum].StartBeat);
-
- // compare it to remaining time
- if (Time - NewTime) > 0 then begin
- // there is still remaining time
- CurBeat := AktSong.BPM[BPMNum].StartBeat;
- Time := Time - NewTime;
- end else begin
- // there is no remaining time
- CurBeat := AktSong.BPM[BPMNum].StartBeat + GetBeats(AktSong.BPM[BPMNum].BPM, Time);
- Time := 0;
- end; // if
- end; // if
-end;
-
-function GetMidBeat(Time: real): real;
-var
- CurBeat: real;
- CurBPM: integer;
-// TopBeat: real;
-// TempBeat: real;
-// TempTime: real;
-begin
- Result := 0;
- if Length(AktSong.BPM) = 1 then Result := Time * AktSong.BPM[0].BPM / 60;
-
- (* 2 BPMs *)
-{ if Length(AktSong.BPM) > 1 then begin
- (* new system *)
- CurBeat := 0;
- TopBeat := GetBeats(AktSong.BPM[0].BPM, Time);
- if TopBeat > AktSong.BPM[1].StartBeat then begin
- // analyze second BPM
- Time := Time - GetTimeForBeats(AktSong.BPM[0].BPM, AktSong.BPM[1].StartBeat - CurBeat);
- CurBeat := AktSong.BPM[1].StartBeat;
- TopBeat := GetBeats(AktSong.BPM[1].BPM, Time);
- Result := CurBeat + TopBeat;
-
- end else begin
- (* pierwszy przedzial *)
- Result := TopBeat;
- end;
- end; // if}
-
- (* more BPMs *)
- if Length(AktSong.BPM) > 1 then begin
-
- CurBeat := 0;
- CurBPM := 0;
- while (Time > 0) do begin
- GetMidBeatSub(CurBPM, Time, CurBeat);
- Inc(CurBPM);
- end;
-
- Result := CurBeat;
- end; // if
-end;
-
-function GetTimeFromBeat(Beat: integer): real;
-var
- CurBPM: integer;
-begin
- Result := 0;
- if Length(AktSong.BPM) = 1 then Result := AktSong.GAP / 1000 + Beat * 60 / AktSong.BPM[0].BPM;
-
- (* more BPMs *)
- if Length(AktSong.BPM) > 1 then begin
- Result := AktSong.GAP / 1000;
- CurBPM := 0;
- while (CurBPM <= High(AktSong.BPM)) and (Beat > AktSong.BPM[CurBPM].StartBeat) do begin
- if (CurBPM < High(AktSong.BPM)) and (Beat >= AktSong.BPM[CurBPM+1].StartBeat) then begin
- // full range
- Result := Result + (60 / AktSong.BPM[CurBPM].BPM) * (AktSong.BPM[CurBPM+1].StartBeat - AktSong.BPM[CurBPM].StartBeat);
- end;
-
- if (CurBPM = High(AktSong.BPM)) or (Beat < AktSong.BPM[CurBPM+1].StartBeat) then begin
- // in the middle
- Result := Result + (60 / AktSong.BPM[CurBPM].BPM) * (Beat - AktSong.BPM[CurBPM].StartBeat);
- end;
- Inc(CurBPM);
- end;
-
-{ while (Time > 0) do begin
- GetMidBeatSub(CurBPM, Time, CurBeat);
- Inc(CurBPM);
- end;}
- end; // if}
-end;
-
-procedure Sing(Sender: TScreenSing);
-var
- Pet: integer;
- PetGr: integer;
- CP: integer;
- Done: real;
- N: integer;
-begin
- Czas.Teraz := Czas.Teraz + TimeSkip;
-
- Czas.OldBeat := Czas.AktBeat;
- Czas.MidBeat := GetMidBeat(Czas.Teraz - (AktSong.Gap{ + 90 I've forgotten for what it is}) / 1000); // new system with variable BPM in function
- Czas.AktBeat := Floor(Czas.MidBeat);
-
-// Czas.OldHalf := Czas.AktHalf;
-// Czas.MidHalf := Czas.MidBeat + 0.5;
-// Czas.AktHalf := Floor(Czas.MidHalf);
-
- Czas.OldBeatC := Czas.AktBeatC;
- Czas.MidBeatC := GetMidBeat(Czas.Teraz - (AktSong.Gap) / 1000);
- Czas.AktBeatC := Floor(Czas.MidBeatC);
-
- Czas.OldBeatD := Czas.AktBeatD;
- Czas.MidBeatD := -0.5+GetMidBeat(Czas.Teraz - (AktSong.Gap + 120 + 20) / 1000); // MidBeat with addition GAP
- Czas.AktBeatD := Floor(Czas.MidBeatD);
- Czas.FracBeatD := Frac(Czas.MidBeatD);
-
- // sentences routines
- for PetGr := 0 to 0 do begin;//High(Gracz) do begin
- CP := PetGr;
- // ustawianie starej czesci
- Czas.OldCzesc := Czesci[CP].Akt;
-
- // wybieranie aktualnej czesci
- for Pet := 0 to Czesci[CP].High do
- if Czas.AktBeat >= Czesci[CP].Czesc[Pet].Start then Czesci[CP].Akt := Pet;
-
- // czysczenie nut gracza, gdy to jest nowa plansza
- // (optymizacja raz na halfbeat jest zla)
- if Czesci[CP].Akt <> Czas.OldCzesc then NewSentence(Sender);
-
- end; // for PetGr
-
- // wykonuje operacje raz na beat
- if (Czas.AktBeat >= 0) and (Czas.OldBeat <> Czas.AktBeat) then
- NewBeat(Sender);
-
- // make some operations on clicks
- if {(Czas.AktBeatC >= 0) and }(Czas.OldBeatC <> Czas.AktBeatC) then
- NewBeatC(Sender);
-
- // make some operations when detecting new voice pitch
- if (Czas.AktBeatD >= 0) and (Czas.OldBeatD <> Czas.AktBeatD) then
- NewBeatD(Sender);
-
- // wykonuje operacje w polowie beatu
-// if (Czas.AktHalf >= 1) and (Czas.OldHalf <> Czas.AktHalf) then
-// NewHalf;
-
- // plynnie przesuwa text
- Done := 1;
- for N := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
- if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start <= Czas.MidBeat)
- and (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start + Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc >= Czas.MidBeat) then
- Done := (Czas.MidBeat - Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start) / (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc);
-
- N := Czesci[0].Czesc[Czesci[0].Akt].HighNut;
-
- // wylacza ostatnia nute po przejsciu
- {// todo: Lyrics
- if (Ini.LyricsEffect = 1) and (Done = 1) and
- (Czas.MidBeat > Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start + Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc)
- then Sender.LyricMain.Selected := -1;
-
- if Done > 1 then Done := 1;
- Sender.LyricMain.Done := Done; }
-
- // use Done with LCD
-{ with ScreenSing do begin
- if LyricMain.Selected >= 0 then begin
- LCD.MoveCursor(1, LyricMain.SelectedLetter + Round((LyricMain.SelectedLength-1) * Done));
- LCD.ShowCursor;
- end;
- end;}
-
-
-end;
-
-procedure NewSentence(Sender: TScreenSing);
-var
-G: Integer;
-begin
- // czyszczenie nut graczy
- for G := 0 to High(Player) do begin
- Player[G].IlNut := 0;
- Player[G].HighNut := -1;
- SetLength(Player[G].Nuta, 0);
- end;
-
- // Add Words to Lyrics
- with Sender do begin
- {LyricMain.AddCzesc(Czesci[0].Akt);
- if Czesci[0].Akt < Czesci[0].High then
- LyricSub.AddCzesc(Czesci[0].Akt+1)
- else
- LyricSub.Clear;}
- while (not Lyrics.LineinQueue) AND (Lyrics.LineCounter <= High(Czesci[0].Czesc)) do
- Lyrics.AddLine(@Czesci[0].Czesc[Lyrics.LineCounter]);
- end;
-
- Sender.UpdateLCD;
-
- //On Sentence Change...
- Sender.onSentenceChange(Czesci[0].Akt);
-end;
-
-procedure NewBeat(Sender: TScreenSing);
-var
- Pet: integer;
-// TempBeat: integer;
-begin
- // ustawia zaznaczenie tekstu
-// SingScreen.LyricMain.Selected := -1;
- for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
- if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeat) then begin
- // operates on currently beated note
- //Todo: Lyrics
- //Sender.LyricMain.Selected := Pet;
-
-// LCD.MoveCursor(1, ScreenSing.LyricMain.SelectedLetter);
-// LCD.ShowCursor;
-
- //LCD.MoveCursorBR(Sender.LyricMain.SelectedLetter);
- LCD.ShowCursor;
-
- end;
-end;
-
-procedure NewBeatC;
-var
- Pet: integer;
-// LPT_1: integer;
-// LPT_2: integer;
-begin
-// LPT_1 := 1;
-// LPT_2 := 1;
-
- // beat click
- if (Ini.BeatClick = 1) and ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod Czesci[0].Resolution = 0) then
- Music.PlayClick;
-
- // debug system on LPT
- if ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod Czesci[0].Resolution = 0) then begin
- //LPT_1 := 0;
-// Light.LightOne(0, 150);
-
- Light.LightOne(1, 200); // beat light
- if ParamStr(1) = '-doublelights' then
- Light.LightOne(0, 200); // beat light
-
-
-{ if ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod (Czesci[0].Resolution * 2) = 0) then
- Light.LightOne(0, 150)
- else
- Light.LightOne(1, 150)}
- end;
-
- for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do
- if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeatC) then begin
- // click assist
- if Ini.ClickAssist = 1 then
- Music.PlayClick;
-
- //LPT_2 := 0;
- if ParamStr(1) <> '-doublelights' then
- Light.LightOne(0, 150); //125
-
-
- // drum machine
-(* TempBeat := Czas.AktBeat;// + 2;
- if (TempBeat mod 8 = 0) then Music.PlayDrum;
- if (TempBeat mod 8 = 4) then Music.PlayClap;
-// if (TempBeat mod 4 = 2) then Music.PlayHihat;
- if (TempBeat mod 4 <> 0) then Music.PlayHihat;*)
- end;
-
- {$IFDEF UseSerialPort}
- // PortWriteB($378, LPT_1 + LPT_2 * 2); // 0 zapala
- {$ENDIF}
-end;
-
-procedure NewBeatD(Sender: TScreenSing);
-begin
- NewNote(Sender);
-end;
-
-//procedure NewHalf;
-//begin
-// NewNote;
-//end;
-
-procedure NewNote(Sender: TScreenSing);
-var
- CP: integer; // current player
- S: integer; // sentence
- SMin: integer;
- SMax: integer;
- SDet: integer; // temporary: sentence of detected note
- Pet: integer;
- Mozna: boolean;
- Nowa: boolean;
- Range: integer;
- NoteHit:boolean;
-begin
-// Log.LogStatus('Beat ' + IntToStr(Czas.AktBeat) + ' HalfBeat ' + IntToStr(Czas.AktHalf), 'NewBeat');
-// beep;
-
- // analizuje dla obu graczy ten sam sygnal (Sound.OneSrcForBoth)
- // albo juz lepiej nie
- for CP := 0 to PlayersPlay-1 do begin
-
- // analyze buffer
- Sound[CP].AnalizujBufor;
-
- // adds some noise
-// Czas.Ton := Czas.Ton + Round(Random(3)) - 1;
-
- // 0.5.0: count min and max sentence range for checking (detection is delayed to the notes we see on the screen)
- SMin := Czesci[0].Akt-1;
- if SMin < 0 then SMin := 0;
- SMax := Czesci[0].Akt;
-
- // check if we can add new note
- Mozna := false;
- SDet:=SMin;
- for S := SMin to SMax do
- for Pet := 0 to Czesci[0].Czesc[S].HighNut do
- if ((Czesci[0].Czesc[S].Nuta[Pet].Start <= Czas.AktBeatD)
- and (Czesci[0].Czesc[S].Nuta[Pet].Start + Czesci[0].Czesc[S].Nuta[Pet].Dlugosc - 1 >= Czas.AktBeatD))
- and (not Czesci[0].Czesc[S].Nuta[Pet].FreeStyle) // but don't allow when it's FreeStyle note
- and (Czesci[0].Czesc[S].Nuta[Pet].Dlugosc > 0) // and make sure the note lenghts is at least 1
- then begin
- SDet := S;
- Mozna := true;
- Break;
- end;
-
- S := SDet;
-
-
-
-
-
-// Czas.SzczytJest := true;
-// Czas.Ton := 27;
-
- // gdy moze, to dodaje nute
- if (Sound[CP].SzczytJest) and (Mozna) then begin
- // operowanie na ostatniej nucie
- for Pet := 0 to Czesci[0].Czesc[S].HighNut do
- if (Czesci[0].Czesc[S].Nuta[Pet].Start <= Czas.OldBeatD+1)
- and (Czesci[0].Czesc[S].Nuta[Pet].Start +
- Czesci[0].Czesc[S].Nuta[Pet].Dlugosc > Czas.OldBeatD+1) then begin
- // to robi, tylko dla pary nut (oryginalnej i gracza)
-
- // przesuwanie tonu w odpowiednia game
- while (Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton > 6) do
- Sound[CP].Ton := Sound[CP].Ton - 12;
- while (Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton < -6) do
- Sound[CP].Ton := Sound[CP].Ton + 12;
-
- // Half size Notes Patch
- NoteHit := false;
-
- //if Ini.Difficulty = 0 then Range := 2;
- //if Ini.Difficulty = 1 then Range := 1;
- //if Ini.Difficulty = 2 then Range := 0;
- Range := 2 - Ini.Difficulty;
- if abs(Czesci[0].Czesc[S].Nuta[Pet].Ton - Sound[CP].Ton) <= Range then begin
- Sound[CP].Ton := Czesci[0].Czesc[S].Nuta[Pet].Ton;
-
-
- // Half size Notes Patch
- NoteHit := true;
-
-
- if (Ini.LineBonus = 0) then
- begin
- // add points without LineBonus
- case Czesci[0].Czesc[S].Nuta[Pet].Wartosc of
- 1: Player[CP].Score := Player[CP].Score + 10000 / Czesci[0].Wartosc *
- Czesci[0].Czesc[S].Nuta[Pet].Wartosc;
- 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 10000 / Czesci[0].Wartosc *
- Czesci[0].Czesc[S].Nuta[Pet].Wartosc;
- end;
- end
- else
- begin
- // add points with Line Bonus
- case Czesci[0].Czesc[S].Nuta[Pet].Wartosc of
- 1: Player[CP].Score := Player[CP].Score + 9000 / Czesci[0].Wartosc *
- Czesci[0].Czesc[S].Nuta[Pet].Wartosc;
- 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 9000 / Czesci[0].Wartosc *
- Czesci[0].Czesc[S].Nuta[Pet].Wartosc;
- end;
- end;
-
- Player[CP].ScoreI := Floor(Player[CP].Score / 10) * 10;
- Player[CP].ScoreGoldenI := Floor(Player[CP].ScoreGolden / 10) * 10;
-
- Player[CP].ScoreTotalI := Player[CP].ScoreI + Player[CP].ScoreGoldenI + Player[CP].ScoreLineI;
- end;
-
- end; // operowanie
-
- // sprawdzanie czy to nowa nuta, czy przedluzenie
- if S = SMax then begin
- Nowa := true;
- // jezeli ostatnia ma ten sam ton
- if (Player[CP].IlNut > 0 ) and (Player[CP].Nuta[Player[CP].HighNut].Ton = Sound[CP].Ton)
- and (Player[CP].Nuta[Player[CP].HighNut].Start + Player[CP].Nuta[Player[CP].HighNut].Dlugosc = Czas.AktBeatD)
- then Nowa := false;
- // jezeli jest jakas nowa nuta na sprawdzanym beacie
- for Pet := 0 to Czesci[0].Czesc[S].HighNut do
- if (Czesci[0].Czesc[S].Nuta[Pet].Start = Czas.AktBeatD) then
- Nowa := true;
-
- // dodawanie nowej nuty
- if Nowa then begin
- // nowa nuta
- Player[CP].IlNut := Player[CP].IlNut + 1;
- Player[CP].HighNut := Player[CP].HighNut + 1;
- SetLength(Player[CP].Nuta, Player[CP].IlNut);
- Player[CP].Nuta[Player[CP].HighNut].Start := Czas.AktBeatD;
- Player[CP].Nuta[Player[CP].HighNut].Dlugosc := 1;
- Player[CP].Nuta[Player[CP].HighNut].Ton := Sound[CP].Ton; // Ton || TonDokl
- Player[CP].Nuta[Player[CP].HighNut].Detekt := Czas.MidBeat;
-
-
- // Half Note Patch
- Player[CP].Nuta[Player[CP].HighNut].Hit := NoteHit;
-
-
- // Log.LogStatus('Nowa Nuta ' + IntToStr(Gracz.Nuta[Gracz.HighNut].Start), 'NewBeat');
-
- end else begin
- // przedluzenie nuty
- Player[CP].Nuta[Player[CP].HighNut].Dlugosc := Player[CP].Nuta[Player[CP].HighNut].Dlugosc + 1;
- end;
-
-
- // check for perfect note and then lit the star (on Draw)
- for Pet := 0 to Czesci[0].Czesc[S].HighNut do
- if (Czesci[0].Czesc[S].Nuta[Pet].Start = Player[CP].Nuta[Player[CP].HighNut].Start)
- and (Czesci[0].Czesc[S].Nuta[Pet].Dlugosc = Player[CP].Nuta[Player[CP].HighNut].Dlugosc)
- and (Czesci[0].Czesc[S].Nuta[Pet].Ton = Player[CP].Nuta[Player[CP].HighNut].Ton) then begin
- Player[CP].Nuta[Player[CP].HighNut].Perfect := true;
- end;
-
- end;// else beep; // if S = SMax
-
- end; // if moze
- end; // for CP
-// Log.LogStatus('EndBeat', 'NewBeat');
-
-//On Sentence End -> For LineBonus + SingBar
-if (sDet >= low(Czesci[0].Czesc)) AND (sDet <= high(Czesci[0].Czesc)) then
-if ((Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Start + Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Dlugosc - 1) = Czas.AktBeatD) then
- Sender.onSentenceEnd(sDet);
-
-end;
-
-procedure ClearScores(PlayerNum: integer);
-begin
- Player[PlayerNum].Score := 0;
- Player[PlayerNum].ScoreI := 0;
- Player[PlayerNum].ScoreLine := 0;
- Player[PlayerNum].ScoreLineI := 0;
- Player[PlayerNum].ScoreGolden := 0;
- Player[PlayerNum].ScoreGoldenI := 0;
- Player[PlayerNum].ScoreTotalI := 0;
-end;
-
-//--------------------
-// Function sets all Absolute Paths e.g. Song Path and makes sure the Directorys exist
-//--------------------
-procedure InitializePaths;
-
- // Initialize a Path Variable
- // After Setting Paths, make sure that Paths exist
- function initialize_path( out aPathVar : String; const aLocation : String ): boolean;
- var
- lWriteable: Boolean;
- lAttrib : integer;
- begin
- lWriteable := false;
- aPathVar := aLocation;
-
- // Make sure the directory is needex
- ForceDirectories(aPathVar);
-
- If DirectoryExists(aPathVar) then
- begin
- lAttrib := fileGetAttr('C:Temp');
-
- lWriteable := ( lAttrib and faDirectory <> 0 ) AND
- NOT ( lAttrib and faReadOnly <> 0 )
- end;
-
- if not lWriteable then
- Log.LogError('Error: Dir ('+ aLocation +') is Readonly');
-
- result := lWriteable;
- end;
-
-begin
-
- GamePath := ExtractFilePath(ParamStr(0));
-
- initialize_path( LogPath , GamePath );
- initialize_path( SoundPath , GamePath + 'Sounds' + PathDelim );
- initialize_path( SongPath , GamePath + 'Songs' + PathDelim );
- initialize_path( ThemePath , GamePath + 'Themes' + PathDelim );
- initialize_path( ScreenshotsPath , GamePath + 'Screenshots' + PathDelim );
- initialize_path( CoversPath , GamePath + 'Covers' + PathDelim );
- initialize_path( LanguagesPath , GamePath + 'Languages' + PathDelim );
- initialize_path( PluginPath , GamePath + 'Plugins' + PathDelim );
- initialize_path( PlaylistPath , GamePath + 'Playlists' + PathDelim );
-
- DecimalSeparator := ',';
-end;
-
-end.
-
+unit UMain; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses + SDL, + UGraphic, + UMusic, + URecord, + UTime, + SysUtils, + UDisplay, + UIni, + ULog, + ULyrics, + UScreenSing, + OpenGL12, + {$IFDEF UseSerialPort} + zlportio {you can disable it and all PortWriteB calls}, + {$ENDIF} + ULCD, + ULight, + UThemes; + +type + TPlayer = record + Name: string; + + Score: real; + ScoreLine: real; + ScoreGolden: real; + + ScoreI: integer; + ScoreLineI: integer; + ScoreGoldenI: integer; + ScoreTotalI: integer; + + + + //LineBonus Mod + ScoreLast: Real;//Last Line Score + {ScorePercent: integer;//Aktual Fillstate of the SingBar + ScorePercentTarget: integer;//Target Fillstate of the SingBar + //end Singbar Mod + + //PhrasenBonus - Line Bonus Mod + LineBonus_PosX: Single; + LineBonus_PosY: Single; + LineBonus_Alpha: Single; + LineBonus_Visible: boolean; + LineBonus_Text: string; + LineBonus_Color: TRGB; + LineBonus_Age: Integer; + LineBonus_Rating: Integer; + //Variable vor Positioning -> Set on ScreenShow, different when Playercount Changes + LineBonus_TargetX: integer; + LineBonus_TargetY: integer; + LineBonus_StartX: integer; + LineBonus_StartY: integer; + //PhrasenBonus - Line Bonus Mod End } + + + //PerfectLineTwinkle Mod (effect) + LastSentencePerfect: Boolean; + //PerfectLineTwinkle Mod end + + +// Meter: real; + + HighNut: integer; + IlNut: integer; + Nuta: array of record + Start: integer; + Dlugosc: integer; + Detekt: real; // dokladne miejsce, w ktorym wykryto ta nute + Ton: real; + Perfect: boolean; // true if the note matches the original one, lit the star + + + + // Half size Notes Patch + Hit: boolean; // true if the note Hits the Line + //end Half size Notes Patch + + + + end; + end; + + +var + //Absolute Paths + GamePath: string; + SoundPath: string; + SongPath: string; + LogPath: string; + ThemePath: string; + ScreenshotsPath: string; + CoversPath: string; + LanguagesPath: string; + PluginPath: string; + PlayListPath: string; + + OGL: Boolean; + Done: Boolean; + Event: TSDL_event; + FileName: string; + Restart: boolean; + + // gracz i jego nuty + Player: array of TPlayer; + PlayersPlay: integer; + +procedure InitializePaths; + +procedure MainLoop; +procedure CheckEvents; +procedure Sing(Sender: TScreenSing); +procedure NewSentence(Sender: TScreenSing); +procedure NewBeat(Sender: TScreenSing); // executed when on then new beat +procedure NewBeatC(Sender: TScreenSing); // executed when on then new beat for click +procedure NewBeatD(Sender: TScreenSing); // executed when on then new beat for detection +//procedure NewHalf; // executed when in the half between beats +procedure NewNote(Sender: TScreenSing); // detect note +function GetMidBeat(Time: real): real; +function GetTimeFromBeat(Beat: integer): real; +procedure ClearScores(PlayerNum: integer); + +implementation +uses USongs, UJoystick, math, UCommandLine; + +procedure MainLoop; +var + Delay: integer; +begin + SDL_EnableKeyRepeat(125, 125); + While not Done do + Begin + // joypad + if (Ini.Joypad = 1) OR (Params.Joypad) then + Joy.Update; + + // keyboard events + CheckEvents; + + // display + done := not Display.Draw; + SwapBuffers; + + // light + Light.Refresh; + + // delay + CountMidTime; +// if 1000*TimeMid > 100 then beep; + Delay := Floor(1000 / 100 - 1000 * TimeMid); + + if Delay >= 1 then + SDL_Delay(Delay); // dynamic, maximum is 100 fps + + CountSkipTime; + + // reinitialization of graphics + if Restart then begin + Reinitialize3D; + Restart := false; + end; + + End; + UnloadOpenGL; +End; + +Procedure CheckEvents; +//var +// p: pointer; +Begin + if not Assigned(Display.NextScreen) then + While SDL_PollEvent( @event ) = 1 Do + Begin +// beep; + Case Event.type_ Of + SDL_QUITEV: begin + Display.Fade := 0; + Display.NextScreenWithCheck := nil; + Display.CheckOK := True; + end; +{ SDL_MOUSEBUTTONDOWN: + With Event.button Do + Begin + If State = SDL_BUTTON_LEFT Then + Begin + // + End; + End; // With} + SDL_KEYDOWN: + begin + //ScreenShot hack. If Print is pressed-> Make screenshot and Save to Screenshots Path + if (Event.key.keysym.sym = SDLK_SYSREQ) then + Display.ScreenShot + + // popup hack... if there is a visible popup then let it handle input instead of underlying screen + // shoud be done in a way to be sure the topmost popup has preference (maybe error, then check) + else if (ScreenPopupError <> NIL) and (ScreenPopupError.Visible) then + done := not ScreenPopupError.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True) + else if (ScreenPopupCheck <> NIL) AND (ScreenPopupCheck.Visible) then + done := not ScreenPopupCheck.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True) + // end of popup hack + + else + begin + // check for Screen want to Exit + done := Not Display.ActualScreen^.ParseInput(Event.key.keysym.sym, Event.key.keysym.unicode, True); + + //If Screen wants to Exit + if done then + begin + //If Question Option is enabled then Show Exit Popup + if (Ini.AskbeforeDel = 1) then + begin + Display.ActualScreen^.CheckFadeTo(NIL,'MSG_QUIT_USDX'); + end + else //When asking for exit is disabled then simply exit + begin + Display.Fade := 0; + Display.NextScreenWithCheck := nil; + Display.CheckOK := True; + end; + end; + + end; // if (Not Display.ActualScreen^.ParseInput(Event.key.keysym.scancode, True)) then + end; +// SDL_JOYAXISMOTION: +// begin +// beep +// end; + SDL_JOYBUTTONDOWN: + begin + beep + end; + End; // Case Event.type_ + End; // While +End; // CheckEvents + +function GetTimeForBeats(BPM, Beats: real): real; +begin + Result := 60 / BPM * Beats; +end; + +function GetBeats(BPM, msTime: real): real; +begin + Result := BPM * msTime / 60; +end; + +procedure GetMidBeatSub(BPMNum: integer; var Time: real; var CurBeat: real); +var + NewTime: real; +begin + if High(AktSong.BPM) = BPMNum then begin + // last BPM + CurBeat := AktSong.BPM[BPMNum].StartBeat + GetBeats(AktSong.BPM[BPMNum].BPM, Time); + Time := 0; + end else begin + // not last BPM + // count how much time is it for start of the new BPM and store it in NewTime + NewTime := GetTimeForBeats(AktSong.BPM[BPMNum].BPM, AktSong.BPM[BPMNum+1].StartBeat - AktSong.BPM[BPMNum].StartBeat); + + // compare it to remaining time + if (Time - NewTime) > 0 then begin + // there is still remaining time + CurBeat := AktSong.BPM[BPMNum].StartBeat; + Time := Time - NewTime; + end else begin + // there is no remaining time + CurBeat := AktSong.BPM[BPMNum].StartBeat + GetBeats(AktSong.BPM[BPMNum].BPM, Time); + Time := 0; + end; // if + end; // if +end; + +function GetMidBeat(Time: real): real; +var + CurBeat: real; + CurBPM: integer; +// TopBeat: real; +// TempBeat: real; +// TempTime: real; +begin + Result := 0; + if Length(AktSong.BPM) = 1 then Result := Time * AktSong.BPM[0].BPM / 60; + + (* 2 BPMs *) +{ if Length(AktSong.BPM) > 1 then begin + (* new system *) + CurBeat := 0; + TopBeat := GetBeats(AktSong.BPM[0].BPM, Time); + if TopBeat > AktSong.BPM[1].StartBeat then begin + // analyze second BPM + Time := Time - GetTimeForBeats(AktSong.BPM[0].BPM, AktSong.BPM[1].StartBeat - CurBeat); + CurBeat := AktSong.BPM[1].StartBeat; + TopBeat := GetBeats(AktSong.BPM[1].BPM, Time); + Result := CurBeat + TopBeat; + + end else begin + (* pierwszy przedzial *) + Result := TopBeat; + end; + end; // if} + + (* more BPMs *) + if Length(AktSong.BPM) > 1 then begin + + CurBeat := 0; + CurBPM := 0; + while (Time > 0) do begin + GetMidBeatSub(CurBPM, Time, CurBeat); + Inc(CurBPM); + end; + + Result := CurBeat; + end; // if +end; + +function GetTimeFromBeat(Beat: integer): real; +var + CurBPM: integer; +begin + Result := 0; + if Length(AktSong.BPM) = 1 then Result := AktSong.GAP / 1000 + Beat * 60 / AktSong.BPM[0].BPM; + + (* more BPMs *) + if Length(AktSong.BPM) > 1 then begin + Result := AktSong.GAP / 1000; + CurBPM := 0; + while (CurBPM <= High(AktSong.BPM)) and (Beat > AktSong.BPM[CurBPM].StartBeat) do begin + if (CurBPM < High(AktSong.BPM)) and (Beat >= AktSong.BPM[CurBPM+1].StartBeat) then begin + // full range + Result := Result + (60 / AktSong.BPM[CurBPM].BPM) * (AktSong.BPM[CurBPM+1].StartBeat - AktSong.BPM[CurBPM].StartBeat); + end; + + if (CurBPM = High(AktSong.BPM)) or (Beat < AktSong.BPM[CurBPM+1].StartBeat) then begin + // in the middle + Result := Result + (60 / AktSong.BPM[CurBPM].BPM) * (Beat - AktSong.BPM[CurBPM].StartBeat); + end; + Inc(CurBPM); + end; + +{ while (Time > 0) do begin + GetMidBeatSub(CurBPM, Time, CurBeat); + Inc(CurBPM); + end;} + end; // if} +end; + +procedure Sing(Sender: TScreenSing); +var + Pet: integer; + PetGr: integer; + CP: integer; + Done: real; + N: integer; +begin + Czas.Teraz := Czas.Teraz + TimeSkip; + + Czas.OldBeat := Czas.AktBeat; + Czas.MidBeat := GetMidBeat(Czas.Teraz - (AktSong.Gap{ + 90 I've forgotten for what it is}) / 1000); // new system with variable BPM in function + Czas.AktBeat := Floor(Czas.MidBeat); + +// Czas.OldHalf := Czas.AktHalf; +// Czas.MidHalf := Czas.MidBeat + 0.5; +// Czas.AktHalf := Floor(Czas.MidHalf); + + Czas.OldBeatC := Czas.AktBeatC; + Czas.MidBeatC := GetMidBeat(Czas.Teraz - (AktSong.Gap) / 1000); + Czas.AktBeatC := Floor(Czas.MidBeatC); + + Czas.OldBeatD := Czas.AktBeatD; + Czas.MidBeatD := -0.5+GetMidBeat(Czas.Teraz - (AktSong.Gap + 120 + 20) / 1000); // MidBeat with addition GAP + Czas.AktBeatD := Floor(Czas.MidBeatD); + Czas.FracBeatD := Frac(Czas.MidBeatD); + + // sentences routines + for PetGr := 0 to 0 do begin;//High(Gracz) do begin + CP := PetGr; + // ustawianie starej czesci + Czas.OldCzesc := Czesci[CP].Akt; + + // wybieranie aktualnej czesci + for Pet := 0 to Czesci[CP].High do + if Czas.AktBeat >= Czesci[CP].Czesc[Pet].Start then Czesci[CP].Akt := Pet; + + // czysczenie nut gracza, gdy to jest nowa plansza + // (optymizacja raz na halfbeat jest zla) + if Czesci[CP].Akt <> Czas.OldCzesc then NewSentence(Sender); + + end; // for PetGr + + // wykonuje operacje raz na beat + if (Czas.AktBeat >= 0) and (Czas.OldBeat <> Czas.AktBeat) then + NewBeat(Sender); + + // make some operations on clicks + if {(Czas.AktBeatC >= 0) and }(Czas.OldBeatC <> Czas.AktBeatC) then + NewBeatC(Sender); + + // make some operations when detecting new voice pitch + if (Czas.AktBeatD >= 0) and (Czas.OldBeatD <> Czas.AktBeatD) then + NewBeatD(Sender); + + // wykonuje operacje w polowie beatu +// if (Czas.AktHalf >= 1) and (Czas.OldHalf <> Czas.AktHalf) then +// NewHalf; + + // plynnie przesuwa text + Done := 1; + for N := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do + if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start <= Czas.MidBeat) + and (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start + Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc >= Czas.MidBeat) then + Done := (Czas.MidBeat - Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start) / (Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc); + + N := Czesci[0].Czesc[Czesci[0].Akt].HighNut; + + // wylacza ostatnia nute po przejsciu + {// todo: Lyrics + if (Ini.LyricsEffect = 1) and (Done = 1) and + (Czas.MidBeat > Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Start + Czesci[0].Czesc[Czesci[0].Akt].Nuta[N].Dlugosc) + then Sender.LyricMain.Selected := -1; + + if Done > 1 then Done := 1; + Sender.LyricMain.Done := Done; } + + // use Done with LCD +{ with ScreenSing do begin + if LyricMain.Selected >= 0 then begin + LCD.MoveCursor(1, LyricMain.SelectedLetter + Round((LyricMain.SelectedLength-1) * Done)); + LCD.ShowCursor; + end; + end;} + + +end; + +procedure NewSentence(Sender: TScreenSing); +var +G: Integer; +begin + // czyszczenie nut graczy + for G := 0 to High(Player) do begin + Player[G].IlNut := 0; + Player[G].HighNut := -1; + SetLength(Player[G].Nuta, 0); + end; + + // Add Words to Lyrics + with Sender do begin + {LyricMain.AddCzesc(Czesci[0].Akt); + if Czesci[0].Akt < Czesci[0].High then + LyricSub.AddCzesc(Czesci[0].Akt+1) + else + LyricSub.Clear;} + while (not Lyrics.LineinQueue) AND (Lyrics.LineCounter <= High(Czesci[0].Czesc)) do + Lyrics.AddLine(@Czesci[0].Czesc[Lyrics.LineCounter]); + end; + + Sender.UpdateLCD; + + //On Sentence Change... + Sender.onSentenceChange(Czesci[0].Akt); +end; + +procedure NewBeat(Sender: TScreenSing); +var + Pet: integer; +// TempBeat: integer; +begin + // ustawia zaznaczenie tekstu +// SingScreen.LyricMain.Selected := -1; + for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do + if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeat) then begin + // operates on currently beated note + //Todo: Lyrics + //Sender.LyricMain.Selected := Pet; + +// LCD.MoveCursor(1, ScreenSing.LyricMain.SelectedLetter); +// LCD.ShowCursor; + + //LCD.MoveCursorBR(Sender.LyricMain.SelectedLetter); + LCD.ShowCursor; + + end; +end; + +procedure NewBeatC; +var + Pet: integer; +// LPT_1: integer; +// LPT_2: integer; +begin +// LPT_1 := 1; +// LPT_2 := 1; + + // beat click + if (Ini.BeatClick = 1) and ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod Czesci[0].Resolution = 0) then + Music.PlayClick; + + // debug system on LPT + if ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod Czesci[0].Resolution = 0) then begin + //LPT_1 := 0; +// Light.LightOne(0, 150); + + Light.LightOne(1, 200); // beat light + if ParamStr(1) = '-doublelights' then + Light.LightOne(0, 200); // beat light + + +{ if ((Czas.AktBeatC + Czesci[0].Resolution + Czesci[0].NotesGAP) mod (Czesci[0].Resolution * 2) = 0) then + Light.LightOne(0, 150) + else + Light.LightOne(1, 150)} + end; + + for Pet := 0 to Czesci[0].Czesc[Czesci[0].Akt].HighNut do + if (Czesci[0].Czesc[Czesci[0].Akt].Nuta[Pet].Start = Czas.AktBeatC) then begin + // click assist + if Ini.ClickAssist = 1 then + Music.PlayClick; + + //LPT_2 := 0; + if ParamStr(1) <> '-doublelights' then + Light.LightOne(0, 150); //125 + + + // drum machine +(* TempBeat := Czas.AktBeat;// + 2; + if (TempBeat mod 8 = 0) then Music.PlayDrum; + if (TempBeat mod 8 = 4) then Music.PlayClap; +// if (TempBeat mod 4 = 2) then Music.PlayHihat; + if (TempBeat mod 4 <> 0) then Music.PlayHihat;*) + end; + + {$IFDEF UseSerialPort} + // PortWriteB($378, LPT_1 + LPT_2 * 2); // 0 zapala + {$ENDIF} +end; + +procedure NewBeatD(Sender: TScreenSing); +begin + NewNote(Sender); +end; + +//procedure NewHalf; +//begin +// NewNote; +//end; + +procedure NewNote(Sender: TScreenSing); +var + CP: integer; // current player + S: integer; // sentence + SMin: integer; + SMax: integer; + SDet: integer; // temporary: sentence of detected note + Pet: integer; + Mozna: boolean; + Nowa: boolean; + Range: integer; + NoteHit:boolean; +begin +// Log.LogStatus('Beat ' + IntToStr(Czas.AktBeat) + ' HalfBeat ' + IntToStr(Czas.AktHalf), 'NewBeat'); +// beep; + + // analizuje dla obu graczy ten sam sygnal (Sound.OneSrcForBoth) + // albo juz lepiej nie + for CP := 0 to PlayersPlay-1 do begin + + // analyze buffer + Sound[CP].AnalizujBufor; + + // adds some noise +// Czas.Ton := Czas.Ton + Round(Random(3)) - 1; + + // 0.5.0: count min and max sentence range for checking (detection is delayed to the notes we see on the screen) + SMin := Czesci[0].Akt-1; + if SMin < 0 then SMin := 0; + SMax := Czesci[0].Akt; + + // check if we can add new note + Mozna := false; + SDet:=SMin; + for S := SMin to SMax do + for Pet := 0 to Czesci[0].Czesc[S].HighNut do + if ((Czesci[0].Czesc[S].Nuta[Pet].Start <= Czas.AktBeatD) + and (Czesci[0].Czesc[S].Nuta[Pet].Start + Czesci[0].Czesc[S].Nuta[Pet].Dlugosc - 1 >= Czas.AktBeatD)) + and (not Czesci[0].Czesc[S].Nuta[Pet].FreeStyle) // but don't allow when it's FreeStyle note + and (Czesci[0].Czesc[S].Nuta[Pet].Dlugosc > 0) // and make sure the note lenghts is at least 1 + then begin + SDet := S; + Mozna := true; + Break; + end; + + S := SDet; + + + + + +// Czas.SzczytJest := true; +// Czas.Ton := 27; + + // gdy moze, to dodaje nute + if (Sound[CP].SzczytJest) and (Mozna) then begin + // operowanie na ostatniej nucie + for Pet := 0 to Czesci[0].Czesc[S].HighNut do + if (Czesci[0].Czesc[S].Nuta[Pet].Start <= Czas.OldBeatD+1) + and (Czesci[0].Czesc[S].Nuta[Pet].Start + + Czesci[0].Czesc[S].Nuta[Pet].Dlugosc > Czas.OldBeatD+1) then begin + // to robi, tylko dla pary nut (oryginalnej i gracza) + + // przesuwanie tonu w odpowiednia game + while (Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton > 6) do + Sound[CP].Ton := Sound[CP].Ton - 12; + while (Sound[CP].Ton - Czesci[0].Czesc[S].Nuta[Pet].Ton < -6) do + Sound[CP].Ton := Sound[CP].Ton + 12; + + // Half size Notes Patch + NoteHit := false; + + //if Ini.Difficulty = 0 then Range := 2; + //if Ini.Difficulty = 1 then Range := 1; + //if Ini.Difficulty = 2 then Range := 0; + Range := 2 - Ini.Difficulty; + if abs(Czesci[0].Czesc[S].Nuta[Pet].Ton - Sound[CP].Ton) <= Range then begin + Sound[CP].Ton := Czesci[0].Czesc[S].Nuta[Pet].Ton; + + + // Half size Notes Patch + NoteHit := true; + + + if (Ini.LineBonus = 0) then + begin + // add points without LineBonus + case Czesci[0].Czesc[S].Nuta[Pet].Wartosc of + 1: Player[CP].Score := Player[CP].Score + 10000 / Czesci[0].Wartosc * + Czesci[0].Czesc[S].Nuta[Pet].Wartosc; + 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 10000 / Czesci[0].Wartosc * + Czesci[0].Czesc[S].Nuta[Pet].Wartosc; + end; + end + else + begin + // add points with Line Bonus + case Czesci[0].Czesc[S].Nuta[Pet].Wartosc of + 1: Player[CP].Score := Player[CP].Score + 9000 / Czesci[0].Wartosc * + Czesci[0].Czesc[S].Nuta[Pet].Wartosc; + 2: Player[CP].ScoreGolden := Player[CP].ScoreGolden + 9000 / Czesci[0].Wartosc * + Czesci[0].Czesc[S].Nuta[Pet].Wartosc; + end; + end; + + Player[CP].ScoreI := Floor(Player[CP].Score / 10) * 10; + Player[CP].ScoreGoldenI := Floor(Player[CP].ScoreGolden / 10) * 10; + + Player[CP].ScoreTotalI := Player[CP].ScoreI + Player[CP].ScoreGoldenI + Player[CP].ScoreLineI; + end; + + end; // operowanie + + // sprawdzanie czy to nowa nuta, czy przedluzenie + if S = SMax then begin + Nowa := true; + // jezeli ostatnia ma ten sam ton + if (Player[CP].IlNut > 0 ) and (Player[CP].Nuta[Player[CP].HighNut].Ton = Sound[CP].Ton) + and (Player[CP].Nuta[Player[CP].HighNut].Start + Player[CP].Nuta[Player[CP].HighNut].Dlugosc = Czas.AktBeatD) + then Nowa := false; + // jezeli jest jakas nowa nuta na sprawdzanym beacie + for Pet := 0 to Czesci[0].Czesc[S].HighNut do + if (Czesci[0].Czesc[S].Nuta[Pet].Start = Czas.AktBeatD) then + Nowa := true; + + // dodawanie nowej nuty + if Nowa then begin + // nowa nuta + Player[CP].IlNut := Player[CP].IlNut + 1; + Player[CP].HighNut := Player[CP].HighNut + 1; + SetLength(Player[CP].Nuta, Player[CP].IlNut); + Player[CP].Nuta[Player[CP].HighNut].Start := Czas.AktBeatD; + Player[CP].Nuta[Player[CP].HighNut].Dlugosc := 1; + Player[CP].Nuta[Player[CP].HighNut].Ton := Sound[CP].Ton; // Ton || TonDokl + Player[CP].Nuta[Player[CP].HighNut].Detekt := Czas.MidBeat; + + + // Half Note Patch + Player[CP].Nuta[Player[CP].HighNut].Hit := NoteHit; + + + // Log.LogStatus('Nowa Nuta ' + IntToStr(Gracz.Nuta[Gracz.HighNut].Start), 'NewBeat'); + + end else begin + // przedluzenie nuty + Player[CP].Nuta[Player[CP].HighNut].Dlugosc := Player[CP].Nuta[Player[CP].HighNut].Dlugosc + 1; + end; + + + // check for perfect note and then lit the star (on Draw) + for Pet := 0 to Czesci[0].Czesc[S].HighNut do + if (Czesci[0].Czesc[S].Nuta[Pet].Start = Player[CP].Nuta[Player[CP].HighNut].Start) + and (Czesci[0].Czesc[S].Nuta[Pet].Dlugosc = Player[CP].Nuta[Player[CP].HighNut].Dlugosc) + and (Czesci[0].Czesc[S].Nuta[Pet].Ton = Player[CP].Nuta[Player[CP].HighNut].Ton) then begin + Player[CP].Nuta[Player[CP].HighNut].Perfect := true; + end; + + end;// else beep; // if S = SMax + + end; // if moze + end; // for CP +// Log.LogStatus('EndBeat', 'NewBeat'); + +//On Sentence End -> For LineBonus + SingBar +if (sDet >= low(Czesci[0].Czesc)) AND (sDet <= high(Czesci[0].Czesc)) then +if ((Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Start + Czesci[0].Czesc[SDet].Nuta[Czesci[0].Czesc[SDet].HighNut].Dlugosc - 1) = Czas.AktBeatD) then + Sender.onSentenceEnd(sDet); + +end; + +procedure ClearScores(PlayerNum: integer); +begin + Player[PlayerNum].Score := 0; + Player[PlayerNum].ScoreI := 0; + Player[PlayerNum].ScoreLine := 0; + Player[PlayerNum].ScoreLineI := 0; + Player[PlayerNum].ScoreGolden := 0; + Player[PlayerNum].ScoreGoldenI := 0; + Player[PlayerNum].ScoreTotalI := 0; +end; + +//-------------------- +// Function sets all Absolute Paths e.g. Song Path and makes sure the Directorys exist +//-------------------- +procedure InitializePaths; + + // Initialize a Path Variable + // After Setting Paths, make sure that Paths exist + function initialize_path( out aPathVar : String; const aLocation : String ): boolean; + var + lWriteable: Boolean; + lAttrib : integer; + begin + lWriteable := false; + aPathVar := aLocation; + + // Make sure the directory is needex + ForceDirectories(aPathVar); + + If DirectoryExists(aPathVar) then + begin + lAttrib := fileGetAttr('C:Temp'); + + lWriteable := ( lAttrib and faDirectory <> 0 ) AND + NOT ( lAttrib and faReadOnly <> 0 ) + end; + + if not lWriteable then + Log.LogError('Error: Dir ('+ aLocation +') is Readonly'); + + result := lWriteable; + end; + +begin + + GamePath := ExtractFilePath(ParamStr(0)); + + initialize_path( LogPath , GamePath ); + initialize_path( SoundPath , GamePath + 'Sounds' + PathDelim ); + initialize_path( SongPath , GamePath + 'Songs' + PathDelim ); + initialize_path( ThemePath , GamePath + 'Themes' + PathDelim ); + initialize_path( ScreenshotsPath , GamePath + 'Screenshots' + PathDelim ); + initialize_path( CoversPath , GamePath + 'Covers' + PathDelim ); + initialize_path( LanguagesPath , GamePath + 'Languages' + PathDelim ); + initialize_path( PluginPath , GamePath + 'Plugins' + PathDelim ); + initialize_path( PlaylistPath , GamePath + 'Playlists' + PathDelim ); + + DecimalSeparator := ','; +end; + +end. + diff --git a/Game/Code/Classes/UMusic.pas b/Game/Code/Classes/UMusic.pas index b9f93b29..b3729e69 100644 --- a/Game/Code/Classes/UMusic.pas +++ b/Game/Code/Classes/UMusic.pas @@ -1,735 +1,738 @@ -unit UMusic;
-
-interface
-
-{$I switches.inc}
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-
-uses Classes,
- {$IFDEF win32}
- windows,
- {$ENDIF}
- UCommon,
- Messages,
- SysUtils,
- {$IFNDEF FPC}
- Forms,
- {$ENDIF}
- {$IFDEF useBASS}
- bass,
- {$ENDIF}
- ULog,
- USongs;
-
-
-procedure InitializeSound;
-
-type
- TSoundCard = record
- Name: string;
- Source: array of string;
- end;
-
- TFFTData = array [0..256] of Single;
-
- TCustomSoundEntry = record
- Filename : String;
- Handle : hStream;
- end;
-
-
- TMusic = class
- private
- BassStart: hStream; // Wait, I've replaced this with BASS
- BassBack: hStream; // It has almost all features we need
- BassSwoosh: hStream;
- BassChange: hStream; // Almost? It aleady has them all :)
- BassOption: hStream;
- BassClick: hStream;
- BassDrum: hStream;
- BassHihat: hStream;
- BassClap: hStream;
- BassShuffle: hStream;
-
- //Custom Sounds
- CustomSounds: array of TCustomSoundEntry;
-
-
- Loaded: boolean;
- Loop: boolean;
- public
- Bass: hStream;
- procedure InitializePlayback;
- procedure InitializeRecord;
- procedure SetVolume(Volume: integer);
- procedure SetMusicVolume(Volume: integer);
- procedure SetLoop(Enabled: boolean);
- function Open(Name: string): boolean; // true if succeed
- procedure Rewind;
- procedure MoveTo(Time: real);
- procedure Play;
- procedure Pause; //Pause Mod
- procedure Stop;
- procedure Close;
- function Finished: boolean;
- function Length: real;
- function Position: real;
- procedure PlayStart;
- procedure PlayBack;
- procedure PlaySwoosh;
- procedure PlayChange;
- procedure PlayOption;
- procedure PlayClick;
- procedure PlayDrum;
- procedure PlayHihat;
- procedure PlayClap;
- procedure PlayShuffle;
- procedure StopShuffle;
- procedure CaptureStart;
- procedure CaptureStop;
- procedure CaptureCard(RecordI, PlayerLeft, PlayerRight: byte);
- procedure StopCard(Card: byte);
- function LoadSoundFromFile(var hStream: hStream; Name: string): boolean;
-
- //Equalizer
- function GetFFTData: TFFTData;
-
- //Custom Sounds
- function LoadCustomSound(const Filename: String): Cardinal;
- procedure PlayCustomSound(const Index: Cardinal);
-
-end;
-
-const
- RecordSystem = 1;
-
-type
- TMuzyka = record
- Path: string;
- Start: integer; // start of song in ms
- IlNut: integer;
- DlugoscNut: integer;
- end;
-
- PLine = ^TLine;
- TLine = record
- Start: integer;
- StartNote: integer;
- Lyric: string;
- LyricWidth: real;
- Koniec: integer;
- BaseNote: integer;
- HighNut: integer;
- IlNut: integer;
- TotalNotes: integer;
- Nuta: array of record
- Color: integer;
- Start: integer;
- Dlugosc: integer;
- Ton: integer;
- TonGamy: integer;
- Tekst: string;
- FreeStyle: boolean;
- Wartosc: integer; // zwykla nuta x1, zlota nuta x2
- end;
- end;
- ALine = array of TLine;
-
- TCzesci = record
- Akt: integer; // aktualna czesc utworu do rysowania
- High: integer;
- Ilosc: integer;
- Resolution: integer;
- NotesGAP: integer;
- Wartosc: integer;
- Czesc: ALine;
- end;
-
- TCzas = record // wszystko, co dotyczy aktualnej klatki
- OldBeat: integer; // poprzednio wykryty beat w utworze
- AktBeat: integer; // aktualny beat w utworze
- MidBeat: real; // dokladny AktBeat
-
- // now we use this for super synchronization!
- // only used when analyzing voice
- OldBeatD: integer; // poprzednio wykryty beat w utworze
- AktBeatD: integer; // aktualny beat w utworze
- MidBeatD: real; // dokladny AktBeatD
- FracBeatD: real; // fractional part of MidBeatD
-
- // we use this for audiable clicks
- OldBeatC: integer; // poprzednio wykryty beat w utworze
- AktBeatC: integer; // aktualny beat w utworze
- MidBeatC: real; // dokladny AktBeatC
- FracBeatC: real; // fractional part of MidBeatC
-
-
- OldCzesc: integer; // poprzednio wyswietlana czesc
- // akt jest w czesci.akt
-
- Teraz: real; // aktualny czas w utworze
- Razem: real; // caly czas utworu
- end;
-
-var
- Music: TMusic;
-
- // muzyka
- Muzyka: TMuzyka;
-
- // czesci z nutami;
- Czesci: array of TCzesci;
-
- // czas
- Czas: TCzas;
-
- fHWND: Thandle;
-
-type
- TMPModes = (mpNotReady, mpStopped, mpPlaying, mpRecording, mpSeeking,
- mpPaused, mpOpen);
-
-const
- ModeStr: array[TMPModes] of string = ('Not ready', 'Stopped', 'Playing', 'Recording', 'Seeking', 'Paused', 'Open');
-
-implementation
-
-uses
- {$IFDEF FPC}
- lclintf,
- {$ENDIF}
- UGraphic,
- URecord,
- UFiles,
- UIni,
- UMain,
- UThemes;
-
-procedure InitializeSound;
-begin
- Log.LogStatus('Initializing Playback', 'InitializeSound'); Music.InitializePlayback;
- Log.LogStatus('Initializing Record', 'InitializeSound'); Music.InitializeRecord;
-end;
-
-procedure TMusic.InitializePlayback;
-var
- Pet: integer;
- S: integer;
-begin
- Log.BenchmarkStart(4);
- Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize');
-
- Loaded := false;
- Loop := false;
-
- fHWND := AllocateHWND( nil); // TODO : JB_lazarus - can we do something different here ?? lazarus didnt like this function
-
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- if not BASS_Init(1, 44100, 0, fHWND, nil) then
- begin
- {$IFNDEF FPC}
- // TODO : JB_linux find a way to do this nice..
- Application.MessageBox ('Could not initialize BASS', 'Error');
- {$ENDIF}
- Exit;
- end;
- {$ENDIF}
-
- Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4);
-
- // config playing buffer
-// BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 10);
-// BASS_SetConfig(BASS_CONFIG_BUFFER, 100);
-
- Log.LogStatus('Loading Sounds', 'Music Initialize');
-
- Log.BenchmarkStart(4);
- LoadSoundFromFile(BassStart, SoundPath + 'Common Start.mp3');
- LoadSoundFromFile(BassBack, SoundPath + 'Common Back.mp3');
- LoadSoundFromFile(BassSwoosh, SoundPath + 'menu swoosh.mp3');
- LoadSoundFromFile(BassChange, SoundPath + 'select music change music 50.mp3');
- LoadSoundFromFile(BassOption, SoundPath + 'option change col.mp3');
- LoadSoundFromFile(BassClick, SoundPath + 'rimshot022b.mp3');
-
-// LoadSoundFromFile(BassDrum, SoundPath + 'bassdrumhard076b.mp3');
-// LoadSoundFromFile(BassHihat, SoundPath + 'hihatclosed068b.mp3');
-// LoadSoundFromFile(BassClap, SoundPath + 'claps050b.mp3');
-
-// LoadSoundFromFile(BassShuffle, SoundPath + 'Shuffle.mp3');
-
- Log.BenchmarkEnd(4); Log.LogBenchmark('--> Loading Sounds', 4);
-end;
-
-procedure TMusic.InitializeRecord;
-var
- S: integer;
- device: integer;
- descr: string;
- input: integer;
- input2: integer;
- flags: integer;
- mic: array[0..15] of integer;
- SC: integer; // soundcard
- SCI: integer; // soundcard input
-begin
- if RecordSystem = 1 then begin
- SetLength(Sound, 6 {max players});//Ini.Players+1);
- for S := 0 to High(Sound) do begin //Ini.Players do begin
- Sound[S] := TSound.Create;
- Sound[S].Num := S;
- Sound[S].BufferNew := TMemoryStream.Create;
- SetLength(Sound[S].BufferLong, 1);
- Sound[S].BufferLong[0] := TMemoryStream.Create;
- Sound[S].n := 4*1024;
- end;
-
-
- // check for recording devices;
- {device := 0;
- descr := BASS_RecordGetDeviceDescription(device);
-
- SetLength(SoundCard, 0);
- while (descr <> '') do begin
- SC := High(SoundCard) + 1;
- SetLength(SoundCard, SC+1);
-
- Log.LogAnalyze('Device #'+IntToStr(device)+': '+ descr);
- SoundCard[SC].Description := Descr;
-
- // check for recording inputs
- mic[device] := -1; // default to no change
- input := 0;
- BASS_RecordInit(device);
- Log.LogAnalyze('Input #' + IntToStr(Input) + ': ' + BASS_RecordGetInputName(input));
- flags := BASS_RecordGetInput(input);
-
- SetLength(SoundCard[SC].Input, 0);
- while (flags <> -1) do begin
- SCI := High(SoundCard[SC].Input) + 1;
- SetLength(SoundCard[SC].Input, SCI+1);
-
- Log.LogAnalyze('Input #' + IntToStr(Input) + ': ' + BASS_RecordGetInputName(input));
- SoundCard[SC].Input[SCI].Name := BASS_RecordGetInputName(Input);
-
- if (flags and BASS_INPUT_TYPE_MASK) = BASS_INPUT_TYPE_MIC then begin
- mic[device] := input; // auto set microphone
- end;
- Inc(Input);
- flags := BASS_RecordGetInput(input);
- end;
-
- if mic[device] <> -1 then begin
- Log.LogAnalyze('Found the mic at input ' + IntToStr(Mic[device]))
- end else begin
- Log.LogAnalyze('Mic not found');
- mic[device] := 0; // setting to the first one (for kxproject)
- end;
- SoundCard[SC].InputSeleceted := Mic[Device];
-
-
- BASS_RecordFree;
-
- inc(Device);
- descr := BASS_RecordGetDeviceDescription(Device);
- end; // while}
- end; // if
-end;
-
-procedure TMusic.SetVolume(Volume: integer);
-begin
- //Old Sets Wave Volume
- //BASS_SetVolume(Volume);
- //New: Sets Volume only for this Application
-
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- BASS_SetConfig(BASS_CONFIG_GVOL_SAMPLE, Volume);
- BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume);
- BASS_SetConfig(BASS_CONFIG_GVOL_MUSIC, Volume);
- {$ENDIF}
-end;
-
-procedure TMusic.SetMusicVolume(Volume: Integer);
-begin
- //Max Volume Prevention
- if Volume > 100 then
- Volume := 100;
-
- //Set Volume
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- BASS_ChannelSetAttributes (Bass, -1, Volume, -101);
- {$ENDIF}
-end;
-
-procedure TMusic.SetLoop(Enabled: boolean);
-begin
- Loop := Enabled;
-end;
-
-function TMusic.Open(Name: string): boolean;
-begin
- Loaded := false;
- if FileExists(Name) then
- begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- Bass := Bass_StreamCreateFile(false, pchar(Name), 0, 0, 0);
- {$ENDIF}
-
- Loaded := true;
- //Set Max Volume
- SetMusicVolume (100);
- end;
-
- Result := Loaded;
-end;
-
-procedure TMusic.Rewind;
-begin
- if Loaded then begin
- end;
-end;
-
-procedure TMusic.MoveTo(Time: real);
-var
- bytes: integer;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- bytes := BASS_ChannelSeconds2Bytes(Bass, Time);
- BASS_ChannelSetPosition(Bass, bytes);
- {$ENDIF}
-end;
-
-procedure TMusic.Play;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- if Loaded then
- begin
- if Loop then
- BASS_ChannelPlay(Bass, True); // start from beginning... actually bass itself does not loop, nor does this TMusic Class
-
- BASS_ChannelPlay(Bass, False); // for setting position before playing
- end;
- {$ENDIF}
-end;
-
-procedure TMusic.Pause; //Pause Mod
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- if Loaded then begin
- BASS_ChannelPause(Bass); // Pauses Song
- end;
- {$ENDIF}
-end;
-
-procedure TMusic.Stop;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- Bass_ChannelStop(Bass);
- {$ENDIF}
-end;
-
-procedure TMusic.Close;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- Bass_StreamFree(Bass);
- {$ENDIF}
-end;
-
-function TMusic.Length: real;
-var
- bytes: integer;
-begin
- Result := 60;
-
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- bytes := BASS_ChannelGetLength(Bass);
- Result := BASS_ChannelBytes2Seconds(Bass, bytes);
- {$ENDIF}
-end;
-
-function TMusic.Position: real;
-var
- bytes: integer;
-begin
- Result := 0;
-
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- bytes := BASS_ChannelGetPosition(BASS);
- Result := BASS_ChannelBytes2Seconds(BASS, bytes);
- {$ENDIF}
-end;
-
-function TMusic.Finished: boolean;
-begin
- Result := false;
-
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- if BASS_ChannelIsActive(BASS) = BASS_ACTIVE_STOPPED then
- begin
- Result := true;
- end;
- {$ENDIF}
-end;
-
-procedure TMusic.PlayStart;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- BASS_ChannelPlay(BassStart, True);
- {$ENDIF}
-end;
-
-procedure TMusic.PlayBack;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- BASS_ChannelPlay(BassBack, True);// then
- {$ENDIF}
-end;
-
-procedure TMusic.PlaySwoosh;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- BASS_ChannelPlay(BassSwoosh, True);
- {$ENDIF}
-end;
-
-procedure TMusic.PlayChange;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- BASS_ChannelPlay(BassChange, True);
- {$ENDIF}
-end;
-
-procedure TMusic.PlayOption;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- BASS_ChannelPlay(BassOption, True);
- {$ENDIF}
-end;
-
-procedure TMusic.PlayClick;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- BASS_ChannelPlay(BassClick, True);
- {$ENDIF}
-end;
-
-procedure TMusic.PlayDrum;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- BASS_ChannelPlay(BassDrum, True);
- {$ENDIF}
-end;
-
-procedure TMusic.PlayHihat;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- BASS_ChannelPlay(BassHihat, True);
- {$ENDIF}
-end;
-
-procedure TMusic.PlayClap;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- BASS_ChannelPlay(BassClap, True);
- {$ENDIF}
-end;
-
-procedure TMusic.PlayShuffle;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- BASS_ChannelPlay(BassShuffle, True);
- {$ENDIF}
-end;
-
-procedure TMusic.StopShuffle;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- BASS_ChannelStop(BassShuffle);
- {$ENDIF}
-end;
-
-procedure TMusic.CaptureStart;
-var
- S: integer;
- SC: integer;
- P1: integer;
- P2: integer;
-begin
- for S := 0 to High(Sound) do
- Sound[S].BufferLong[0].Clear;
-
- for SC := 0 to High(Ini.CardList) do begin
- P1 := Ini.CardList[SC].ChannelL;
- P2 := Ini.CardList[SC].ChannelR;
- if P1 > PlayersPlay then P1 := 0;
- if P2 > PlayersPlay then P2 := 0;
- if (P1 > 0) or (P2 > 0) then
- CaptureCard(SC, P1, P2);
- end;
-end;
-
-procedure TMusic.CaptureStop;
-var
- SC: integer;
- P1: integer;
- P2: integer;
-begin
-
- for SC := 0 to High(Ini.CardList) do begin
- P1 := Ini.CardList[SC].ChannelL;
- P2 := Ini.CardList[SC].ChannelR;
- if P1 > PlayersPlay then P1 := 0;
- if P2 > PlayersPlay then P2 := 0;
- if (P1 > 0) or (P2 > 0) then StopCard(SC);
- end;
-
-end;
-
-//procedure TMusic.CaptureCard(RecordI, SoundNum, PlayerLeft, PlayerRight: byte);
-procedure TMusic.CaptureCard(RecordI, PlayerLeft, PlayerRight: byte);
-var
- Error: integer;
- ErrorMsg: string;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
-
- if not BASS_RecordInit(RecordI) then begin
- Error := BASS_ErrorGetCode;
-
- ErrorMsg := IntToStr(Error);
- if Error = BASS_ERROR_DX then ErrorMsg := 'No DX5';
- if Error = BASS_ERROR_ALREADY then ErrorMsg := 'The device has already been initialized';
- if Error = BASS_ERROR_DEVICE then ErrorMsg := 'The device number specified is invalid';
- if Error = BASS_ERROR_DRIVER then ErrorMsg := 'There is no available device driver';
-
- {Log.LogAnalyze('Error initializing record [' + IntToStr(RecordI) + ', '
- + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: '
- + ErrorMsg);}
- Log.LogError('Error initializing record [' + IntToStr(RecordI) + ', '
- + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: '
- + ErrorMsg);
- Log.LogError('Music -> CaptureCard: Error initializing record: ' + ErrorMsg);
-
-
- end
- else
- begin
- Recording.SoundCard[RecordI].BassRecordStream := BASS_RecordStart(44100, 2, MakeLong(0, 20) , @GetMicrophone, PlayerLeft + PlayerRight*256);
- end;
-
- {$ENDIF}
-end;
-
-procedure TMusic.StopCard(Card: byte);
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- BASS_RecordSetDevice(Card);
- BASS_RecordFree;
- {$ENDIF}
-end;
-
-function TMusic.LoadSoundFromFile(var hStream: hStream; Name: string): boolean;
-var
- L: Integer;
-begin
- if FileExists(Name) then begin
- Log.LogStatus('Loading Sound: "' + Name + '"', 'LoadSoundFromFile');
- try
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
- hStream := BASS_StreamCreateFile(False, pchar(Name), 0, 0, 0);
- {$ENDIF}
-
- //Add CustomSound
- L := High(CustomSounds) + 1;
- SetLength (CustomSounds, L + 1);
- CustomSounds[L].Filename := Name;
- CustomSounds[L].Handle := hStream;
- except
- Log.LogError('Failed to open using BASS', 'LoadSoundFromFile');
- end;
- end else begin
- Log.LogError('Sound not found: "' + Name + '"', 'LoadSoundFromFile');
- exit;
- end;
-end;
-
-//Equalizer
-function TMusic.GetFFTData: TFFTData;
-var
-Data: TFFTData;
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
-
- //Get Channel Data Mono and 256 Values
- BASS_ChannelGetData(Bass, @Result, BASS_DATA_FFT512);
- //Result := Data;
-
- {$ENDIF}
-end;
-
-function TMusic.LoadCustomSound(const Filename: String): Cardinal;
-var
- S: hStream;
- I: Integer;
- F: String;
-begin
- //Search for Sound in already loaded Sounds
- F := UpperCase(SoundPath + FileName);
- For I := 0 to High(CustomSounds) do
- begin
- if (UpperCase(CustomSounds[I].Filename) = F) then
- begin
- Result := I;
- Exit;
- end;
- end;
-
- if LoadSoundFromFile(S, SoundPath + Filename) then
- Result := High(CustomSounds)
- else
- Result := 0;
-end;
-
-procedure TMusic.PlayCustomSound(const Index: Cardinal);
-begin
- {$IFDEF useBASS}
- // TODO : jb_linux replace with something other than bass
-
- if Index <= High(CustomSounds) then
- BASS_ChannelPlay(CustomSounds[Index].Handle, True);
-
- {$ENDIF}
-end;
-
-
-end.
+unit UMusic; + +interface + +{$I switches.inc} + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + + +uses Classes, + {$IFDEF win32} + windows, + {$ENDIF} + UCommon, + Messages, + SysUtils, + {$IFNDEF FPC} + Forms, + {$ENDIF} + {$IFDEF useBASS} + bass, + {$ENDIF} + ULog, + USongs; + + +procedure InitializeSound; + +type + TSoundCard = record + Name: string; + Source: array of string; + end; + + TFFTData = array [0..256] of Single; + + TCustomSoundEntry = record + Filename : String; + Handle : hStream; + end; + + + TMusic = class + private + BassStart: hStream; // Wait, I've replaced this with BASS + BassBack: hStream; // It has almost all features we need + BassSwoosh: hStream; + BassChange: hStream; // Almost? It aleady has them all :) + BassOption: hStream; + BassClick: hStream; + BassDrum: hStream; + BassHihat: hStream; + BassClap: hStream; + BassShuffle: hStream; + + //Custom Sounds + CustomSounds: array of TCustomSoundEntry; + + + Loaded: boolean; + Loop: boolean; + public + Bass: hStream; + procedure InitializePlayback; + procedure InitializeRecord; + procedure SetVolume(Volume: integer); + procedure SetMusicVolume(Volume: integer); + procedure SetLoop(Enabled: boolean); + function Open(Name: string): boolean; // true if succeed + procedure Rewind; + procedure MoveTo(Time: real); + procedure Play; + procedure Pause; //Pause Mod + procedure Stop; + procedure Close; + function Finished: boolean; + function Length: real; + function Position: real; + procedure PlayStart; + procedure PlayBack; + procedure PlaySwoosh; + procedure PlayChange; + procedure PlayOption; + procedure PlayClick; + procedure PlayDrum; + procedure PlayHihat; + procedure PlayClap; + procedure PlayShuffle; + procedure StopShuffle; + procedure CaptureStart; + procedure CaptureStop; + procedure CaptureCard(RecordI, PlayerLeft, PlayerRight: byte); + procedure StopCard(Card: byte); + function LoadSoundFromFile(var hStream: hStream; Name: string): boolean; + + //Equalizer + function GetFFTData: TFFTData; + + //Custom Sounds + function LoadCustomSound(const Filename: String): Cardinal; + procedure PlayCustomSound(const Index: Cardinal); + +end; + +const + RecordSystem = 1; + +type + TMuzyka = record + Path: string; + Start: integer; // start of song in ms + IlNut: integer; + DlugoscNut: integer; + end; + + PLine = ^TLine; + TLine = record + Start: integer; + StartNote: integer; + Lyric: string; + LyricWidth: real; + Koniec: integer; + BaseNote: integer; + HighNut: integer; + IlNut: integer; + TotalNotes: integer; + Nuta: array of record + Color: integer; + Start: integer; + Dlugosc: integer; + Ton: integer; + TonGamy: integer; + Tekst: string; + FreeStyle: boolean; + Wartosc: integer; // zwykla nuta x1, zlota nuta x2 + end; + end; + ALine = array of TLine; + + TCzesci = record + Akt: integer; // aktualna czesc utworu do rysowania + High: integer; + Ilosc: integer; + Resolution: integer; + NotesGAP: integer; + Wartosc: integer; + Czesc: ALine; + end; + + TCzas = record // wszystko, co dotyczy aktualnej klatki + OldBeat: integer; // poprzednio wykryty beat w utworze + AktBeat: integer; // aktualny beat w utworze + MidBeat: real; // dokladny AktBeat + + // now we use this for super synchronization! + // only used when analyzing voice + OldBeatD: integer; // poprzednio wykryty beat w utworze + AktBeatD: integer; // aktualny beat w utworze + MidBeatD: real; // dokladny AktBeatD + FracBeatD: real; // fractional part of MidBeatD + + // we use this for audiable clicks + OldBeatC: integer; // poprzednio wykryty beat w utworze + AktBeatC: integer; // aktualny beat w utworze + MidBeatC: real; // dokladny AktBeatC + FracBeatC: real; // fractional part of MidBeatC + + + OldCzesc: integer; // poprzednio wyswietlana czesc + // akt jest w czesci.akt + + Teraz: real; // aktualny czas w utworze + Razem: real; // caly czas utworu + end; + +var + Music: TMusic; + + // muzyka + Muzyka: TMuzyka; + + // czesci z nutami; + Czesci: array of TCzesci; + + // czas + Czas: TCzas; + + fHWND: Thandle; + +type + TMPModes = (mpNotReady, mpStopped, mpPlaying, mpRecording, mpSeeking, + mpPaused, mpOpen); + +const + ModeStr: array[TMPModes] of string = ('Not ready', 'Stopped', 'Playing', 'Recording', 'Seeking', 'Paused', 'Open'); + +implementation + +uses + {$IFDEF FPC} + lclintf, + {$ENDIF} + UGraphic, + URecord, + UFiles, + UIni, + UMain, + UThemes; + +procedure InitializeSound; +begin + Log.LogStatus('Initializing Playback', 'InitializeSound'); Music.InitializePlayback; + Log.LogStatus('Initializing Record', 'InitializeSound'); Music.InitializeRecord; +end; + +procedure TMusic.InitializePlayback; +var + Pet: integer; + S: integer; +begin + Log.BenchmarkStart(4); + Log.LogStatus('Initializing Playback Subsystem', 'Music Initialize'); + + Loaded := false; + Loop := false; + + {$ifdef win32} + // TODO : JB_Linux ... is this needed ? :) + fHWND := AllocateHWND( nil); // TODO : JB_lazarus - can we do something different here ?? lazarus didnt like this function + {$ENDIF} + + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + if not BASS_Init(1, 44100, 0, fHWND, nil) then + begin + {$IFNDEF FPC} + // TODO : JB_linux find a way to do this nice.. + Application.MessageBox ('Could not initialize BASS', 'Error'); + {$ENDIF} + Exit; + end; + {$ENDIF} + + Log.BenchmarkEnd(4); Log.LogBenchmark('--> Bass Init', 4); + + // config playing buffer +// BASS_SetConfig(BASS_CONFIG_UPDATEPERIOD, 10); +// BASS_SetConfig(BASS_CONFIG_BUFFER, 100); + + Log.LogStatus('Loading Sounds', 'Music Initialize'); + + Log.BenchmarkStart(4); + LoadSoundFromFile(BassStart, SoundPath + 'Common Start.mp3'); + LoadSoundFromFile(BassBack, SoundPath + 'Common Back.mp3'); + LoadSoundFromFile(BassSwoosh, SoundPath + 'menu swoosh.mp3'); + LoadSoundFromFile(BassChange, SoundPath + 'select music change music 50.mp3'); + LoadSoundFromFile(BassOption, SoundPath + 'option change col.mp3'); + LoadSoundFromFile(BassClick, SoundPath + 'rimshot022b.mp3'); + +// LoadSoundFromFile(BassDrum, SoundPath + 'bassdrumhard076b.mp3'); +// LoadSoundFromFile(BassHihat, SoundPath + 'hihatclosed068b.mp3'); +// LoadSoundFromFile(BassClap, SoundPath + 'claps050b.mp3'); + +// LoadSoundFromFile(BassShuffle, SoundPath + 'Shuffle.mp3'); + + Log.BenchmarkEnd(4); Log.LogBenchmark('--> Loading Sounds', 4); +end; + +procedure TMusic.InitializeRecord; +var + S: integer; + device: integer; + descr: string; + input: integer; + input2: integer; + flags: integer; + mic: array[0..15] of integer; + SC: integer; // soundcard + SCI: integer; // soundcard input +begin + if RecordSystem = 1 then begin + SetLength(Sound, 6 {max players});//Ini.Players+1); + for S := 0 to High(Sound) do begin //Ini.Players do begin + Sound[S] := TSound.Create; + Sound[S].Num := S; + Sound[S].BufferNew := TMemoryStream.Create; + SetLength(Sound[S].BufferLong, 1); + Sound[S].BufferLong[0] := TMemoryStream.Create; + Sound[S].n := 4*1024; + end; + + + // check for recording devices; + {device := 0; + descr := BASS_RecordGetDeviceDescription(device); + + SetLength(SoundCard, 0); + while (descr <> '') do begin + SC := High(SoundCard) + 1; + SetLength(SoundCard, SC+1); + + Log.LogAnalyze('Device #'+IntToStr(device)+': '+ descr); + SoundCard[SC].Description := Descr; + + // check for recording inputs + mic[device] := -1; // default to no change + input := 0; + BASS_RecordInit(device); + Log.LogAnalyze('Input #' + IntToStr(Input) + ': ' + BASS_RecordGetInputName(input)); + flags := BASS_RecordGetInput(input); + + SetLength(SoundCard[SC].Input, 0); + while (flags <> -1) do begin + SCI := High(SoundCard[SC].Input) + 1; + SetLength(SoundCard[SC].Input, SCI+1); + + Log.LogAnalyze('Input #' + IntToStr(Input) + ': ' + BASS_RecordGetInputName(input)); + SoundCard[SC].Input[SCI].Name := BASS_RecordGetInputName(Input); + + if (flags and BASS_INPUT_TYPE_MASK) = BASS_INPUT_TYPE_MIC then begin + mic[device] := input; // auto set microphone + end; + Inc(Input); + flags := BASS_RecordGetInput(input); + end; + + if mic[device] <> -1 then begin + Log.LogAnalyze('Found the mic at input ' + IntToStr(Mic[device])) + end else begin + Log.LogAnalyze('Mic not found'); + mic[device] := 0; // setting to the first one (for kxproject) + end; + SoundCard[SC].InputSeleceted := Mic[Device]; + + + BASS_RecordFree; + + inc(Device); + descr := BASS_RecordGetDeviceDescription(Device); + end; // while} + end; // if +end; + +procedure TMusic.SetVolume(Volume: integer); +begin + //Old Sets Wave Volume + //BASS_SetVolume(Volume); + //New: Sets Volume only for this Application + + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_SetConfig(BASS_CONFIG_GVOL_SAMPLE, Volume); + BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, Volume); + BASS_SetConfig(BASS_CONFIG_GVOL_MUSIC, Volume); + {$ENDIF} +end; + +procedure TMusic.SetMusicVolume(Volume: Integer); +begin + //Max Volume Prevention + if Volume > 100 then + Volume := 100; + + //Set Volume + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelSetAttributes (Bass, -1, Volume, -101); + {$ENDIF} +end; + +procedure TMusic.SetLoop(Enabled: boolean); +begin + Loop := Enabled; +end; + +function TMusic.Open(Name: string): boolean; +begin + Loaded := false; + if FileExists(Name) then + begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + Bass := Bass_StreamCreateFile(false, pchar(Name), 0, 0, 0); + {$ENDIF} + + Loaded := true; + //Set Max Volume + SetMusicVolume (100); + end; + + Result := Loaded; +end; + +procedure TMusic.Rewind; +begin + if Loaded then begin + end; +end; + +procedure TMusic.MoveTo(Time: real); +var + bytes: integer; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + bytes := BASS_ChannelSeconds2Bytes(Bass, Time); + BASS_ChannelSetPosition(Bass, bytes); + {$ENDIF} +end; + +procedure TMusic.Play; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + if Loaded then + begin + if Loop then + BASS_ChannelPlay(Bass, True); // start from beginning... actually bass itself does not loop, nor does this TMusic Class + + BASS_ChannelPlay(Bass, False); // for setting position before playing + end; + {$ENDIF} +end; + +procedure TMusic.Pause; //Pause Mod +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + if Loaded then begin + BASS_ChannelPause(Bass); // Pauses Song + end; + {$ENDIF} +end; + +procedure TMusic.Stop; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + Bass_ChannelStop(Bass); + {$ENDIF} +end; + +procedure TMusic.Close; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + Bass_StreamFree(Bass); + {$ENDIF} +end; + +function TMusic.Length: real; +var + bytes: integer; +begin + Result := 60; + + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + bytes := BASS_ChannelGetLength(Bass); + Result := BASS_ChannelBytes2Seconds(Bass, bytes); + {$ENDIF} +end; + +function TMusic.Position: real; +var + bytes: integer; +begin + Result := 0; + + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + bytes := BASS_ChannelGetPosition(BASS); + Result := BASS_ChannelBytes2Seconds(BASS, bytes); + {$ENDIF} +end; + +function TMusic.Finished: boolean; +begin + Result := false; + + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + if BASS_ChannelIsActive(BASS) = BASS_ACTIVE_STOPPED then + begin + Result := true; + end; + {$ENDIF} +end; + +procedure TMusic.PlayStart; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassStart, True); + {$ENDIF} +end; + +procedure TMusic.PlayBack; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassBack, True);// then + {$ENDIF} +end; + +procedure TMusic.PlaySwoosh; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassSwoosh, True); + {$ENDIF} +end; + +procedure TMusic.PlayChange; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassChange, True); + {$ENDIF} +end; + +procedure TMusic.PlayOption; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassOption, True); + {$ENDIF} +end; + +procedure TMusic.PlayClick; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassClick, True); + {$ENDIF} +end; + +procedure TMusic.PlayDrum; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassDrum, True); + {$ENDIF} +end; + +procedure TMusic.PlayHihat; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassHihat, True); + {$ENDIF} +end; + +procedure TMusic.PlayClap; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassClap, True); + {$ENDIF} +end; + +procedure TMusic.PlayShuffle; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelPlay(BassShuffle, True); + {$ENDIF} +end; + +procedure TMusic.StopShuffle; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_ChannelStop(BassShuffle); + {$ENDIF} +end; + +procedure TMusic.CaptureStart; +var + S: integer; + SC: integer; + P1: integer; + P2: integer; +begin + for S := 0 to High(Sound) do + Sound[S].BufferLong[0].Clear; + + for SC := 0 to High(Ini.CardList) do begin + P1 := Ini.CardList[SC].ChannelL; + P2 := Ini.CardList[SC].ChannelR; + if P1 > PlayersPlay then P1 := 0; + if P2 > PlayersPlay then P2 := 0; + if (P1 > 0) or (P2 > 0) then + CaptureCard(SC, P1, P2); + end; +end; + +procedure TMusic.CaptureStop; +var + SC: integer; + P1: integer; + P2: integer; +begin + + for SC := 0 to High(Ini.CardList) do begin + P1 := Ini.CardList[SC].ChannelL; + P2 := Ini.CardList[SC].ChannelR; + if P1 > PlayersPlay then P1 := 0; + if P2 > PlayersPlay then P2 := 0; + if (P1 > 0) or (P2 > 0) then StopCard(SC); + end; + +end; + +//procedure TMusic.CaptureCard(RecordI, SoundNum, PlayerLeft, PlayerRight: byte); +procedure TMusic.CaptureCard(RecordI, PlayerLeft, PlayerRight: byte); +var + Error: integer; + ErrorMsg: string; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + + if not BASS_RecordInit(RecordI) then begin + Error := BASS_ErrorGetCode; + + ErrorMsg := IntToStr(Error); + if Error = BASS_ERROR_DX then ErrorMsg := 'No DX5'; + if Error = BASS_ERROR_ALREADY then ErrorMsg := 'The device has already been initialized'; + if Error = BASS_ERROR_DEVICE then ErrorMsg := 'The device number specified is invalid'; + if Error = BASS_ERROR_DRIVER then ErrorMsg := 'There is no available device driver'; + + {Log.LogAnalyze('Error initializing record [' + IntToStr(RecordI) + ', ' + + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: ' + + ErrorMsg);} + Log.LogError('Error initializing record [' + IntToStr(RecordI) + ', ' + + IntToStr(PlayerLeft) + ', '+ IntToStr(PlayerRight) + ']: ' + + ErrorMsg); + Log.LogError('Music -> CaptureCard: Error initializing record: ' + ErrorMsg); + + + end + else + begin + Recording.SoundCard[RecordI].BassRecordStream := BASS_RecordStart(44100, 2, MakeLong(0, 20) , @GetMicrophone, PlayerLeft + PlayerRight*256); + end; + + {$ENDIF} +end; + +procedure TMusic.StopCard(Card: byte); +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + BASS_RecordSetDevice(Card); + BASS_RecordFree; + {$ENDIF} +end; + +function TMusic.LoadSoundFromFile(var hStream: hStream; Name: string): boolean; +var + L: Integer; +begin + if FileExists(Name) then begin + Log.LogStatus('Loading Sound: "' + Name + '"', 'LoadSoundFromFile'); + try + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + hStream := BASS_StreamCreateFile(False, pchar(Name), 0, 0, 0); + {$ENDIF} + + //Add CustomSound + L := High(CustomSounds) + 1; + SetLength (CustomSounds, L + 1); + CustomSounds[L].Filename := Name; + CustomSounds[L].Handle := hStream; + except + Log.LogError('Failed to open using BASS', 'LoadSoundFromFile'); + end; + end else begin + Log.LogError('Sound not found: "' + Name + '"', 'LoadSoundFromFile'); + exit; + end; +end; + +//Equalizer +function TMusic.GetFFTData: TFFTData; +var +Data: TFFTData; +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + + //Get Channel Data Mono and 256 Values + BASS_ChannelGetData(Bass, @Result, BASS_DATA_FFT512); + //Result := Data; + + {$ENDIF} +end; + +function TMusic.LoadCustomSound(const Filename: String): Cardinal; +var + S: hStream; + I: Integer; + F: String; +begin + //Search for Sound in already loaded Sounds + F := UpperCase(SoundPath + FileName); + For I := 0 to High(CustomSounds) do + begin + if (UpperCase(CustomSounds[I].Filename) = F) then + begin + Result := I; + Exit; + end; + end; + + if LoadSoundFromFile(S, SoundPath + Filename) then + Result := High(CustomSounds) + else + Result := 0; +end; + +procedure TMusic.PlayCustomSound(const Index: Cardinal); +begin + {$IFDEF useBASS} + // TODO : jb_linux replace with something other than bass + + if Index <= High(CustomSounds) then + BASS_ChannelPlay(CustomSounds[Index].Handle, True); + + {$ENDIF} +end; + + +end. diff --git a/Game/Code/Classes/USkins.pas b/Game/Code/Classes/USkins.pas index 7fdbacde..c9d7f2fd 100644 --- a/Game/Code/Classes/USkins.pas +++ b/Game/Code/Classes/USkins.pas @@ -1,171 +1,174 @@ -unit USkins;
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-
-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'+PathDelim+'*', faDirectory, SR) = 0 then begin
- repeat
- if (SR.Name <> '.') and (SR.Name <> '..') then
- ParseDir('Skins'+PathDelim + SR.Name + PathDelim);
- 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
- begin
- if ( SkinTexture[T].Name = TextureName ) AND
- ( SkinTexture[T].FileName <> '' ) then
- begin
- Result := SkinPath + SkinTexture[T].FileName;
- end;
- end;
-
-{ 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
- Ini.SkinNo:=0;
- 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.
+unit USkins; + +{$IFDEF FPC} + {$MODE DELPHI} +{$ENDIF} + + +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'+PathDelim+'*', faDirectory, SR) = 0 then begin + repeat + if (SR.Name <> '.') and (SR.Name <> '..') then + ParseDir('Skins'+PathDelim + SR.Name + PathDelim); + 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 + begin + if ( SkinTexture[T].Name = TextureName ) AND + ( SkinTexture[T].FileName <> '' ) then + begin + Result := SkinPath + SkinTexture[T].FileName; + end; + end; + + Log.LogStatus('', '-----------------------------------------'); + Log.LogStatus(TextureName+' - '+ Result, 'TSkin.GetTextureFileName'); + +{ 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 + Ini.SkinNo:=0; + 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/UTexture.pas b/Game/Code/Classes/UTexture.pas index f5169e8c..173fbd4c 100644 --- a/Game/Code/Classes/UTexture.pas +++ b/Game/Code/Classes/UTexture.pas @@ -1,1098 +1,1151 @@ -unit UTexture;
-// added for easier debug disabling
-{$define blindydebug}
-
-// Plain (alpha = 1)
-// Transparent
-// Colorized
-
-// obsolete?
-// Transparent Range
-// Font (white is drawn, black is transparent)
-// Font Outline (Font with darker outline)
-// Font Outline 2 (Font with darker outline)
-// Font Black (black is drawn, white is transparent)
-// Font Gray (gray is drawn, white is transparent)
-// Arrow (for arrows, white is white, gray has color, black is transparent);
-
-interface
-
-{$I switches.inc}
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-uses OpenGL12,
- {$IFDEF win32}
- windows,
- {$ENDIF}
- Math,
- Classes,
- SysUtils,
- Graphics,
- UCommon,
- UThemes,
- SDL,
- sdlutils,
- SDL_Image;
-
-
- {$IFDEF Win32}
- procedure glGenTextures(n: GLsizei; var textures: GLuint); stdcall; external opengl32;
-
- {$ELSE}
- {$ifdef darwin}
- const opengl32 = '/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib';
- {$ELSE}
- const opengl32 = 'libGL.so' ; // YES Capital GL
- {$ENDIF}
-
- procedure glGenTextures(n: GLsizei; var textures: GLuint); stdcall; external opengl32;
- {$ENDIF}
-
-type
- TTexture = record
- TexNum: integer;
- X: real;
- Y: real;
- Z: real; // new
- W: real;
- H: real;
- ScaleW: real; // for dynamic scalling while leaving width constant
- ScaleH: real; // for dynamic scalling while leaving height constant
- Rot: real; // 0 - 2*pi
- Int: real; // intensity
- ColR: real;
- ColG: real;
- ColB: real;
- TexW: real; // used?
- TexH: real; // used?
- TexX1: real;
- TexY1: real;
- TexX2: real;
- TexY2: real;
- Alpha: real;
- Name: string; // 0.5.0: experimental for handling cache images. maybe it's useful for dynamic skins
- end;
-
- TTextureEntry = record
- Name: string;
- Typ: string;
-
- // we use normal TTexture, it's easier to implement and if needed - we copy ready data
- Texture: TTexture;
- TextureCache: TTexture; // 0.5.0
- end;
-
- TTextureDatabase = record
- Texture: array of TTextureEntry;
- end;
-
- TTextureUnit = class
-
- private
- function LoadImage(Identifier: PChar): PSDL_Surface;
- function pixfmt_eq(fmt1,fmt2: PSDL_Pixelformat): boolean;
- procedure AdjustPixelFormat(var TexSurface: PSDL_Surface; Typ: PChar);
- function GetScaledTexture(TexSurface: PSDL_Surface; W,H: Cardinal): PSDL_Surface;
- procedure ScaleTexture(var TexSurface: PSDL_Surface; W,H: Cardinal);
- procedure FitTexture(var TexSurface: PSDL_Surface; W,H: Cardinal);
- procedure ColorizeTexture(TexSurface: PSDL_Surface; Col: Cardinal);
-
- public
- Limit: integer;
- CreateCacheMipmap: boolean;
-
-// function GetNumberFor
- function GetTexture(Name, Typ: string): TTexture; overload;
- function GetTexture(Name, Typ: string; FromCache: boolean): TTexture; overload;
- function FindTexture(Name: string): integer;
- function LoadTexture(FromRegistry: boolean; Identifier, Format, Typ: PChar; Col: LongWord): TTexture; overload;
- function LoadTexture(Identifier, Format, Typ: PChar; Col: LongWord): TTexture; overload;
- function LoadTexture(Identifier: string): TTexture; overload;
- function CreateTexture(var Data: array of byte; Name: string; W, H: word; Bits: byte): TTexture;
- procedure UnloadTexture(Name: string; FromCache: boolean);
- Constructor Create;
- Destructor Destroy;
- end;
-
-var
- Texture: TTextureUnit;
- TextureDatabase: TTextureDatabase;
-
- // this should be in UDisplay?!
- PrintScreenData: array[0..1024*768-1] of longword;
-
- ActTex: GLuint;//integer;
-
-// TextureD8: array[1..1024*1024] of byte; // 1MB
- TextureD16: array[1..1024*1024, 1..2] of byte; // luminance/alpha tex (2MB)
-// TextureD24: array[1..1024*1024, 1..3] of byte; // normal 24-bit tex (3MB)
-// TextureD242: array[1..512*512, 1..3] of byte; // normal 24-bit tex (0,75MB)
-// TextureD32: array[1..1024*1024, 1..4] of byte; // transparent 32-bit tex (4MB)
- // total 40MB at 2048*2048
- // total 10MB at 1024*1024
-
- Mipmapping: Boolean;
-
- CacheMipmap: array[0..256*256*3-1] of byte; // 3KB
- CacheMipmapSurface: PSDL_Surface;
-
-
-implementation
-
-uses ULog,
- DateUtils,
- UCovers,
- {$IFDEF FPC}
- LResources,
- {$ENDIF}
- StrUtils, dialogs;
-
-const
- fmt_rgba: TSDL_Pixelformat=(palette: nil;
- BitsPerPixel: 32;
- BytesPerPixel: 4;
- Rloss: 0;
- Gloss: 0;
- Bloss: 0;
- Aloss: 0;
- Rshift: 0;
- Gshift: 8;
- Bshift: 16;
- Ashift: 24;
- Rmask: $000000ff;
- Gmask: $0000ff00;
- Bmask: $00ff0000;
- Amask: $ff000000;
- ColorKey: 0;
- Alpha: 255);
- fmt_rgb: TSDL_Pixelformat=( palette: nil;
- BitsPerPixel: 24;
- BytesPerPixel: 3;
- Rloss: 0;
- Gloss: 0;
- Bloss: 0;
- Aloss: 0;
- Rshift: 0;
- Gshift: 8;
- Bshift: 16;
- Ashift: 0;
- Rmask: $000000ff;
- Gmask: $0000ff00;
- Bmask: $00ff0000;
- Amask: $00000000;
- ColorKey: 0;
- Alpha: 255);
-
-
-Constructor TTextureUnit.Create;
-begin
- inherited Create;
-end;
-
-Destructor TTextureUnit.Destroy;
-begin
- inherited Destroy;
-end;
-
-function TTextureUnit.pixfmt_eq(fmt1,fmt2: PSDL_Pixelformat): boolean;
-begin
- if (fmt1^.BitsPerPixel = fmt2^.BitsPerPixel) and
- (fmt1^.BytesPerPixel = fmt2^.BytesPerPixel) and
- (fmt1^.Rloss = fmt2^.Rloss) and (fmt1^.Gloss = fmt2^.Gloss) and
- (fmt1^.Bloss = fmt2^.Bloss) and (fmt1^.Rmask = fmt2^.Rmask) and
- (fmt1^.Gmask = fmt2^.Gmask) and (fmt1^.Bmask = fmt2^.Bmask) and
- (fmt1^.Rshift = fmt2^.Rshift) and (fmt1^.Gshift = fmt2^.Gshift) and
- (fmt1^.Bshift = fmt2^.Bshift)
- then
- Result:=True
- else
- Result:=False;
-end;
-
-// +++++++++++++++++++++ helpers for loadimage +++++++++++++++
- function SdlStreamSeek( context : PSDL_RWops; offset : Integer; whence : Integer ) : integer; cdecl;
- var
- stream : TStream;
- origin : Word;
- begin
- stream := TStream( context.unknown );
- if ( stream = nil ) then
- raise EInvalidContainer.Create( 'SDLStreamSeek on nil' );
- case whence of
- 0 : origin := soFromBeginning; // Offset is from the beginning of the resource. Seek moves to the position Offset. Offset must be >= 0.
- 1 : origin := soFromCurrent; // Offset is from the current position in the resource. Seek moves to Position + Offset.
- 2 : origin := soFromEnd;
- else
- origin := soFromBeginning; // just in case
- end;
- Result := stream.Seek( offset, origin );
- end;
- function SdlStreamRead( context : PSDL_RWops; Ptr : Pointer; size : Integer; maxnum: Integer ) : Integer; cdecl;
- var
- stream : TStream;
- begin
- stream := TStream( context.unknown );
- if ( stream = nil ) then
- raise EInvalidContainer.Create( 'SDLStreamRead on nil' );
- try
- Result := stream.read( Ptr^, Size * maxnum ) div size;
- except
- Result := -1;
- end;
- end;
- function SDLStreamClose( context : PSDL_RWops ) : Integer; cdecl;
- var
- stream : TStream;
- begin
- stream := TStream( context.unknown );
- if ( stream = nil ) then
- raise EInvalidContainer.Create( 'SDLStreamClose on nil' );
- stream.Free;
- Result := 1;
- end;
-// -----------------------------------------------
-
-function TTextureUnit.LoadImage(Identifier: PChar): PSDL_Surface;
-var
-
- TexRWops: PSDL_RWops;
- dHandle: THandle;
-
- {$IFDEF FPC}
- lLazRes : TLResource;
- lResData : TStringStream;
- {$ELSE}
- TexStream: TStream;
- {$ENDIF}
-
-begin
- Result := nil;
- TexRWops := nil;
-
-// Log.LogStatus( Identifier, 'LoadImage' );
-
- if ( FileExists(Identifier) ) then
- begin
- // load from file
- Log.LogStatus( 'Is File', ' LoadImage' );
- try
- Result:=IMG_Load(Identifier);
- except
- Log.LogStatus( 'ERROR Could not load from file' , Identifier);
- beep;
- Exit;
- end;
- end
- else
- begin
- Log.LogStatus( 'IS Resource', ' LoadImage' );
-
- // load from resource stream
- {$IFNDEF FPC}
- dHandle := FindResource(hInstance, Identifier, 'TEX');
- if dHandle=0 then
- begin
- Log.LogStatus( 'ERROR Could not find resource' , ' '+ Identifier);
- beep;
- Exit;
- end;
-
-
- TexStream := nil;
- try
- TexStream := TResourceStream.Create(HInstance, Identifier, 'TEX');
- except
- Log.LogStatus( 'ERROR Could not load from resource' , Identifier);
- beep;
- Exit;
- end;
-
- try
- TexStream.position := 0;
- try
- TexRWops := SDL_AllocRW;
- TexRWops.unknown := TUnknown(TexStream);
- TexRWops.seek := SDLStreamSeek;
- TexRWops.read := SDLStreamRead;
- TexRWops.write := nil;
- TexRWops.close := SDLStreamClose;
- TexRWops.type_ := 2;
- except
- Log.LogStatus( 'ERROR Could not assign resource' , Identifier);
- beep;
- Exit;
- end;
-
- Log.LogStatus( 'resource Assigned....' , Identifier);
- Result:=IMG_Load_RW(TexRWops,0);
- SDL_FreeRW(TexRWops);
-
- finally
- if assigned( TexStream ) then
- freeandnil( TexStream );
- end;
-
-
- {$ELSE}
- lLazRes := LazFindResource( Identifier, 'TEX' );
- if lLazRes <> nil then
- begin
- lResData := TStringStream.create( lLazRes.value );
- try
- lResData.position := 0;
- try
- TexRWops := SDL_AllocRW;
- TexRWops.unknown := TUnknown( lResData );
- TexRWops.seek := SDLStreamSeek;
- TexRWops.read := SDLStreamRead;
- TexRWops.write := nil;
- TexRWops.close := SDLStreamClose;
- TexRWops.type_ := 2;
- except
- Log.LogStatus( 'ERROR Could not assign resource' , Identifier);
- beep;
- Exit;
- end;
-
- Result := IMG_Load_RW(TexRWops,0);
- SDL_FreeRW(TexRWops);
- finally
- freeandnil( lResData );
- end;
- end
- else
- begin
- Log.LogStatus( 'NOT found in Resource', ' LoadImage' );
- end;
- {$ENDIF}
-
-
- end;
-end;
-
-procedure TTextureUnit.AdjustPixelFormat(var TexSurface: PSDL_Surface; Typ: PChar);
-var
- TempSurface: PSDL_Surface;
- NeededPixFmt: PSDL_Pixelformat;
-begin
- NeededPixFmt:=@fmt_rgba;
- if Typ= 'Plain' then NeededPixFmt:=@fmt_rgb
- else
- if (Typ='Transparent') or
- (Typ='Colorized')
- then NeededPixFmt:=@fmt_rgba
- else
- NeededPixFmt:=@fmt_rgb;
-
-
- if not pixfmt_eq(TexSurface^.format, NeededPixFmt) then
- begin
- TempSurface:=TexSurface;
- TexSurface:=SDL_ConvertSurface(TempSurface,NeededPixFmt,SDL_SWSURFACE);
- SDL_FreeSurface(TempSurface);
- end;
-end;
-
-function TTextureUnit.GetScaledTexture(TexSurface: PSDL_Surface; W,H: Cardinal): PSDL_Surface;
-var
- TempSurface: PSDL_Surface;
-begin
- TempSurface:=TexSurface;
- Result:=SDL_ScaleSurfaceRect(TempSurface,
- 0,0,TempSurface^.W,TempSurface^.H,
- W,H);
-end;
-
-procedure TTextureUnit.ScaleTexture(var TexSurface: PSDL_Surface; W,H: Cardinal);
-var
- TempSurface: PSDL_Surface;
-begin
- TempSurface:=TexSurface;
- TexSurface:=SDL_ScaleSurfaceRect(TempSurface,
- 0,0,TempSurface^.W,TempSurface^.H,
- W,H);
- SDL_FreeSurface(TempSurface);
-end;
-
-procedure TTextureUnit.FitTexture(var TexSurface: PSDL_Surface; W,H: Cardinal);
-var
- TempSurface: PSDL_Surface;
-begin
- TempSurface:=TexSurface;
- with TempSurface^.format^ do
- TexSurface:=SDL_CreateRGBSurface(SDL_SWSURFACE,W,H,BitsPerPixel,RMask, GMask, BMask, AMask);
- SDL_SetAlpha(TexSurface, 0, 255);
- SDL_SetAlpha(TempSurface, 0, 255);
- SDL_BlitSurface(TempSurface,nil,TexSurface,nil);
- SDL_FreeSurface(TempSurface);
-end;
-
-procedure TTextureUnit.ColorizeTexture(TexSurface: PSDL_Surface; Col: Cardinal);
- //returns hue within range [0.0-6.0)
- function col2h(Color:Cardinal):double;
- var
- clr,hls: array[0..2] of double;
- delta: double;
- begin
- clr[0]:=((Color and $ff0000) shr 16)/255;
- clr[1]:=((Color and $ff00) shr 8)/255;
- clr[2]:=(Color and $ff)/255;
- hls[1]:=maxvalue(clr);
- delta:=hls[1]-minvalue(clr);
- if clr[0]=hls[1] then hls[0]:=(clr[1]-clr[2])/delta
- else if clr[1]=hls[1] then hls[0]:=2.0+(clr[2]-clr[0])/delta
- else if clr[2]=hls[1] then hls[0]:=4.0+(clr[0]-clr[1])/delta;
- if hls[0]<0.0 then hls[0]:=hls[0]+6.0;
- if hls[0]=6.0 then hls[0]:=0.0;
- col2h:=hls[0];
- end;
- procedure ColorizePixel(Pix: PByteArray; hue: Double);
- var
- i,j,k: Cardinal;
- clr, hls: array[0..2] of Double;
- delta, f, p, q, t: Double;
- begin
- hls[0]:=hue;
-
- clr[0] := Pix[0]/255;
- clr[1] := Pix[1]/255;
- clr[2] := Pix[2]/255;
-
- //calculate luminance and saturation from rgb
- hls[1] := maxvalue(clr); //l:=...
- delta := hls[1] - minvalue(clr);
-
- if hls[1] = 0.0 then
- hls[2] := 0.0
- else
- hls[2] := delta/hls[1]; //v:=...
-
- // calc new rgb from our hls (h from color, l ans s from pixel)
- // if (hls[1]<>0.0) and (hls[2]<>0.0) then // only if colorizing makes sense
- begin
- k:=trunc(hls[0]);
- f:=hls[0]-k;
- p:=hls[1]*(1.0-hls[2]);
- q:=hls[1]*(1.0-(hls[2]*f));
- t:=hls[1]*(1.0-(hls[2]*(1.0-f)));
- case k of
- 0: begin clr[0]:=hls[1]; clr[1]:=t; clr[2]:=p; end;
- 1: begin clr[0]:=q; clr[1]:=hls[1]; clr[2]:=p; end;
- 2: begin clr[0]:=p; clr[1]:=hls[1]; clr[2]:=t; end;
- 3: begin clr[0]:=p; clr[1]:=q; clr[2]:=hls[1]; end;
- 4: begin clr[0]:=t; clr[1]:=p; clr[2]:=hls[1]; end;
- 5: begin clr[0]:=hls[1]; clr[1]:=p; clr[2]:=q; end;
- end;
- // and store new rgb back into the image
- Pix[0]:=floor(255*clr[0]);
- Pix[1]:=floor(255*clr[1]);
- Pix[2]:=floor(255*clr[2]);
- end;
- end;
-
-var
- DestinationHue: Double;
- PixelIndex: Cardinal;
-begin
- DestinationHue:=col2h(Col);
- for PixelIndex:=0 to (TexSurface^.W*TexSurface^.H -1) do
- ColorizePixel(@(PByteArray(TexSurface^.Pixels)[PixelIndex*TexSurface^.format.BytesPerPixel]),DestinationHue);
-end;
-
-function TTextureUnit.LoadTexture(FromRegistry: boolean; Identifier, Format, Typ: PChar; Col: LongWord): TTexture;
-var
- TexSurface: PSDL_Surface;
- MipmapSurface: PSDL_Surface;
- newWidth, newHeight: Cardinal;
- oldWidth, oldHeight: Cardinal;
- kopierindex: Cardinal;
-begin
- Log.BenchmarkStart(4);
- Mipmapping := true;
-(*
- Log.LogStatus( '', '' );
-
- if Identifier = nil then
- Log.LogStatus(' ERROR unknown Identifier', 'Id:'''+Identifier+''' Fmt:'''+Format+''' Typ:'''+Typ+'''')
- else
- Log.LogStatus(' should be ok - trying to load', 'Id:'''+Identifier+''' Fmt:'''+Format+''' Typ:'''+Typ+'''');
-*)
-
- // load texture data into memory
- {$ifdef blindydebug}
- Log.LogStatus('',' LoadImage('''+Identifier+''') (called by '+Format+')');
- {$endif}
- TexSurface := LoadImage(Identifier);
- {$ifdef blindydebug}
- Log.LogStatus('',' ok');
- {$endif}
- if not assigned(TexSurface) then
- begin
- Log.LogStatus( 'ERROR Could not load texture' , Identifier +' '+ Format +' '+ Typ );
- beep;
- Exit;
- end;
- // convert pixel format as needed
- {$ifdef blindydebug}
- Log.LogStatus('',' AdjustPixelFormat');
- {$endif}
- AdjustPixelFormat(TexSurface, Typ);
- {$ifdef blindydebug}
- Log.LogStatus('',' ok');
- {$endif}
- // adjust texture size (scale down, if necessary)
- newWidth:=TexSurface.W;
- newHeight:=TexSurface.H;
- if (newWidth > Limit) then
- newWidth:=Limit;
- if (newHeight > Limit) then
- newHeight:=Limit;
- if (TexSurface.W > newWidth) or (TexSurface.H > newHeight) then
- begin
- {$ifdef blindydebug}
- Log.LogStatus('',' ScaleTexture');
- {$endif}
- ScaleTexture(TexSurface,newWidth,newHeight);
- {$ifdef blindydebug}
- Log.LogStatus('',' ok');
- {$endif}
- end;
-
- // don't actually understand, if this is needed...
- // this should definately be changed... together with all this
- // cover cache stuff
- if (CreateCacheMipmap) and (Typ='Plain') then
- begin
- if (Covers.W <= 256) and (Covers.H <= 256) then
- begin
- {$ifdef blindydebug}
- Log.LogStatus('',' GetScaledTexture('''+inttostr(Covers.W)+''','''+inttostr(Covers.H)+''') (for CacheMipmap)');
- {$endif}
- MipmapSurface:=GetScaledTexture(TexSurface,Covers.W, Covers.H);
- if assigned(MipmapSurface) then
- begin
- {$ifdef blindydebug}
- Log.LogStatus('',' ok');
- Log.LogStatus('',' BlitSurface Stuff');
- {$endif}
- // creating and freeing the surface could be done once, if Cover.W and Cover.H don't change
- CacheMipmapSurface:=SDL_CreateRGBSurfaceFrom(@CacheMipmap[0], Covers.W, Covers.H, 24, Covers.W*3, $000000ff, $0000ff00, $00ff0000, 0);
- SDL_BlitSurface(MipMapSurface,nil,CacheMipmapSurface,nil);
- SDL_FreeSurface(CacheMipmapSurface);
- {$ifdef blindydebug}
- Log.LogStatus('',' ok');
- Log.LogStatus('',' SDL_FreeSurface (CacheMipmap)');
- {$endif}
- SDL_FreeSurface(MipmapSurface);
- {$ifdef blindydebug}
- Log.LogStatus('',' ok');
- {$endif}
- end
- else
- begin
- Log.LogStatus(' Error creating CacheMipmap',' LoadTexture('''+Identifier+''')');
- end;
- end;
- // should i create a cache texture, if Covers.W/H are larger?
- end;
-
- // now we might colorize the whole thing
- if Typ='Colorized' then ColorizeTexture(TexSurface,Col);
- // save actual dimensions of our texture
- oldWidth:=newWidth;
- oldHeight:=newHeight;
- // make texture dimensions be powers of 2
- newWidth:=Round(Power(2, Ceil(Log2(newWidth))));
- newHeight:=Round(Power(2, Ceil(Log2(newHeight))));
- if (newHeight <> oldHeight) or (newWidth <> oldWidth) then
- FitTexture(TexSurface,newWidth,newHeight);
-
- // at this point we have the image in memory...
- // scaled to be at most 1024x1024 pixels large
- // scaled so that dimensions are powers of 2
- // and converted to either RGB or RGBA
-
-
- // if we got a Texture of Type Plain, Transparent or Colorized,
- // then we're done manipulating it
- // and could now create our openGL texture from it
-
- // prepare OpenGL texture
- glGenTextures(1, ActTex);
- glBindTexture(GL_TEXTURE_2D, ActTex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- // load data into gl texture
- if (Typ = 'Transparent') or (Typ='Colorized') then begin
- glTexImage2D(GL_TEXTURE_2D, 0, 4, newWidth, newHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, TexSurface.pixels);
- end
- {if Typ = 'Plain' then} else
- begin
- glTexImage2D(GL_TEXTURE_2D, 0, 3, newWidth, newHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, TexSurface.pixels);
- end;
-{
- if Typ = 'Transparent Range' then
- // set alpha to 256-green-component (not sure)
- Pix := TextureB.Canvas.Pixels[Position2, Position];
- TextureD32[Position*TexNewW + Position2+1, 1] := Pix;
- TextureD32[Position*TexNewW + Position2+1, 2] := Pix div 256;
- TextureD32[Position*TexNewW + Position2+1, 3] := Pix div (256*256);
- TextureD32[Position*TexNewW + Position2+1, 4] := 256 - Pix div 256;
-}
-{
- if Typ = 'Font' then
- // either create luminance-alpha texture
- // or use transparency from differently saved file
- // or do something totally different (text engine with ttf)
- Pix := PPix[Position2 * 3];
- TextureD16[Position*TextureB.Width + Position2 + 1, 1] := 255;
- TextureD16[Position*TextureB.Width + Position2 + 1, 2] := Pix;
- glTexImage2D(GL_TEXTURE_2D, 0, 2, TextureB.Width, TextureB.Height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
-}
-{
- if Typ = 'Font Outline' then
- // no idea...
- begin
- TextureB.PixelFormat := pf24bit;
- for Position := 0 to TextureB.Height-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TextureB.Width-1 do begin
- Pix := PPix[Position2 * 3];
-
- Col := Pix;
- if Col < 127 then Col := 127;
-
- TempA := Pix;
- if TempA >= 95 then TempA := 255;
- if TempA >= 31 then TempA := 255;
- if Pix < 95 then TempA := (Pix * 256) div 96;
-
-
- TextureD16[Position*TextureB.Width + Position2 + 1, 1] := Col;
- TextureD16[Position*TextureB.Width + Position2 + 1, 2] := TempA;
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 2, TextureB.Width, TextureB.Height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
- end;
-}
-{
- if Typ = 'Font Outline 2' then
- // same as above
- begin
- TextureB.PixelFormat := pf24bit;
- for Position := 0 to TextureB.Height-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TextureB.Width-1 do begin
- Pix := PPix[Position2 * 3];
-
- Col := Pix;
- if Col < 31 then Col := 31;
-
- TempA := Pix;
- if TempA >= 31 then TempA := 255;
- if Pix < 31 then TempA := Pix * (256 div 32);
-
- TextureD16[Position*TextureB.Width + Position2 + 1, 1] := Col;
- TextureD16[Position*TextureB.Width + Position2 + 1, 2] := TempA;
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 2, TextureB.Width, TextureB.Height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
- if Mipmapping then glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- if Mipmapping then begin
- Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 2, TextureB.Width, TextureB.Height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16);
- if Error > 0 then beep;
- end;
- end;
-
- if Typ = 'Font Black' then
- // and so on
- begin
- // normalnie 0,125s bez niczego 0,015s - 0,030s z pix 0,125s <-- ???
- // dimensions
- TextureB.PixelFormat := pf24bit;
- TexOrigW := TextureB.Width;
- TexOrigH := TextureB.Height;
- TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
- TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
- TextureB.Width := TexNewW;
- TextureB.Height := TexNewH;
- // copy and process pixeldata
- for Position := 0 to TextureB.Height-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TextureB.Width-1 do begin
- Pix := PPix[Position2*3];
- TextureD32[Position*TextureB.Width + Position2 + 1, 1] := 255;
- TextureD32[Position*TextureB.Width + Position2 + 1, 2] := 255;
- TextureD32[Position*TextureB.Width + Position2 + 1, 3] := 255;
- TextureD32[Position*TextureB.Width + Position2 + 1, 4] := 255 - (Pix mod 256);
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
- end;
-
- if Typ = 'Alpha Black Colored' then
- // ... hope, noone needs this
- begin
- TextureB.PixelFormat := pf24bit;
- TexOrigW := TextureB.Width;
- TexOrigH := TextureB.Height;
- TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
- TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
- TextureB.Width := TexNewW;
- TextureB.Height := TexNewH;
- // copy and process pixeldata
- for Position := 0 to TextureB.Height-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TextureB.Width-1 do begin
- Pix := PPix[Position2*3];
- TextureD32[Position*TextureB.Width + Position2 + 1, 1] := (Col div $10000) and $FF;
- TextureD32[Position*TextureB.Width + Position2 + 1, 2] := (Col div $100) and $FF;
- TextureD32[Position*TextureB.Width + Position2 + 1, 3] := Col and $FF;
- TextureD32[Position*TextureB.Width + Position2 + 1, 4] := 255 - (Pix mod 256);
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
- end;
-
- if Typ = 'Font Gray' then
- begin
- // dimensions
- TexOrigW := TextureB.Width;
- TexOrigH := TextureB.Height;
- TexNewW := Round(Power(2, Ceil(Log2(TexOrigW))));
- TexNewH := Round(Power(2, Ceil(Log2(TexOrigH))));
- TextureB.Width := TexNewW;
- TextureB.Height := TexNewH;
- // copy and process pixeldata
- for Position := 0 to TextureB.Height-1 do begin
- for Position2 := 0 to TextureB.Width-1 do begin
- Pix := TextureB.Canvas.Pixels[Position2, Position];
- TextureD32[Position*TextureB.Width + Position2 + 1, 1] := 127;
- TextureD32[Position*TextureB.Width + Position2 + 1, 2] := 127;
- TextureD32[Position*TextureB.Width + Position2 + 1, 3] := 127;
- TextureD32[Position*TextureB.Width + Position2 + 1, 4] := 255 - (Pix mod 256);
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
- end;
-
- if Typ = 'Arrow' then
- begin
- TextureB.PixelFormat := pf24bit;
- for Position := 0 to TextureB.Height-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TextureB.Width-1 do begin
- Pix := PPix[Position2 * 3];
-
- // transparency
- if Pix >= 127 then TempA := 255;
- if Pix < 127 then TempA := Pix * 2;
-
- // ColInt = color intensity
- if Pix < 127 then ColInt := 1;
- if Pix >= 127 then ColInt := 2 - Pix / 128;
- //0.75, 0.6, 0.25
-
- TextureD32[Position*TextureB.Width + Position2 + 1, 1] := Round(ColInt * 0.75 * 255 + (1 - ColInt) * 255);
- TextureD32[Position*TextureB.Width + Position2 + 1, 2] := Round(ColInt * 0.6 * 255 + (1 - ColInt) * 255);
- TextureD32[Position*TextureB.Width + Position2 + 1, 3] := Round(ColInt * 0.25 * 255 + (1 - ColInt) * 255);
- TextureD32[Position*TextureB.Width + Position2 + 1, 4] := TempA;
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
-
- if Mipmapping then glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
- if Mipmapping then begin
- Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 4, TextureB.Width, TextureB.Height, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
- if Error > 0 then beep;
- end;
- end;
-
- if Typ = 'Note Plain' then
- begin
- for Position := 0 to TextureB.Height-1 do
- begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TextureB.Width-1 do
- begin
-
-
-
- // Skin Patch
- // 0-191= Fade Black to Col, 192= Col, 193-254 Fade Col to White, 255= White
- case PPix[Position2*3] of
- 0..191: Pix := $10000 * ((((Col div $10000) and $FF) * PPix[Position2*3]) div $Bf) + $100 * ((((Col div $100) and $FF) * PPix[Position2*3]) div $Bf) + (((Col and $FF) * PPix[Position2*3]) div $Bf);
- 192: Pix := Col;
- 193..254: Pix := Col + ($10000 * ((($FF - ((Col div $10000) and $FF)) * ((PPix[Position2*3] - $C0) * 4) ) div $FF) + $100 * ((($FF - ((Col div $100) and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF) + ((($FF - (Col and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF));
- 255: Pix := $FFFFFF;
- end;
-// 0.5.0. Original
-// case PPix[Position2*3] of
-// 128: Pix := $10000 * ((Col div $10000) div 2) + $100 * (((Col div $100) and $FF) div 2) + (Col and $FF) div 2;
-// 192: Pix := Col;
-// 255: Pix := $FFFFFF;
-// end;
-
-
-
-
-
- TextureD24[Position*TextureB.Width + Position2 + 1, 1] := Pix div $10000;
- TextureD24[Position*TextureB.Width + Position2 + 1, 2] := (Pix div $100) and $FF;
- TextureD24[Position*TextureB.Width + Position2 + 1, 3] := Pix and $FF;
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureB.Width, TextureB.Height, 0, GL_RGB, GL_UNSIGNED_BYTE, @TextureD24);
- end;
-
- if Typ = 'Note Transparent' then
- begin
- for Position := 0 to TextureB.Height-1 do begin
- PPix := TextureB.ScanLine[Position];
- for Position2 := 0 to TextureB.Width-1 do begin
- TempA := 255;
-
-
-
- //Skin Patch
- // 0= Transparent, 1-191= Fade Black to Col, 192= Col, 193-254 Fade Col to White, 255= White
- case PPix[Position2*3] of
- 0: TempA := 0;
- 1..191: Pix := $10000 * ((((Col div $10000) and $FF) * PPix[Position2*3]) div $Bf) + $100 * ((((Col div $100) and $FF) * PPix[Position2*3]) div $Bf) + (((Col and $FF) * PPix[Position2*3]) div $Bf);
- 192: Pix := Col;
- 193..254: Pix := Col + ($10000 * ((($FF - ((Col div $10000) and $FF)) * ((PPix[Position2*3] - $C0) * 4) ) div $FF) + $100 * ((($FF - ((Col div $100) and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF) + ((($FF - (Col and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF));
- 255: Pix := $FFFFFF;
- end;
-// 0.5.0 Original
-// case PPix[Position2*3] of
-// 0: TempA := 0;
-// 128: Pix := $10000 * ((Col div $10000) div 2) + $100 * (((Col div $100) and $FF) div 2) + (Col and $FF) div 2;
-// 192: Pix := Col;
-// 255: Pix := $FFFFFF;
-// end;
-
-
-
-
- TextureD32[Position*TextureB.Width + Position2 + 1, 1] := Pix div $10000;
- TextureD32[Position*TextureB.Width + Position2 + 1, 2] := (Pix div $100) and $FF;
- TextureD32[Position*TextureB.Width + Position2 + 1, 3] := Pix and $FF;
- TextureD32[Position*TextureB.Width + Position2 + 1, 4] := TempA;
- end;
- end;
- glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32);
- end;
-}
-
- 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 := oldWidth / newWidth;
- Result.TexH := oldHeight / newHeight;
-
- Result.Int := 1;
- Result.ColR := 1;
- Result.ColG := 1;
- Result.ColB := 1;
- Result.Alpha := 1;
-
- // 0.4.2 new test - default use whole texure, taking TexW and TexH as const and changing these
- Result.TexX1 := 0;
- Result.TexY1 := 0;
- Result.TexX2 := 1;
- Result.TexY2 := 1;
-
- // 0.5.0
- Result.Name := Identifier;
-
- SDL_FreeSurface(TexSurface);
-
-
- Log.BenchmarkEnd(4);
- if Log.BenchmarkTimeLength[4] >= 1 then
- Log.LogBenchmark('**********> Texture Load Time Warning - ' + Format + '/' + Identifier + '/' + Typ, 4);
-end;
-
-
-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
-
- if Name = '' then
- exit;
-
- // find texture entry
- T := FindTexture(Name);
-
- if T = -1 then
- begin
- // create texture entry
- T := Length(TextureDatabase.Texture);
- SetLength(TextureDatabase.Texture, T+1);
-
- TextureDatabase.Texture[T].Name := Name;
- TextureDatabase.Texture[T].Typ := Typ;
-
- // inform database that no textures have been loaded into memory
- TextureDatabase.Texture[T].Texture.TexNum := -1;
- TextureDatabase.Texture[T].TextureCache.TexNum := -1;
- end;
-
- // use preloaded texture
- if (not FromCache) or (FromCache and not Covers.CoverExists(Name)) then
- begin
- // use full texture
- if TextureDatabase.Texture[T].Texture.TexNum = -1 then
- begin
- // load texture
- {$ifdef blindydebug}
- Log.LogStatus('...', 'GetTexture('''+Name+''','''+Typ+''')');
- {$endif}
- TextureDatabase.Texture[T].Texture := LoadTexture(false, pchar(Name), 'JPG', pchar(Typ), $0);
- {$ifdef blindydebug}
- Log.LogStatus('done',' ');
- {$endif}
- end;
-
- // use texture
- Result := TextureDatabase.Texture[T].Texture;
- end;
-
- if FromCache and Covers.CoverExists(Name) then
- begin
- // use cache texture
- C := Covers.CoverNumber(Name);
-
- if TextureDatabase.Texture[T].TextureCache.TexNum = -1 then
- begin
- // load texture
- Covers.PrepareData(Name);
- TextureDatabase.Texture[T].TextureCache := CreateTexture(Covers.Data, Name, Covers.Cover[C].W, Covers.Cover[C].H, 24);
- end;
-
- // use texture
- Result := TextureDatabase.Texture[T].TextureCache;
- end;
-end;
-
-function TTextureUnit.FindTexture(Name: string): integer;
-var
- T: integer; // texture
-begin
- Result := -1;
- for T := 0 to high(TextureDatabase.Texture) do
- if TextureDatabase.Texture[T].Name = Name then
- Result := T;
-end;
-
-function TTextureUnit.LoadTexture(Identifier, Format, Typ: PChar; Col: LongWord): TTexture;
-begin
- Result := LoadTexture(false, Identifier, Format, Typ, Col);
-end;
-
-function TTextureUnit.LoadTexture(Identifier: string): TTexture;
-begin
- Result := LoadTexture(false, pchar(Identifier), 'JPG', 'Plain', 0);
-end;
-
-function TTextureUnit.CreateTexture(var Data: array of byte; Name: string; W, H: word; Bits: byte): TTexture;
-var
- Position: integer;
- Position2: integer;
- Pix: integer;
- ColInt: real;
- PPix: PByteArray;
- TempA: integer;
- Error: integer;
-begin
- Mipmapping := false;
-
- glGenTextures(1, ActTex); // ActText = new texture number
- glBindTexture(GL_TEXTURE_2D, ActTex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glTexImage2D(GL_TEXTURE_2D, 0, 3, W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, @Data[0]);
- if Mipmapping then begin
- Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 3, W, H, GL_RGB, GL_UNSIGNED_BYTE, @Data[0]);
- if Error > 0 then beep;
- end;
-
- Result.X := 0;
- Result.Y := 0;
- Result.W := 0;
- Result.H := 0;
- Result.ScaleW := 1;
- Result.ScaleH := 1;
- Result.Rot := 0;
- Result.TexNum := ActTex;
- Result.TexW := 1;
- Result.TexH := 1;
-
- Result.Int := 1;
- Result.ColR := 1;
- Result.ColG := 1;
- Result.ColB := 1;
- Result.Alpha := 1;
-
- // 0.4.2 new test - default use whole texure, taking TexW and TexH as const and changing these
- Result.TexX1 := 0;
- Result.TexY1 := 0;
- Result.TexX2 := 1;
- Result.TexY2 := 1;
-
- // 0.5.0
- Result.Name := Name;
-end;
-
-procedure TTextureUnit.UnloadTexture(Name: string; FromCache: boolean);
-var
- T: integer;
- TexNum: GLuint;
-begin
- T := FindTexture(Name);
-
- if not FromCache then begin
- TexNum := TextureDatabase.Texture[T].Texture.TexNum;
- if TexNum >= 0 then begin
- glDeleteTextures(1, @TexNum);
- TextureDatabase.Texture[T].Texture.TexNum := -1;
-// Log.LogError('Unload texture no '+IntToStr(TexNum));
- end;
- end else begin
- TexNum := TextureDatabase.Texture[T].TextureCache.TexNum;
- if TexNum >= 0 then begin
- glDeleteTextures(1, @TexNum);
- TextureDatabase.Texture[T].TextureCache.TexNum := -1;
-// Log.LogError('Unload texture cache no '+IntToStr(TexNum));
- end;
- end;
-end;
-
-{$IFDEF FPC}
-{$IFDEF win32}
-initialization
- {$I UltraStar.lrs}
-{$ENDIF}
-{$ENDIF}
-
-
-end.
+unit UTexture; +// added for easier debug disabling +{$define blindydebug} + +// Plain (alpha = 1) +// Transparent +// Colorized + +// obsolete? +// Transparent Range +// Font (white is drawn, black is transparent) +// Font Outline (Font with darker outline) +// Font Outline 2 (Font with darker outline) +// Font Black (black is drawn, white is transparent) +// Font Gray (gray is drawn, white is transparent) +// Arrow (for arrows, white is white, gray has color, black is transparent); + +interface + +{$I switches.inc} + +{$IFDEF FPC} + {$MODE DELPHI} +{$ENDIF} + +uses OpenGL12, + {$IFDEF win32} + windows, + {$ENDIF} + Math, + Classes, + SysUtils, + Graphics, + UCommon, + UThemes, + SDL, + sdlutils, + SDL_Image; + + + {$IFDEF Win32} + procedure glGenTextures(n: GLsizei; var textures: GLuint); stdcall; external opengl32; + +(* + {$ELSE} + {$ifdef darwin} + const opengl32 = '/System/Library/Frameworks/OpenGL.framework/Libraries/libGL.dylib'; + {$ELSE} + const opengl32 = 'libGL.so' ; // YES Capital GL + {$ENDIF} + + procedure glGenTextures(n: GLsizei; var textures: PGLuint); stdcall; external opengl32; +*) + {$ENDIF} + +type + TTexture = record + TexNum: integer; + X: real; + Y: real; + Z: real; // new + W: real; + H: real; + ScaleW: real; // for dynamic scalling while leaving width constant + ScaleH: real; // for dynamic scalling while leaving height constant + Rot: real; // 0 - 2*pi + Int: real; // intensity + ColR: real; + ColG: real; + ColB: real; + TexW: real; // used? + TexH: real; // used? + TexX1: real; + TexY1: real; + TexX2: real; + TexY2: real; + Alpha: real; + Name: string; // 0.5.0: experimental for handling cache images. maybe it's useful for dynamic skins + end; + + TTextureEntry = record + Name: string; + Typ: string; + + // we use normal TTexture, it's easier to implement and if needed - we copy ready data + Texture: TTexture; + TextureCache: TTexture; // 0.5.0 + end; + + TTextureDatabase = record + Texture: array of TTextureEntry; + end; + + TTextureUnit = class + + private + function LoadImage(Identifier: PChar): PSDL_Surface; + function pixfmt_eq(fmt1,fmt2: PSDL_Pixelformat): boolean; + procedure AdjustPixelFormat(var TexSurface: PSDL_Surface; Typ: PChar); + function GetScaledTexture(TexSurface: PSDL_Surface; W,H: Cardinal): PSDL_Surface; + procedure ScaleTexture(var TexSurface: PSDL_Surface; W,H: Cardinal); + procedure FitTexture(var TexSurface: PSDL_Surface; W,H: Cardinal); + procedure ColorizeTexture(TexSurface: PSDL_Surface; Col: Cardinal); + + public + Limit: integer; + CreateCacheMipmap: boolean; + +// function GetNumberFor + function GetTexture(Name, Typ: string): TTexture; overload; + function GetTexture(Name, Typ: string; FromCache: boolean): TTexture; overload; + function FindTexture(Name: string): integer; + function LoadTexture(FromRegistry: boolean; Identifier, Format, Typ: PChar; Col: LongWord): TTexture; overload; + function LoadTexture(Identifier, Format, Typ: PChar; Col: LongWord): TTexture; overload; + function LoadTexture(Identifier: string): TTexture; overload; + function CreateTexture(var Data: array of byte; Name: string; W, H: word; Bits: byte): TTexture; + procedure UnloadTexture(Name: string; FromCache: boolean); + Constructor Create; + Destructor Destroy; + end; + +var + Texture: TTextureUnit; + TextureDatabase: TTextureDatabase; + + // this should be in UDisplay?! + PrintScreenData: array[0..1024*768-1] of longword; + + ActTex: GLuint;//integer; + +// TextureD8: array[1..1024*1024] of byte; // 1MB + TextureD16: array[1..1024*1024, 1..2] of byte; // luminance/alpha tex (2MB) +// TextureD24: array[1..1024*1024, 1..3] of byte; // normal 24-bit tex (3MB) +// TextureD242: array[1..512*512, 1..3] of byte; // normal 24-bit tex (0,75MB) +// TextureD32: array[1..1024*1024, 1..4] of byte; // transparent 32-bit tex (4MB) + // total 40MB at 2048*2048 + // total 10MB at 1024*1024 + + Mipmapping: Boolean; + + CacheMipmap: array[0..256*256*3-1] of byte; // 3KB + CacheMipmapSurface: PSDL_Surface; + + +implementation + +uses ULog, + DateUtils, + UCovers, + {$IFDEF FPC} + LResources, + {$ENDIF} + StrUtils, dialogs; + +const + fmt_rgba: TSDL_Pixelformat=(palette: nil; + BitsPerPixel: 32; + BytesPerPixel: 4; + Rloss: 0; + Gloss: 0; + Bloss: 0; + Aloss: 0; + Rshift: 0; + Gshift: 8; + Bshift: 16; + Ashift: 24; + Rmask: $000000ff; + Gmask: $0000ff00; + Bmask: $00ff0000; + Amask: $ff000000; + ColorKey: 0; + Alpha: 255); + fmt_rgb: TSDL_Pixelformat=( palette: nil; + BitsPerPixel: 24; + BytesPerPixel: 3; + Rloss: 0; + Gloss: 0; + Bloss: 0; + Aloss: 0; + Rshift: 0; + Gshift: 8; + Bshift: 16; + Ashift: 0; + Rmask: $000000ff; + Gmask: $0000ff00; + Bmask: $00ff0000; + Amask: $00000000; + ColorKey: 0; + Alpha: 255); + + +Constructor TTextureUnit.Create; +begin + inherited Create; +end; + +Destructor TTextureUnit.Destroy; +begin + inherited Destroy; +end; + +function TTextureUnit.pixfmt_eq(fmt1,fmt2: PSDL_Pixelformat): boolean; +begin + if (fmt1^.BitsPerPixel = fmt2^.BitsPerPixel) and + (fmt1^.BytesPerPixel = fmt2^.BytesPerPixel) and + (fmt1^.Rloss = fmt2^.Rloss) and (fmt1^.Gloss = fmt2^.Gloss) and + (fmt1^.Bloss = fmt2^.Bloss) and (fmt1^.Rmask = fmt2^.Rmask) and + (fmt1^.Gmask = fmt2^.Gmask) and (fmt1^.Bmask = fmt2^.Bmask) and + (fmt1^.Rshift = fmt2^.Rshift) and (fmt1^.Gshift = fmt2^.Gshift) and + (fmt1^.Bshift = fmt2^.Bshift) + then + Result:=True + else + Result:=False; +end; + +// +++++++++++++++++++++ helpers for loadimage +++++++++++++++ + function SdlStreamSeek( context : PSDL_RWops; offset : Integer; whence : Integer ) : integer; cdecl; + var + stream : TStream; + origin : Word; + begin + stream := TStream( context.unknown ); + if ( stream = nil ) then + raise EInvalidContainer.Create( 'SDLStreamSeek on nil' ); + case whence of + 0 : origin := soFromBeginning; // Offset is from the beginning of the resource. Seek moves to the position Offset. Offset must be >= 0. + 1 : origin := soFromCurrent; // Offset is from the current position in the resource. Seek moves to Position + Offset. + 2 : origin := soFromEnd; + else + origin := soFromBeginning; // just in case + end; + Result := stream.Seek( offset, origin ); + end; + function SdlStreamRead( context : PSDL_RWops; Ptr : Pointer; size : Integer; maxnum: Integer ) : Integer; cdecl; + var + stream : TStream; + begin + stream := TStream( context.unknown ); + if ( stream = nil ) then + raise EInvalidContainer.Create( 'SDLStreamRead on nil' ); + try + Result := stream.read( Ptr^, Size * maxnum ) div size; + except + Result := -1; + end; + end; + function SDLStreamClose( context : PSDL_RWops ) : Integer; cdecl; + var + stream : TStream; + begin + stream := TStream( context.unknown ); + if ( stream = nil ) then + raise EInvalidContainer.Create( 'SDLStreamClose on nil' ); + stream.Free; + Result := 1; + end; +// ----------------------------------------------- + +function TTextureUnit.LoadImage(Identifier: PChar): PSDL_Surface; +var + + TexRWops: PSDL_RWops; + dHandle: THandle; + + {$IFDEF FPC} + lLazRes : TLResource; + lResData : TStringStream; + {$ELSE} + TexStream: TStream; + {$ENDIF} + +begin + Result := nil; + TexRWops := nil; + +// Log.LogStatus( Identifier, 'LoadImage' ); + + if ( FileExists(Identifier) ) then + begin + // load from file + Log.LogStatus( 'Is File', ' LoadImage' ); + try + Result:=IMG_Load(Identifier); + except + Log.LogStatus( 'ERROR Could not load from file' , Identifier); + beep; + Exit; + end; + end + else + begin + Log.LogStatus( 'IS Resource, because file does not exist.('+Identifier+')', ' LoadImage' ); + + // load from resource stream + {$IFNDEF FPC} + dHandle := FindResource(hInstance, Identifier, 'TEX'); + if dHandle=0 then + begin + Log.LogStatus( 'ERROR Could not find resource' , ' '+ Identifier); + beep; + Exit; + end; + + + TexStream := nil; + try + TexStream := TResourceStream.Create(HInstance, Identifier, 'TEX'); + except + Log.LogStatus( 'ERROR Could not load from resource' , Identifier); + beep; + Exit; + end; + + try + TexStream.position := 0; + try + TexRWops := SDL_AllocRW; + TexRWops.unknown := TUnknown(TexStream); + TexRWops.seek := SDLStreamSeek; + TexRWops.read := SDLStreamRead; + TexRWops.write := nil; + TexRWops.close := SDLStreamClose; + TexRWops.type_ := 2; + except + Log.LogStatus( 'ERROR Could not assign resource' , Identifier); + beep; + Exit; + end; + + Log.LogStatus( 'resource Assigned....' , Identifier); + Result:=IMG_Load_RW(TexRWops,0); + SDL_FreeRW(TexRWops); + + finally + if assigned( TexStream ) then + freeandnil( TexStream ); + end; + + + {$ELSE} + lLazRes := LazFindResource( Identifier, 'TEX' ); + if lLazRes <> nil then + begin + lResData := TStringStream.create( lLazRes.value ); + try + lResData.position := 0; + try + TexRWops := SDL_AllocRW; + TexRWops.unknown := TUnknown( lResData ); + TexRWops.seek := SDLStreamSeek; + TexRWops.read := SDLStreamRead; + TexRWops.write := nil; + TexRWops.close := SDLStreamClose; + TexRWops.type_ := 2; + except + Log.LogStatus( 'ERROR Could not assign resource ('+Identifier+')' , Identifier); + beep; + Exit; + end; + + Result := IMG_Load_RW(TexRWops,0); + SDL_FreeRW(TexRWops); + finally + freeandnil( lResData ); + end; + end + else + begin + Log.LogStatus( 'NOT found in Resource ('+Identifier+')', ' LoadImage' ); + end; + {$ENDIF} + + + end; +end; + +procedure TTextureUnit.AdjustPixelFormat(var TexSurface: PSDL_Surface; Typ: PChar); +var + TempSurface: PSDL_Surface; + NeededPixFmt: PSDL_Pixelformat; +begin + NeededPixFmt:=@fmt_rgba; + if Typ= 'Plain' then NeededPixFmt:=@fmt_rgb + else + if (Typ='Transparent') or + (Typ='Colorized') + then NeededPixFmt:=@fmt_rgba + else + NeededPixFmt:=@fmt_rgb; + + + if not pixfmt_eq(TexSurface^.format, NeededPixFmt) then + begin + TempSurface:=TexSurface; + TexSurface:=SDL_ConvertSurface(TempSurface,NeededPixFmt,SDL_SWSURFACE); + SDL_FreeSurface(TempSurface); + end; +end; + +function TTextureUnit.GetScaledTexture(TexSurface: PSDL_Surface; W,H: Cardinal): PSDL_Surface; +var + TempSurface: PSDL_Surface; +begin + TempSurface:=TexSurface; + Result:=SDL_ScaleSurfaceRect(TempSurface, + 0,0,TempSurface^.W,TempSurface^.H, + W,H); +end; + +procedure TTextureUnit.ScaleTexture(var TexSurface: PSDL_Surface; W,H: Cardinal); +var + TempSurface: PSDL_Surface; +begin + TempSurface:=TexSurface; + TexSurface:=SDL_ScaleSurfaceRect(TempSurface, + 0,0,TempSurface^.W,TempSurface^.H, + W,H); + SDL_FreeSurface(TempSurface); +end; + +procedure TTextureUnit.FitTexture(var TexSurface: PSDL_Surface; W,H: Cardinal); +var + TempSurface: PSDL_Surface; +begin + TempSurface:=TexSurface; + with TempSurface^.format^ do + TexSurface:=SDL_CreateRGBSurface(SDL_SWSURFACE,W,H,BitsPerPixel,RMask, GMask, BMask, AMask); + SDL_SetAlpha(TexSurface, 0, 255); + SDL_SetAlpha(TempSurface, 0, 255); + SDL_BlitSurface(TempSurface,nil,TexSurface,nil); + SDL_FreeSurface(TempSurface); +end; + +procedure TTextureUnit.ColorizeTexture(TexSurface: PSDL_Surface; Col: Cardinal); + //returns hue within range [0.0-6.0) + function col2h(Color:Cardinal):double; + var + clr,hls: array[0..2] of double; + delta: double; + begin + clr[0]:=((Color and $ff0000) shr 16)/255; + clr[1]:=((Color and $ff00) shr 8)/255; + clr[2]:=(Color and $ff)/255; + hls[1]:=maxvalue(clr); + delta:=hls[1]-minvalue(clr); + if clr[0]=hls[1] then hls[0]:=(clr[1]-clr[2])/delta + else if clr[1]=hls[1] then hls[0]:=2.0+(clr[2]-clr[0])/delta + else if clr[2]=hls[1] then hls[0]:=4.0+(clr[0]-clr[1])/delta; + if hls[0]<0.0 then hls[0]:=hls[0]+6.0; + if hls[0]=6.0 then hls[0]:=0.0; + col2h:=hls[0]; + end; + procedure ColorizePixel(Pix: PByteArray; hue: Double); + var + i,j,k: Cardinal; + clr, hls: array[0..2] of Double; + delta, f, p, q, t: Double; + begin + hls[0]:=hue; + + clr[0] := Pix[0]/255; + clr[1] := Pix[1]/255; + clr[2] := Pix[2]/255; + + //calculate luminance and saturation from rgb + hls[1] := maxvalue(clr); //l:=... + delta := hls[1] - minvalue(clr); + + if hls[1] = 0.0 then + hls[2] := 0.0 + else + hls[2] := delta/hls[1]; //v:=... + + // calc new rgb from our hls (h from color, l ans s from pixel) + // if (hls[1]<>0.0) and (hls[2]<>0.0) then // only if colorizing makes sense + begin + k:=trunc(hls[0]); + f:=hls[0]-k; + p:=hls[1]*(1.0-hls[2]); + q:=hls[1]*(1.0-(hls[2]*f)); + t:=hls[1]*(1.0-(hls[2]*(1.0-f))); + case k of + 0: begin clr[0]:=hls[1]; clr[1]:=t; clr[2]:=p; end; + 1: begin clr[0]:=q; clr[1]:=hls[1]; clr[2]:=p; end; + 2: begin clr[0]:=p; clr[1]:=hls[1]; clr[2]:=t; end; + 3: begin clr[0]:=p; clr[1]:=q; clr[2]:=hls[1]; end; + 4: begin clr[0]:=t; clr[1]:=p; clr[2]:=hls[1]; end; + 5: begin clr[0]:=hls[1]; clr[1]:=p; clr[2]:=q; end; + end; + // and store new rgb back into the image + Pix[0]:=floor(255*clr[0]); + Pix[1]:=floor(255*clr[1]); + Pix[2]:=floor(255*clr[2]); + end; + end; + +var + DestinationHue: Double; + PixelIndex: Cardinal; +begin + DestinationHue:=col2h(Col); + for PixelIndex:=0 to (TexSurface^.W*TexSurface^.H -1) do + ColorizePixel(@(PByteArray(TexSurface^.Pixels)[PixelIndex*TexSurface^.format.BytesPerPixel]),DestinationHue); +end; + +function TTextureUnit.LoadTexture(FromRegistry: boolean; Identifier, Format, Typ: PChar; Col: LongWord): TTexture; +var + TexSurface: PSDL_Surface; + MipmapSurface: PSDL_Surface; + newWidth, newHeight: Cardinal; + oldWidth, oldHeight: Cardinal; + kopierindex: Cardinal; +begin + Log.BenchmarkStart(4); + Mipmapping := true; +(* + Log.LogStatus( '', '' ); + + if Identifier = nil then + Log.LogStatus(' ERROR unknown Identifier', 'Id:'''+Identifier+''' Fmt:'''+Format+''' Typ:'''+Typ+'''') + else + Log.LogStatus(' should be ok - trying to load', 'Id:'''+Identifier+''' Fmt:'''+Format+''' Typ:'''+Typ+''''); +*) + + // load texture data into memory + {$ifdef blindydebug} + Log.LogStatus('',' LoadImage('''+Identifier+''') (called by '+Format+')'); + {$endif} + TexSurface := LoadImage(Identifier); + {$ifdef blindydebug} + Log.LogStatus('',' ok'); + {$endif} + if not assigned(TexSurface) then + begin + Log.LogStatus( 'ERROR Could not load texture' , Identifier +' '+ Format +' '+ Typ ); + beep; + Exit; + end; + // convert pixel format as needed + {$ifdef blindydebug} + Log.LogStatus('',' AdjustPixelFormat'); + {$endif} + AdjustPixelFormat(TexSurface, Typ); + {$ifdef blindydebug} + Log.LogStatus('',' ok'); + {$endif} + // adjust texture size (scale down, if necessary) + newWidth := TexSurface.W; + newHeight := TexSurface.H; + + if (newWidth > Limit) then + newWidth := Limit; + + if (newHeight > Limit) then + newHeight := Limit; + + if (TexSurface.W > newWidth) or (TexSurface.H > newHeight) then + begin + {$ifdef blindydebug} + Log.LogStatus('',' ScaleTexture'); + {$endif} + ScaleTexture(TexSurface,newWidth,newHeight); + {$ifdef blindydebug} + Log.LogStatus('',' ok'); + {$endif} + end; + + {$ifdef blindydebug} + Log.LogStatus('',' JB-1'); + {$endif} + + + + // don't actually understand, if this is needed... + // this should definately be changed... together with all this + // cover cache stuff + if (CreateCacheMipmap) and (Typ='Plain') then + begin + if (Covers.W <= 256) and (Covers.H <= 256) then + begin + {$ifdef blindydebug} + Log.LogStatus('',' GetScaledTexture('''+inttostr(Covers.W)+''','''+inttostr(Covers.H)+''') (for CacheMipmap)'); + {$endif} + MipmapSurface:=GetScaledTexture(TexSurface,Covers.W, Covers.H); + if assigned(MipmapSurface) then + begin + {$ifdef blindydebug} + Log.LogStatus('',' ok'); + Log.LogStatus('',' BlitSurface Stuff'); + {$endif} + // creating and freeing the surface could be done once, if Cover.W and Cover.H don't change + CacheMipmapSurface:=SDL_CreateRGBSurfaceFrom(@CacheMipmap[0], Covers.W, Covers.H, 24, Covers.W*3, $000000ff, $0000ff00, $00ff0000, 0); + SDL_BlitSurface(MipMapSurface,nil,CacheMipmapSurface,nil); + SDL_FreeSurface(CacheMipmapSurface); + {$ifdef blindydebug} + Log.LogStatus('',' ok'); + Log.LogStatus('',' SDL_FreeSurface (CacheMipmap)'); + {$endif} + SDL_FreeSurface(MipmapSurface); + {$ifdef blindydebug} + Log.LogStatus('',' ok'); + {$endif} + end + else + begin + Log.LogStatus(' Error creating CacheMipmap',' LoadTexture('''+Identifier+''')'); + end; + end; + // should i create a cache texture, if Covers.W/H are larger? + end; + + {$ifdef blindydebug} + Log.LogStatus('',' JB-2'); + {$endif} + + + // now we might colorize the whole thing + if Typ='Colorized' then + ColorizeTexture(TexSurface,Col); + + // save actual dimensions of our texture + oldWidth:=newWidth; + oldHeight:=newHeight; + // make texture dimensions be powers of 2 + newWidth:=Round(Power(2, Ceil(Log2(newWidth)))); + newHeight:=Round(Power(2, Ceil(Log2(newHeight)))); + if (newHeight <> oldHeight) or (newWidth <> oldWidth) then + FitTexture(TexSurface,newWidth,newHeight); + + // at this point we have the image in memory... + // scaled to be at most 1024x1024 pixels large + // scaled so that dimensions are powers of 2 + // and converted to either RGB or RGBA + + {$ifdef blindydebug} + Log.LogStatus('',' JB-3'); + {$endif} + + + // if we got a Texture of Type Plain, Transparent or Colorized, + // then we're done manipulating it + // and could now create our openGL texture from it + + // prepare OpenGL texture + + // JB_linux : this is causing AV's on linux... ActText seems to be nil ! + {$IFnDEF win32} + if pointer(ActTex) = nil then + exit; + {$endif} + + glGenTextures(1, @ActTex); + + glBindTexture(GL_TEXTURE_2D, ActTex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + // load data into gl texture + if (Typ = 'Transparent') or (Typ='Colorized') then begin + glTexImage2D(GL_TEXTURE_2D, 0, 4, newWidth, newHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, TexSurface.pixels); + end + {if Typ = 'Plain' then} else + begin + glTexImage2D(GL_TEXTURE_2D, 0, 3, newWidth, newHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, TexSurface.pixels); + end; + + {$ifdef blindydebug} + Log.LogStatus('',' JB-4'); + {$endif} + +{ + if Typ = 'Transparent Range' then + // set alpha to 256-green-component (not sure) + Pix := TextureB.Canvas.Pixels[Position2, Position]; + TextureD32[Position*TexNewW + Position2+1, 1] := Pix; + TextureD32[Position*TexNewW + Position2+1, 2] := Pix div 256; + TextureD32[Position*TexNewW + Position2+1, 3] := Pix div (256*256); + TextureD32[Position*TexNewW + Position2+1, 4] := 256 - Pix div 256; +} +{ + if Typ = 'Font' then + // either create luminance-alpha texture + // or use transparency from differently saved file + // or do something totally different (text engine with ttf) + Pix := PPix[Position2 * 3]; + TextureD16[Position*TextureB.Width + Position2 + 1, 1] := 255; + TextureD16[Position*TextureB.Width + Position2 + 1, 2] := Pix; + glTexImage2D(GL_TEXTURE_2D, 0, 2, TextureB.Width, TextureB.Height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16); +} +{ + if Typ = 'Font Outline' then + // no idea... + begin + TextureB.PixelFormat := pf24bit; + for Position := 0 to TextureB.Height-1 do begin + PPix := TextureB.ScanLine[Position]; + for Position2 := 0 to TextureB.Width-1 do begin + Pix := PPix[Position2 * 3]; + + Col := Pix; + if Col < 127 then Col := 127; + + TempA := Pix; + if TempA >= 95 then TempA := 255; + if TempA >= 31 then TempA := 255; + if Pix < 95 then TempA := (Pix * 256) div 96; + + + TextureD16[Position*TextureB.Width + Position2 + 1, 1] := Col; + TextureD16[Position*TextureB.Width + Position2 + 1, 2] := TempA; + end; + end; + glTexImage2D(GL_TEXTURE_2D, 0, 2, TextureB.Width, TextureB.Height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16); + end; +} +{ + if Typ = 'Font Outline 2' then + // same as above + begin + TextureB.PixelFormat := pf24bit; + for Position := 0 to TextureB.Height-1 do begin + PPix := TextureB.ScanLine[Position]; + for Position2 := 0 to TextureB.Width-1 do begin + Pix := PPix[Position2 * 3]; + + Col := Pix; + if Col < 31 then Col := 31; + + TempA := Pix; + if TempA >= 31 then TempA := 255; + if Pix < 31 then TempA := Pix * (256 div 32); + + TextureD16[Position*TextureB.Width + Position2 + 1, 1] := Col; + TextureD16[Position*TextureB.Width + Position2 + 1, 2] := TempA; + end; + end; + glTexImage2D(GL_TEXTURE_2D, 0, 2, TextureB.Width, TextureB.Height, 0, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16); + if Mipmapping then glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + if Mipmapping then begin + Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 2, TextureB.Width, TextureB.Height, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, @TextureD16); + if Error > 0 then beep; + end; + end; + + if Typ = 'Font Black' then + // and so on + begin + // normalnie 0,125s bez niczego 0,015s - 0,030s z pix 0,125s <-- ??? + // dimensions + TextureB.PixelFormat := pf24bit; + TexOrigW := TextureB.Width; + TexOrigH := TextureB.Height; + TexNewW := Round(Power(2, Ceil(Log2(TexOrigW)))); + TexNewH := Round(Power(2, Ceil(Log2(TexOrigH)))); + TextureB.Width := TexNewW; + TextureB.Height := TexNewH; + // copy and process pixeldata + for Position := 0 to TextureB.Height-1 do begin + PPix := TextureB.ScanLine[Position]; + for Position2 := 0 to TextureB.Width-1 do begin + Pix := PPix[Position2*3]; + TextureD32[Position*TextureB.Width + Position2 + 1, 1] := 255; + TextureD32[Position*TextureB.Width + Position2 + 1, 2] := 255; + TextureD32[Position*TextureB.Width + Position2 + 1, 3] := 255; + TextureD32[Position*TextureB.Width + Position2 + 1, 4] := 255 - (Pix mod 256); + end; + end; + glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32); + end; + + if Typ = 'Alpha Black Colored' then + // ... hope, noone needs this + begin + TextureB.PixelFormat := pf24bit; + TexOrigW := TextureB.Width; + TexOrigH := TextureB.Height; + TexNewW := Round(Power(2, Ceil(Log2(TexOrigW)))); + TexNewH := Round(Power(2, Ceil(Log2(TexOrigH)))); + TextureB.Width := TexNewW; + TextureB.Height := TexNewH; + // copy and process pixeldata + for Position := 0 to TextureB.Height-1 do begin + PPix := TextureB.ScanLine[Position]; + for Position2 := 0 to TextureB.Width-1 do begin + Pix := PPix[Position2*3]; + TextureD32[Position*TextureB.Width + Position2 + 1, 1] := (Col div $10000) and $FF; + TextureD32[Position*TextureB.Width + Position2 + 1, 2] := (Col div $100) and $FF; + TextureD32[Position*TextureB.Width + Position2 + 1, 3] := Col and $FF; + TextureD32[Position*TextureB.Width + Position2 + 1, 4] := 255 - (Pix mod 256); + end; + end; + glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32); + end; + + if Typ = 'Font Gray' then + begin + // dimensions + TexOrigW := TextureB.Width; + TexOrigH := TextureB.Height; + TexNewW := Round(Power(2, Ceil(Log2(TexOrigW)))); + TexNewH := Round(Power(2, Ceil(Log2(TexOrigH)))); + TextureB.Width := TexNewW; + TextureB.Height := TexNewH; + // copy and process pixeldata + for Position := 0 to TextureB.Height-1 do begin + for Position2 := 0 to TextureB.Width-1 do begin + Pix := TextureB.Canvas.Pixels[Position2, Position]; + TextureD32[Position*TextureB.Width + Position2 + 1, 1] := 127; + TextureD32[Position*TextureB.Width + Position2 + 1, 2] := 127; + TextureD32[Position*TextureB.Width + Position2 + 1, 3] := 127; + TextureD32[Position*TextureB.Width + Position2 + 1, 4] := 255 - (Pix mod 256); + end; + end; + glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32); + end; + + if Typ = 'Arrow' then + begin + TextureB.PixelFormat := pf24bit; + for Position := 0 to TextureB.Height-1 do begin + PPix := TextureB.ScanLine[Position]; + for Position2 := 0 to TextureB.Width-1 do begin + Pix := PPix[Position2 * 3]; + + // transparency + if Pix >= 127 then TempA := 255; + if Pix < 127 then TempA := Pix * 2; + + // ColInt = color intensity + if Pix < 127 then ColInt := 1; + if Pix >= 127 then ColInt := 2 - Pix / 128; + //0.75, 0.6, 0.25 + + TextureD32[Position*TextureB.Width + Position2 + 1, 1] := Round(ColInt * 0.75 * 255 + (1 - ColInt) * 255); + TextureD32[Position*TextureB.Width + Position2 + 1, 2] := Round(ColInt * 0.6 * 255 + (1 - ColInt) * 255); + TextureD32[Position*TextureB.Width + Position2 + 1, 3] := Round(ColInt * 0.25 * 255 + (1 - ColInt) * 255); + TextureD32[Position*TextureB.Width + Position2 + 1, 4] := TempA; + end; + end; + glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32); + + if Mipmapping then glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + if Mipmapping then begin + Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 4, TextureB.Width, TextureB.Height, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32); + if Error > 0 then beep; + end; + end; + + if Typ = 'Note Plain' then + begin + for Position := 0 to TextureB.Height-1 do + begin + PPix := TextureB.ScanLine[Position]; + for Position2 := 0 to TextureB.Width-1 do + begin + + + + // Skin Patch + // 0-191= Fade Black to Col, 192= Col, 193-254 Fade Col to White, 255= White + case PPix[Position2*3] of + 0..191: Pix := $10000 * ((((Col div $10000) and $FF) * PPix[Position2*3]) div $Bf) + $100 * ((((Col div $100) and $FF) * PPix[Position2*3]) div $Bf) + (((Col and $FF) * PPix[Position2*3]) div $Bf); + 192: Pix := Col; + 193..254: Pix := Col + ($10000 * ((($FF - ((Col div $10000) and $FF)) * ((PPix[Position2*3] - $C0) * 4) ) div $FF) + $100 * ((($FF - ((Col div $100) and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF) + ((($FF - (Col and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF)); + 255: Pix := $FFFFFF; + end; +// 0.5.0. Original +// case PPix[Position2*3] of +// 128: Pix := $10000 * ((Col div $10000) div 2) + $100 * (((Col div $100) and $FF) div 2) + (Col and $FF) div 2; +// 192: Pix := Col; +// 255: Pix := $FFFFFF; +// end; + + + + + + TextureD24[Position*TextureB.Width + Position2 + 1, 1] := Pix div $10000; + TextureD24[Position*TextureB.Width + Position2 + 1, 2] := (Pix div $100) and $FF; + TextureD24[Position*TextureB.Width + Position2 + 1, 3] := Pix and $FF; + end; + end; + glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureB.Width, TextureB.Height, 0, GL_RGB, GL_UNSIGNED_BYTE, @TextureD24); + end; + + if Typ = 'Note Transparent' then + begin + for Position := 0 to TextureB.Height-1 do begin + PPix := TextureB.ScanLine[Position]; + for Position2 := 0 to TextureB.Width-1 do begin + TempA := 255; + + + + //Skin Patch + // 0= Transparent, 1-191= Fade Black to Col, 192= Col, 193-254 Fade Col to White, 255= White + case PPix[Position2*3] of + 0: TempA := 0; + 1..191: Pix := $10000 * ((((Col div $10000) and $FF) * PPix[Position2*3]) div $Bf) + $100 * ((((Col div $100) and $FF) * PPix[Position2*3]) div $Bf) + (((Col and $FF) * PPix[Position2*3]) div $Bf); + 192: Pix := Col; + 193..254: Pix := Col + ($10000 * ((($FF - ((Col div $10000) and $FF)) * ((PPix[Position2*3] - $C0) * 4) ) div $FF) + $100 * ((($FF - ((Col div $100) and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF) + ((($FF - (Col and $FF)) * ((PPix[Position2*3] - $C0) * 4)) div $FF)); + 255: Pix := $FFFFFF; + end; +// 0.5.0 Original +// case PPix[Position2*3] of +// 0: TempA := 0; +// 128: Pix := $10000 * ((Col div $10000) div 2) + $100 * (((Col div $100) and $FF) div 2) + (Col and $FF) div 2; +// 192: Pix := Col; +// 255: Pix := $FFFFFF; +// end; + + + + + TextureD32[Position*TextureB.Width + Position2 + 1, 1] := Pix div $10000; + TextureD32[Position*TextureB.Width + Position2 + 1, 2] := (Pix div $100) and $FF; + TextureD32[Position*TextureB.Width + Position2 + 1, 3] := Pix and $FF; + TextureD32[Position*TextureB.Width + Position2 + 1, 4] := TempA; + end; + end; + glTexImage2D(GL_TEXTURE_2D, 0, 4, TextureB.Width, TextureB.Height, 0, GL_RGBA, GL_UNSIGNED_BYTE, @TextureD32); + end; +} + + {$ifdef blindydebug} + Log.LogStatus('',' JB-5'); + {$endif} + + + 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 := oldWidth / newWidth; + Result.TexH := oldHeight / newHeight; + + 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; + + {$ifdef blindydebug} + Log.LogStatus('',' JB-6'); + {$endif} + + + // 0.5.0 + Result.Name := Identifier; + + SDL_FreeSurface(TexSurface); + + {$ifdef blindydebug} + Log.LogStatus('',' JB-7'); + {$endif} + + + Log.BenchmarkEnd(4); + if Log.BenchmarkTimeLength[4] >= 1 then + Log.LogBenchmark('**********> Texture Load Time Warning - ' + Format + '/' + Identifier + '/' + Typ, 4); + + {$ifdef blindydebug} + Log.LogStatus('',' JB-8'); + {$endif} + +end; + + +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 + + if Name = '' then + exit; + + // find texture entry + T := FindTexture(Name); + + if T = -1 then + begin + // create texture entry + T := Length(TextureDatabase.Texture); + SetLength(TextureDatabase.Texture, T+1); + + TextureDatabase.Texture[T].Name := Name; + TextureDatabase.Texture[T].Typ := Typ; + + // inform database that no textures have been loaded into memory + TextureDatabase.Texture[T].Texture.TexNum := -1; + TextureDatabase.Texture[T].TextureCache.TexNum := -1; + end; + + // use preloaded texture + if (not FromCache) or (FromCache and not Covers.CoverExists(Name)) then + begin + // use full texture + if TextureDatabase.Texture[T].Texture.TexNum = -1 then + begin + // load texture + {$ifdef blindydebug} + Log.LogStatus('...', 'GetTexture('''+Name+''','''+Typ+''')'); + {$endif} + TextureDatabase.Texture[T].Texture := LoadTexture(false, pchar(Name), 'JPG', pchar(Typ), $0); + {$ifdef blindydebug} + Log.LogStatus('done',' '); + {$endif} + end; + + // use texture + Result := TextureDatabase.Texture[T].Texture; + end; + + if FromCache and Covers.CoverExists(Name) then + begin + // use cache texture + C := Covers.CoverNumber(Name); + + if TextureDatabase.Texture[T].TextureCache.TexNum = -1 then + begin + // load texture + Covers.PrepareData(Name); + TextureDatabase.Texture[T].TextureCache := CreateTexture(Covers.Data, Name, Covers.Cover[C].W, Covers.Cover[C].H, 24); + end; + + // use texture + Result := TextureDatabase.Texture[T].TextureCache; + end; +end; + +function TTextureUnit.FindTexture(Name: string): integer; +var + T: integer; // texture +begin + Result := -1; + for T := 0 to high(TextureDatabase.Texture) do + if TextureDatabase.Texture[T].Name = Name then + Result := T; +end; + +function TTextureUnit.LoadTexture(Identifier, Format, Typ: PChar; Col: LongWord): TTexture; +begin + Result := LoadTexture(false, Identifier, Format, Typ, Col); +end; + +function TTextureUnit.LoadTexture(Identifier: string): TTexture; +begin + Result := LoadTexture(false, pchar(Identifier), 'JPG', 'Plain', 0); +end; + +function TTextureUnit.CreateTexture(var Data: array of byte; Name: string; W, H: word; Bits: byte): TTexture; +var + Position: integer; + Position2: integer; + Pix: integer; + ColInt: real; + PPix: PByteArray; + TempA: integer; + Error: integer; +begin + Mipmapping := false; + + glGenTextures(1, @ActTex); // ActText = new texture number + glBindTexture(GL_TEXTURE_2D, ActTex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glTexImage2D(GL_TEXTURE_2D, 0, 3, W, H, 0, GL_RGB, GL_UNSIGNED_BYTE, @Data[0]); + if Mipmapping then begin + Error := gluBuild2DMipmaps(GL_TEXTURE_2D, 3, W, H, GL_RGB, GL_UNSIGNED_BYTE, @Data[0]); + if Error > 0 then beep; + end; + + Result.X := 0; + Result.Y := 0; + Result.W := 0; + Result.H := 0; + Result.ScaleW := 1; + Result.ScaleH := 1; + Result.Rot := 0; + Result.TexNum := ActTex; + Result.TexW := 1; + Result.TexH := 1; + + Result.Int := 1; + Result.ColR := 1; + Result.ColG := 1; + Result.ColB := 1; + Result.Alpha := 1; + + // 0.4.2 new test - default use whole texure, taking TexW and TexH as const and changing these + Result.TexX1 := 0; + Result.TexY1 := 0; + Result.TexX2 := 1; + Result.TexY2 := 1; + + // 0.5.0 + Result.Name := Name; +end; + +procedure TTextureUnit.UnloadTexture(Name: string; FromCache: boolean); +var + T: integer; + TexNum: GLuint; +begin + T := FindTexture(Name); + + if not FromCache then begin + TexNum := TextureDatabase.Texture[T].Texture.TexNum; + if TexNum >= 0 then begin + glDeleteTextures(1, @TexNum); + TextureDatabase.Texture[T].Texture.TexNum := -1; +// Log.LogError('Unload texture no '+IntToStr(TexNum)); + end; + end else begin + TexNum := TextureDatabase.Texture[T].TextureCache.TexNum; + if TexNum >= 0 then begin + glDeleteTextures(1, @TexNum); + TextureDatabase.Texture[T].TextureCache.TexNum := -1; +// Log.LogError('Unload texture cache no '+IntToStr(TexNum)); + end; + end; +end; + +{$IFDEF FPC} +initialization + {$I UltraStar.lrs} +{$ENDIF} + + +end. diff --git a/Game/Code/Classes/UThemes.pas b/Game/Code/Classes/UThemes.pas index 9da176df..00b763f0 100644 --- a/Game/Code/Classes/UThemes.pas +++ b/Game/Code/Classes/UThemes.pas @@ -1,2200 +1,2212 @@ -unit UThemes;
-
-interface
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-uses
- ULog,
- IniFiles,
- SysUtils,
- Classes;
-
-type
- TRGB = record
- R: single;
- G: single;
- B: single;
- end;
-
- TRGBA = record
- R, G, B, A: Double;
- 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;
- //Reflection Mod
- Reflection: boolean;
- Reflectionspacing: Real;
- end;
- AThemeStatic = array of TThemeStatic;
-
- TThemeText = record
- X: integer;
- Y: integer;
- W: 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;
- Z: Real;
- 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;
-
- Visible: Boolean;
-
- //Reflection Mod
- Reflection: boolean;
- Reflectionspacing: Real;
- //Fade Mod
- SelectH: integer;
- SelectW: integer;
- Fade: boolean;
- FadeText: boolean;
- DeSelectReflectionspacing : Real;
- FadeTex: string;
- FadeTexPos: integer;
-
- //Button Collection Mod
- Parent: Byte; //Number of the Button Collection this Button is assigned to. IF 0: No Assignement
- end;
-
- //Button Collection Mod
- TThemeButtonCollection = record
- Style: TThemeButton;
- ChildCount: Byte; //No of assigned Childs
- FirstChild: Byte; //No of Child on whose Interaction Position the Button should be
- end;
-
- AThemeButtonCollection = array of TThemeButtonCollection;
- PAThemeButtonCollection = ^AThemeButtonCollection;
-
- 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;
- Z: real;
-
- TextSize: integer;
-
- //SBGW Mod
- SBGW: 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;
-
- PThemeBasic = ^TThemeBasic;
- TThemeBasic = class
- Background: TThemeBackground;
- Text: AThemeText;
- Static: AThemeStatic;
-
- //Button Collection Mod
- ButtonCollection: AThemeButtonCollection;
- end;
-
- TThemeLoading = class(TThemeBasic)
- StaticAnimation: TThemeStatic;
- TextLoading: TThemeText;
- end;
-
- TThemeMain = class(TThemeBasic)
- ButtonSolo: TThemeButton;
- ButtonMulti: TThemeButton;
- ButtonStat: TThemeButton;
- ButtonEditor: TThemeButton;
- ButtonOptions: TThemeButton;
- ButtonExit: TThemeButton;
-
- TextDescription: TThemeText;
- TextDescriptionLong: TThemeText;
- Description: array[0..5] of string;
- DescriptionLong: array[0..5] 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;
-
- //Video Icon Mod
- VideoIcon: TThemeStatic;
-
- //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 and Non Party specific Statics and Texts
- StaticParty: AThemeStatic;
- TextParty: AThemeText;
-
- StaticNonParty: AThemeStatic;
- TextNonParty: AThemeText;
-
- //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)
-
- //TimeBar mod
- StaticTimeProgress: TThemeStatic;
- TextTimeText : TThemeText;
- //eoa TimeBar mod
-
- StaticP1: TThemeStatic;
- TextP1: TThemeText;
- StaticP1ScoreBG: TThemeStatic; //Static for ScoreBG
- TextP1Score: TThemeText;
-
- //moveable singbar mod
- StaticP1SingBar: TThemeStatic;
- StaticP1ThreePSingBar: TThemeStatic;
- StaticP1TwoPSingBar: TThemeStatic;
- StaticP2RSingBar: TThemeStatic;
- StaticP2MSingBar: TThemeStatic;
- StaticP3SingBar: TThemeStatic;
- //eoa moveable singbar
-
- //added for ps3 skin
- //game in 2/4 player modi
- StaticP1TwoP: TThemeStatic;
- StaticP1TwoPScoreBG: TThemeStatic; //Static for ScoreBG
- TextP1TwoP: TThemeText;
- TextP1TwoPScore: TThemeText;
- //game in 3/6 player modi
- StaticP1ThreeP: TThemeStatic;
- StaticP1ThreePScoreBG: TThemeStatic; //Static for ScoreBG
- TextP1ThreeP: TThemeText;
- TextP1ThreePScore: TThemeText;
- //eoa
-
- 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;
-
- //Linebonus Translations
- LineBonusText: Array [0..8] of String;
- end;
-
- TThemeScore = class(TThemeBasic)
- TextArtist: TThemeText;
- TextTitle: TThemeText;
-
- TextArtistTitle: TThemeText;
-
- PlayerStatic: array[1..6] of AThemeStatic;
- PlayerTexts: array[1..6] of AThemeText;
-
- 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;
- ButtonAdvanced: TThemeButton;
- ButtonExit: TThemeButton;
-
- TextDescription: TThemeText;
- Description: array[0..7] 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;
- //Song Preview
- SelectSlidePreviewVolume: TThemeSelectSlide;
- SelectSlidePreviewFading: TThemeSelectSlide;
- 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;
-
- TThemeOptionsAdvanced = class(TThemeBasic)
- SelectLoadAnimation: TThemeSelect;
- SelectEffectSing: TThemeSelect;
- SelectScreenFade: TThemeSelect;
- SelectLineBonus: TThemeSelect;
- SelectAskbeforeDel: TThemeSelect;
- SelectOnSongClick: TThemeSelectSlide;
- SelectPartyPopup: TThemeSelect;
- ButtonExit: TThemeButton;
- end;
-
- //Error- and Check-Popup
- TThemeError = class(TThemeBasic)
- Button1: TThemeButton;
- TextError: TThemeText;
- end;
-
- TThemeCheck = class(TThemeBasic)
- Button1: TThemeButton;
- Button2: TThemeButton;
- TextCheck: TThemeText;
- end;
-
-
- //ScreenSong Menue
- TThemeSongMenu = class(TThemeBasic)
- Button1: TThemeButton;
- Button2: TThemeButton;
- Button3: TThemeButton;
- Button4: TThemeButton;
-
- SelectSlide3: TThemeSelectSlide;
-
- TextMenu: TThemeText;
- end;
-
- TThemeSongJumpTo = class(TThemeBasic)
- ButtonSearchText: TThemeButton;
- SelectSlideType: TThemeSelectSlide;
- TextFound: TThemeText;
-
- //Translated Texts
- Songsfound: String;
- NoSongsfound: String;
- CatText: String;
- IType: array [0..2] of String;
- 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;
- TextTeam1Players: TThemeText;
- TextTeam2Players: TThemeText;
- TextTeam3Players: TThemeText;
-
- StaticTeam1: TThemeStatic;
- StaticTeam2: TThemeStatic;
- StaticTeam3: TThemeStatic;
- StaticNextPlayer1: TThemeStatic;
- StaticNextPlayer2: TThemeStatic;
- StaticNextPlayer3: TThemeStatic;
- end;
-
- TThemePartyScore = class(TThemeBasic)
- TextScoreTeam1: TThemeText;
- TextScoreTeam2: TThemeText;
- TextScoreTeam3: TThemeText;
- TextNameTeam1: TThemeText;
- TextNameTeam2: TThemeText;
- TextNameTeam3: TThemeText;
- StaticTeam1: TThemeStatic;
- StaticTeam1BG: TThemeStatic;
- StaticTeam1Deco: TThemeStatic;
- StaticTeam2: TThemeStatic;
- StaticTeam2BG: TThemeStatic;
- StaticTeam2Deco: TThemeStatic;
- StaticTeam3: TThemeStatic;
- StaticTeam3BG: TThemeStatic;
- StaticTeam3Deco: TThemeStatic;
-
- DecoTextures: record
- ChangeTextures: Boolean;
-
- FirstTexture: String;
- FirstTyp: String;
- FirstColor: String;
-
- SecondTexture: String;
- SecondTyp: String;
- SecondColor: String;
-
- ThirdTexture: String;
- ThirdTyp: String;
- ThirdColor: String;
- end;
-
-
- TextWinner: TThemeText;
- end;
-
- TThemePartyWin = class(TThemeBasic)
- TextScoreTeam1: TThemeText;
- TextScoreTeam2: TThemeText;
- TextScoreTeam3: TThemeText;
- TextNameTeam1: TThemeText;
- TextNameTeam2: TThemeText;
- TextNameTeam3: TThemeText;
- StaticTeam1: TThemeStatic;
- StaticTeam1BG: TThemeStatic;
- StaticTeam1Deco: TThemeStatic;
- StaticTeam2: TThemeStatic;
- StaticTeam2BG: TThemeStatic;
- StaticTeam2Deco: TThemeStatic;
- StaticTeam3: TThemeStatic;
- StaticTeam3BG: TThemeStatic;
- StaticTeam3Deco: 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;
-
- //Stats Screens
- TThemeStatMain = class(TThemeBasic)
- ButtonScores: TThemeButton;
- ButtonSingers: TThemeButton;
- ButtonSongs: TThemeButton;
- ButtonBands: TThemeButton;
- ButtonExit: TThemeButton;
-
- TextOverview: TThemeText;
- end;
-
- TThemeStatDetail = class(TThemeBasic)
- ButtonNext: TThemeButton;
- ButtonPrev: TThemeButton;
- ButtonReverse: TThemeButton;
- ButtonExit: TThemeButton;
-
- TextDescription: TThemeText;
- TextPage: TThemeText;
- TextList: AThemeText;
-
- Description: array[0..3] of string;
- DescriptionR: array[0..3] of string;
- FormatStr: array[0..3] of string;
- PageStr: String;
- end;
-
- //Playlist Translations
- TThemePlaylist = record
- CatText: string;
- end;
-
- TTheme = class
- private
- {$IFDEF THEMESAVE}
- ThemeIni: TIniFile;
- {$ELSE}
- ThemeIni: TMemIniFile;
- {$ENDIF}
-
- LastThemeBasic: TThemeBasic;
- public
-
- 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;
- OptionsAdvanced: TThemeOptionsAdvanced;
- //error and check popup
- ErrorPopup: TThemeError;
- CheckPopup: TThemeCheck;
- //ScreenSong extensions
- SongMenu: TThemeSongMenu;
- SongJumpto: TThemeSongJumpTo;
- //Party Screens:
- PartyNewRound: TThemePartyNewRound;
- PartyScore: TThemePartyScore;
- PartyWin: TThemePartyWin;
- PartyOptions: TThemePartyOptions;
- PartyPlayer: TThemePartyPlayer;
-
- //Stats Screens:
- StatMain: TThemeStatMain;
- StatDetail: TThemeStatDetail;
-
- Playlist: TThemePlaylist;
-
- ILevel: array[0..2] of String;
-
- 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; const Collections: PAThemeButtonCollection = nil);
- procedure ThemeLoadButtonCollection(var Collection: TThemeButtonCollection; Name: string);
- procedure ThemeLoadButtonCollections(var Collections: AThemeButtonCollection; 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;
- OptionsAdvanced := TThemeOptionsAdvanced.Create;
-
- ErrorPopup := TThemeError.Create;
- CheckPopup := TThemeCheck.Create;
-
- SongMenu := TThemeSongMenu.Create;
- SongJumpto := TThemeSongJumpto.Create;
- //Party Screens
- PartyNewRound := TThemePartyNewRound.Create;
- PartyWin := TThemePartyWin.Create;
- PartyScore := TThemePartyScore.Create;
- PartyOptions := TThemePartyOptions.Create;
- PartyPlayer := TThemePartyPlayer.Create;
-
- //Stats Screens:
- StatMain := TThemeStatMain.Create;
- StatDetail := TThemeStatDetail.Create;
-
- LoadTheme(FileName, Color);
-
-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');
- ThemeLoadText(Loading.TextLoading, 'LoadingTextLoading');
- ThemeLoadStatic(Loading.StaticAnimation, 'LoadingStaticAnimation');
-
- // Main
- ThemeLoadBasic(Main, 'Main');
-
- ThemeLoadText(Main.TextDescription, 'MainTextDescription');
- ThemeLoadText(Main.TextDescriptionLong, 'MainTextDescriptionLong');
- ThemeLoadButton(Main.ButtonSolo, 'MainButtonSolo');
- ThemeLoadButton(Main.ButtonMulti, 'MainButtonMulti');
- ThemeLoadButton(Main.ButtonStat, 'MainButtonStats');
- ThemeLoadButton(Main.ButtonEditor, 'MainButtonEditor');
- ThemeLoadButton(Main.ButtonOptions, 'MainButtonOptions');
- ThemeLoadButton(Main.ButtonExit, 'MainButtonExit');
-
- //Main Desc 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_MULTI');
- Main.DescriptionLong[1] := Language.Translate('SING_MULTI_DESC');
- Main.Description[2] := Language.Translate('SING_STATS');
- Main.DescriptionLong[2] := Language.Translate('SING_STATS_DESC');
- Main.Description[3] := Language.Translate('SING_EDITOR');
- Main.DescriptionLong[3] := Language.Translate('SING_EDITOR_DESC');
- Main.Description[4] := Language.Translate('SING_GAME_OPTIONS');
- Main.DescriptionLong[4] := Language.Translate('SING_GAME_OPTIONS_DESC');
- Main.Description[5] := Language.Translate('SING_EXIT');
- Main.DescriptionLong[5] := Language.Translate('SING_EXIT_DESC');
- {{$ENDIF}
-
- //Main Desc 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');
-
- //Video Icon Mod
- ThemeLoadStatic(Song.VideoIcon, 'SongVideoIcon');
-
- //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', 300);
- Song.Cover.Y := ThemeIni.ReadInteger('SongCover', 'Y', 190);
- Song.Cover.W := ThemeIni.ReadInteger('SongCover', 'W', 300);
- Song.Cover.H := ThemeIni.ReadInteger('SongCover', 'H', 200);
- Song.Cover.Style := ThemeIni.ReadInteger('SongCover', 'Style', 4);
- 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', 0);
- Song.Equalizer.Y := ThemeIni.ReadInteger('SongEqualizer', 'Y', 0);
- 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);
-
- //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
- else begin
- Song.Equalizer.ColR := 0;
- Song.Equalizer.ColG := 0;
- Song.Equalizer.ColB := 0;
- end;
- //Load Equalizer Pos and Size from Theme Mod End
-
- //Party and Non Party specific Statics and Texts
- ThemeLoadStatics (Song.StaticParty, 'SongStaticParty');
- ThemeLoadTexts (Song.TextParty, 'SongTextParty');
-
- ThemeLoadStatics (Song.StaticNonParty, 'SongStaticNonParty');
- ThemeLoadTexts (Song.TextNonParty, 'SongTextNonParty');
-
- //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');
-
-
- // Sing
- ThemeLoadBasic(Sing, 'Sing');
-
- //TimeBar mod
- ThemeLoadStatic(Sing.StaticTimeProgress, 'SingTimeProgress');
- ThemeLoadText(Sing.TextTimeText, 'SingTimeText');
- //eoa TimeBar mod
-
- //moveable singbar mod
- ThemeLoadStatic(Sing.StaticP1SingBar, 'SingP1SingBar');
- ThemeLoadStatic(Sing.StaticP1TwoPSingBar, 'SingP1TwoPSingBar');
- ThemeLoadStatic(Sing.StaticP1ThreePSingBar, 'SingP1ThreePSingBar');
- ThemeLoadStatic(Sing.StaticP2RSingBar, 'SingP2RSingBar');
- ThemeLoadStatic(Sing.StaticP2MSingBar, 'SingP2MSingBar');
- ThemeLoadStatic(Sing.StaticP3SingBar, 'SingP3SingBar');
- //eoa moveable singbar
-
- ThemeLoadStatic(Sing.StaticP1, 'SingP1Static');
- ThemeLoadText(Sing.TextP1, 'SingP1Text');
- ThemeLoadStatic(Sing.StaticP1ScoreBG, 'SingP1Static2');
- ThemeLoadText(Sing.TextP1Score, 'SingP1TextScore');
- //Added for ps3 skin
- //This one is shown in 2/4P mode
- //if it exists, otherwise the one Player equivaltents are used
- if (ThemeIni.SectionExists('SingP1TwoPTextScore')) then
- begin
- ThemeLoadStatic(Sing.StaticP1TwoP, 'SingP1TwoPStatic');
- ThemeLoadText(Sing.TextP1TwoP, 'SingP1TwoPText');
- ThemeLoadStatic(Sing.StaticP1TwoPScoreBG, 'SingP1TwoPStatic2');
- ThemeLoadText(Sing.TextP1TwoPScore, 'SingP1TwoPTextScore');
- end
- else
- begin
- Sing.StaticP1TwoP := Sing.StaticP1;
- Sing.TextP1TwoP := Sing.TextP1;
- Sing.StaticP1TwoPScoreBG := Sing.StaticP1ScoreBG;
- Sing.TextP1TwoPScore := Sing.TextP1Score;
- end;
-
- //This one is shown in 3/6P mode
- //if it exists, otherwise the one Player equivaltents are used
- if (ThemeIni.SectionExists('SingP1TwoPTextScore')) then
- begin
- ThemeLoadStatic(Sing.StaticP1ThreeP, 'SingP1ThreePStatic');
- ThemeLoadText(Sing.TextP1ThreeP, 'SingP1ThreePText');
- ThemeLoadStatic(Sing.StaticP1ThreePScoreBG, 'SingP1ThreePStatic2');
- ThemeLoadText(Sing.TextP1ThreePScore, 'SingP1ThreePTextScore');
- end
- else
- begin
- Sing.StaticP1ThreeP := Sing.StaticP1;
- Sing.TextP1ThreeP := Sing.TextP1;
- Sing.StaticP1ThreePScoreBG := Sing.StaticP1ScoreBG;
- Sing.TextP1ThreePScore := Sing.TextP1Score;
- end;
- //eoa
- ThemeLoadStatic(Sing.StaticP2R, 'SingP2RStatic');
- ThemeLoadText(Sing.TextP2R, 'SingP2RText');
- ThemeLoadStatic(Sing.StaticP2RScoreBG, 'SingP2RStatic2');
- ThemeLoadText(Sing.TextP2RScore, 'SingP2RTextScore');
-
- ThemeLoadStatic(Sing.StaticP2M, 'SingP2MStatic');
- ThemeLoadText(Sing.TextP2M, 'SingP2MText');
- ThemeLoadStatic(Sing.StaticP2MScoreBG, 'SingP2MStatic2');
- ThemeLoadText(Sing.TextP2MScore, 'SingP2MTextScore');
-
- ThemeLoadStatic(Sing.StaticP3R, 'SingP3RStatic');
- ThemeLoadText(Sing.TextP3R, 'SingP3RText');
- ThemeLoadStatic(Sing.StaticP3RScoreBG, 'SingP3RStatic2');
- ThemeLoadText(Sing.TextP3RScore, 'SingP3RTextScore');
-
- //Line Bonus Texts
- Sing.LineBonusText[0] := Language.Translate('POPUP_AWFUL');
- Sing.LineBonusText[1] := Sing.LineBonusText[0];
- Sing.LineBonusText[2] := Language.Translate('POPUP_POOR');
- Sing.LineBonusText[3] := Language.Translate('POPUP_BAD');
- Sing.LineBonusText[4] := Language.Translate('POPUP_NOTBAD');
- Sing.LineBonusText[5] := Language.Translate('POPUP_GOOD');
- Sing.LineBonusText[6] := Language.Translate('POPUP_GREAT');
- Sing.LineBonusText[7] := Language.Translate('POPUP_AWESOME');
- Sing.LineBonusText[8] := Language.Translate('POPUP_PERFECT');
-
- // Score
- ThemeLoadBasic(Score, 'Score');
-
- ThemeLoadText(Score.TextArtist, 'ScoreTextArtist');
- ThemeLoadText(Score.TextTitle, 'ScoreTextTitle');
- ThemeLoadText(Score.TextArtistTitle, 'ScoreTextArtistTitle');
-
- for I := 1 to 6 do begin
- ThemeLoadStatics(Score.PlayerStatic[I], 'ScorePlayer' + IntToStr(I) + 'Static');
- ThemeLoadTexts(Score.PlayerTexts[I], 'ScorePlayer' + IntToStr(I) + 'Text');
-
- 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.ButtonAdvanced, 'OptionsButtonAdvanced');
- 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_ADVANCED');
- Options.Description[7] := 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');
- //Song Preview
- ThemeLoadSelectSlide(OptionsSound.SelectSlidePreviewVolume, 'OptionsSoundSelectSlidePreviewVolume');
- ThemeLoadSelectSlide(OptionsSound.SelectSlidePreviewFading, 'OptionsSoundSelectSlidePreviewFading');
-
- 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');
-
- //Options Advanced
- ThemeLoadBasic(OptionsAdvanced, 'OptionsAdvanced');
-
- ThemeLoadSelect (OptionsAdvanced.SelectLoadAnimation, 'OptionsAdvancedSelectLoadAnimation');
- ThemeLoadSelect (OptionsAdvanced.SelectScreenFade, 'OptionsAdvancedSelectScreenFade');
- ThemeLoadSelect (OptionsAdvanced.SelectEffectSing, 'OptionsAdvancedSelectEffectSing');
- ThemeLoadSelect (OptionsAdvanced.SelectLineBonus, 'OptionsAdvancedSelectLineBonus');
- ThemeLoadSelectSlide (OptionsAdvanced.SelectOnSongClick, 'OptionsAdvancedSelectSlideOnSongClick');
- ThemeLoadSelect (OptionsAdvanced.SelectAskbeforeDel, 'OptionsAdvancedSelectAskbeforeDel');
- ThemeLoadSelect (OptionsAdvanced.SelectPartyPopup, 'OptionsAdvancedSelectPartyPopup');
- ThemeLoadButton (OptionsAdvanced.ButtonExit, 'OptionsAdvancedButtonExit');
-
- //error and check popup
- ThemeLoadBasic (ErrorPopup, 'ErrorPopup');
- ThemeLoadButton(ErrorPopup.Button1, 'ErrorPopupButton1');
- ThemeLoadText (ErrorPopup.TextError,'ErrorPopupText');
- ThemeLoadBasic (CheckPopup, 'CheckPopup');
- ThemeLoadButton(CheckPopup.Button1, 'CheckPopupButton1');
- ThemeLoadButton(CheckPopup.Button2, 'CheckPopupButton2');
- ThemeLoadText(CheckPopup.TextCheck , 'CheckPopupText');
-
- //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');
-
- //Song Jumpto
- ThemeLoadBasic (SongJumpto, 'SongJumpto');
- ThemeLoadButton(SongJumpto.ButtonSearchText, 'SongJumptoButtonSearchText');
- ThemeLoadSelectSlide(SongJumpto.SelectSlideType, 'SongJumptoSelectSlideType');
- ThemeLoadText(SongJumpto.TextFound, 'SongJumptoTextFound');
- //Translations
- SongJumpto.IType[0] := Language.Translate('SONG_JUMPTO_TYPE1');
- SongJumpto.IType[1] := Language.Translate('SONG_JUMPTO_TYPE2');
- SongJumpto.IType[2] := Language.Translate('SONG_JUMPTO_TYPE3');
- SongJumpto.SongsFound := Language.Translate('SONG_JUMPTO_SONGSFOUND');
- SongJumpto.NoSongsFound := Language.Translate('SONG_JUMPTO_NOSONGSFOUND');
- SongJumpto.CatText := Language.Translate('SONG_JUMPTO_CATTEXT');
-
- //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');
-
- ThemeLoadText (PartyNewRound.TextTeam1Players, 'PartyNewRoundTextTeam1Players');
- ThemeLoadText (PartyNewRound.TextTeam2Players, 'PartyNewRoundTextTeam2Players');
- ThemeLoadText (PartyNewRound.TextTeam3Players, 'PartyNewRoundTextTeam3Players');
-
- ThemeLoadStatic (PartyNewRound.StaticTeam1, 'PartyNewRoundStaticTeam1');
- ThemeLoadStatic (PartyNewRound.StaticTeam2, 'PartyNewRoundStaticTeam2');
- ThemeLoadStatic (PartyNewRound.StaticTeam3, 'PartyNewRoundStaticTeam3');
- ThemeLoadStatic (PartyNewRound.StaticNextPlayer1, 'PartyNewRoundStaticNextPlayer1');
- ThemeLoadStatic (PartyNewRound.StaticNextPlayer2, 'PartyNewRoundStaticNextPlayer2');
- ThemeLoadStatic (PartyNewRound.StaticNextPlayer3, 'PartyNewRoundStaticNextPlayer3');
-
- //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.StaticTeam1BG, 'PartyScoreStaticTeam1BG');
- ThemeLoadStatic (PartyScore.StaticTeam1Deco, 'PartyScoreStaticTeam1Deco');
- ThemeLoadStatic (PartyScore.StaticTeam2, 'PartyScoreStaticTeam2');
- ThemeLoadStatic (PartyScore.StaticTeam2BG, 'PartyScoreStaticTeam2BG');
- ThemeLoadStatic (PartyScore.StaticTeam2Deco, 'PartyScoreStaticTeam2Deco');
- ThemeLoadStatic (PartyScore.StaticTeam3, 'PartyScoreStaticTeam3');
- ThemeLoadStatic (PartyScore.StaticTeam3BG, 'PartyScoreStaticTeam3BG');
- ThemeLoadStatic (PartyScore.StaticTeam3Deco, 'PartyScoreStaticTeam3Deco');
-
- //Load Party Score DecoTextures Object
- PartyScore.DecoTextures.ChangeTextures := (ThemeIni.ReadInteger('PartyScoreDecoTextures', 'ChangeTextures', 0) = 1);
-
- PartyScore.DecoTextures.FirstTexture := ThemeIni.ReadString('PartyScoreDecoTextures', 'FirstTexture', '');
- PartyScore.DecoTextures.FirstTyp := ThemeIni.ReadString('PartyScoreDecoTextures', 'FirstTyp', 'Note Black');
- PartyScore.DecoTextures.FirstColor := ThemeIni.ReadString('PartyScoreDecoTextures', 'FirstColor', 'Black');
-
- PartyScore.DecoTextures.SecondTexture := ThemeIni.ReadString('PartyScoreDecoTextures', 'SecondTexture', '');
- PartyScore.DecoTextures.SecondTyp := ThemeIni.ReadString('PartyScoreDecoTextures', 'SecondTyp', 'Note Black');
- PartyScore.DecoTextures.SecondColor := ThemeIni.ReadString('PartyScoreDecoTextures', 'SecondColor', 'Black');
-
- PartyScore.DecoTextures.ThirdTexture := ThemeIni.ReadString('PartyScoreDecoTextures', 'ThirdTexture', '');
- PartyScore.DecoTextures.ThirdTyp := ThemeIni.ReadString('PartyScoreDecoTextures', 'ThirdTyp', 'Note Black');
- PartyScore.DecoTextures.ThirdColor := ThemeIni.ReadString('PartyScoreDecoTextures', 'ThirdColor', 'Black');
-
- 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.StaticTeam1BG, 'PartyWinStaticTeam1BG');
- ThemeLoadStatic (PartyWin.StaticTeam1Deco, 'PartyWinStaticTeam1Deco');
- ThemeLoadStatic (PartyWin.StaticTeam2, 'PartyWinStaticTeam2');
- ThemeLoadStatic (PartyWin.StaticTeam2BG, 'PartyWinStaticTeam2BG');
- ThemeLoadStatic (PartyWin.StaticTeam2Deco, 'PartyWinStaticTeam2Deco');
- ThemeLoadStatic (PartyWin.StaticTeam3, 'PartyWinStaticTeam3');
- ThemeLoadStatic (PartyWin.StaticTeam3BG, 'PartyWinStaticTeam3BG');
- ThemeLoadStatic (PartyWin.StaticTeam3Deco, 'PartyWinStaticTeam3Deco');
-
- 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');}
-
- ThemeLoadBasic(StatMain, 'StatMain');
-
- ThemeLoadButton(StatMain.ButtonScores, 'StatMainButtonScores');
- ThemeLoadButton(StatMain.ButtonSingers, 'StatMainButtonSingers');
- ThemeLoadButton(StatMain.ButtonSongs, 'StatMainButtonSongs');
- ThemeLoadButton(StatMain.ButtonBands, 'StatMainButtonBands');
- ThemeLoadButton(StatMain.ButtonExit, 'StatMainButtonExit');
-
- ThemeLoadText (StatMain.TextOverview, 'StatMainTextOverview');
-
-
- ThemeLoadBasic(StatDetail, 'StatDetail');
-
- ThemeLoadButton(StatDetail.ButtonNext, 'StatDetailButtonNext');
- ThemeLoadButton(StatDetail.ButtonPrev, 'StatDetailButtonPrev');
- ThemeLoadButton(StatDetail.ButtonReverse, 'StatDetailButtonReverse');
- ThemeLoadButton(StatDetail.ButtonExit, 'StatDetailButtonExit');
-
- ThemeLoadText (StatDetail.TextDescription, 'StatDetailTextDescription');
- ThemeLoadText (StatDetail.TextPage, 'StatDetailTextPage');
- ThemeLoadTexts(StatDetail.TextList, 'StatDetailTextList');
-
- //Translate Texts
- StatDetail.Description[0] := Language.Translate('STAT_DESC_SCORES');
- StatDetail.Description[1] := Language.Translate('STAT_DESC_SINGERS');
- StatDetail.Description[2] := Language.Translate('STAT_DESC_SONGS');
- StatDetail.Description[3] := Language.Translate('STAT_DESC_BANDS');
-
- StatDetail.DescriptionR[0] := Language.Translate('STAT_DESC_SCORES_REVERSED');
- StatDetail.DescriptionR[1] := Language.Translate('STAT_DESC_SINGERS_REVERSED');
- StatDetail.DescriptionR[2] := Language.Translate('STAT_DESC_SONGS_REVERSED');
- StatDetail.DescriptionR[3] := Language.Translate('STAT_DESC_BANDS_REVERSED');
-
- StatDetail.FormatStr[0] := Language.Translate('STAT_FORMAT_SCORES');
- StatDetail.FormatStr[1] := Language.Translate('STAT_FORMAT_SINGERS');
- StatDetail.FormatStr[2] := Language.Translate('STAT_FORMAT_SONGS');
- StatDetail.FormatStr[3] := Language.Translate('STAT_FORMAT_BANDS');
-
- StatDetail.PageStr := Language.Translate('STAT_PAGE');
-
- //Playlist Translations
- Playlist.CatText := Language.Translate('PLAYLIST_CATTEXT');
-
- //Level Translations
- //Fill ILevel
- ILevel[0] := Language.Translate('SING_EASY');
- ILevel[1] := Language.Translate('SING_MEDIUM');
- ILevel[2] := Language.Translate('SING_HARD');
- 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');
- ThemeLoadButtonCollections(Theme.ButtonCollection, Name + 'ButtonCollection');
-
- LastThemeBasic := Theme;
-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.W := ThemeIni.ReadInteger(Name, 'W', 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);
-
- ThemeText.Text := Language.Translate(ThemeIni.ReadString(Name, 'Text', ''));
- 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);
-
- //Reflection Mod
- ThemeStatic.Reflection := (ThemeIni.ReadInteger(Name, 'Reflection', 0) = 1);
- ThemeStatic.ReflectionSpacing := ThemeIni.ReadFloat(Name, 'ReflectionSpacing', 15);
-
- 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;
-
-//Button Collection Mod
-procedure TTheme.ThemeLoadButtonCollection(var Collection: TThemeButtonCollection; Name: string);
-var T: Integer;
-begin
- //Load Collection Style
- ThemeLoadButton(Collection.Style, Name);
-
- //Load Other Attributes
- T := ThemeIni.ReadInteger (Name, 'FirstChild', 0);
- if (T > 0) And (T < 256) then
- Collection.FirstChild := T
- else
- Collection.FirstChild := 0;
-end;
-
-procedure TTheme.ThemeLoadButtonCollections(var Collections: AThemeButtonCollection; Name: string);
-var
- I: integer;
-begin
- I := 1;
- while ThemeIni.SectionExists(Name + IntToStr(I)) do begin
- SetLength(Collections, I);
- ThemeLoadButtonCollection(Collections[I-1], Name + IntToStr(I));
- Inc(I);
- end;
-end;
-//End Button Collection Mod
-
-procedure TTheme.ThemeLoadButton(var ThemeButton: TThemeButton; Name: string; const Collections: PAThemeButtonCollection);
-var
- C: integer;
- TLen: integer;
- T: integer;
- Collections2: PAThemeButtonCollection;
-begin
- if not ThemeIni.SectionExists(Name) then
- begin
- ThemeButton.Visible := False;
- exit;
- end;
- DecimalSeparator := '.';
- ThemeButton.Tex := ThemeIni.ReadString(Name, 'Tex', '');
- ThemeButton.X := ThemeIni.ReadInteger (Name, 'X', 0);
- ThemeButton.Y := ThemeIni.ReadInteger (Name, 'Y', 0);
- ThemeButton.Z := ThemeIni.ReadFloat (Name, 'Z', 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.ReflectionSpacing := ThemeIni.ReadFloat(Name, 'ReflectionSpacing', 15);
-
- 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;
-
- ThemeButton.Visible := (ThemeIni.ReadInteger(Name, 'Visible', 1) = 1);
-
- //Fade Mod
- ThemeButton.SelectH := ThemeIni.ReadInteger (Name, 'SelectH', ThemeButton.H);
- ThemeButton.SelectW := ThemeIni.ReadInteger (Name, 'SelectW', ThemeButton.W);
-
- ThemeButton.DeSelectReflectionspacing := ThemeIni.ReadFloat(Name, 'DeSelectReflectionSpacing', ThemeButton.Reflectionspacing);
-
- ThemeButton.Fade := (ThemeIni.ReadInteger(Name, 'Fade', 0) = 1);
- ThemeButton.FadeText := (ThemeIni.ReadInteger(Name, 'FadeText', 0) = 1);
-
-
- ThemeButton.FadeTex := ThemeIni.ReadString(Name, 'FadeTex', '');
- ThemeButton.FadeTexPos:= ThemeIni.ReadInteger(Name, 'FadeTexPos', 0);
- if (ThemeButton.FadeTexPos > 4) Or (ThemeButton.FadeTexPos < 0) then
- ThemeButton.FadeTexPos := 0;
-
- //Button Collection Mod
- T := ThemeIni.ReadInteger(Name, 'Parent', 0);
-
- //Set Collections to Last Basic Collections if no valid Value
- if (Collections = nil) then
- Collections2 := @LastThemeBasic.ButtonCollection
- else
- Collections2 := Collections;
- //Test for valid Value
- if (Collections2 <> nil) AND (T > 0) AND (T <= Length(Collections2^)) then
- begin
- Inc(Collections2^[T-1].ChildCount);
- ThemeButton.Parent := T;
- end
- else
- ThemeButton.Parent := 0;
-
- //Read ButtonTexts
- 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.Z := ThemeIni.ReadFloat(Name, 'Z', 0);
-
- ThemeSelectS.TextSize := ThemeIni.ReadInteger(Name, 'TextSize', 10);
-
- ThemeSelectS.SkipX := ThemeIni.ReadInteger(Name, 'SkipX', 0);
-
- ThemeSelectS.SBGW := ThemeIni.ReadInteger(Name, 'SBGW', 450);
-
- 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;
-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');
-
- //TimeBar mod
- ThemeSaveStatic(Sing.StaticTimeProgress, 'SingTimeProgress');
- ThemeSaveText(Sing.TextTimeText, 'SingTimeText');
- //eoa TimeBar mod
-
- ThemeSaveStatic(Sing.StaticP1, 'SingP1Static');
- ThemeSaveText(Sing.TextP1, 'SingP1Text');
- ThemeSaveStatic(Sing.StaticP1ScoreBG, 'SingP1Static2');
- ThemeSaveText(Sing.TextP1Score, 'SingP1TextScore');
-
- //moveable singbar mod
- ThemeSaveStatic(Sing.StaticP1SingBar, 'SingP1SingBar');
- ThemeSaveStatic(Sing.StaticP1TwoPSingBar, 'SingP1TwoPSingBar');
- ThemeSaveStatic(Sing.StaticP1ThreePSingBar, 'SingP1ThreePSingBar');
- ThemeSaveStatic(Sing.StaticP2RSingBar, 'SingP2RSingBar');
- ThemeSaveStatic(Sing.StaticP2MSingBar, 'SingP2MSingBar');
- ThemeSaveStatic(Sing.StaticP3SingBar, 'SingP3SingBar');
- //eoa moveable singbar
-
- //Added for ps3 skin
- //This one is shown in 2/4P mode
- ThemeSaveStatic(Sing.StaticP1TwoP, 'SingP1TwoPStatic');
- ThemeSaveText(Sing.TextP1TwoP, 'SingP1TwoPText');
- ThemeSaveStatic(Sing.StaticP1TwoPScoreBG, 'SingP1TwoPStatic2');
- ThemeSaveText(Sing.TextP1TwoPScore, 'SingP1TwoPTextScore');
-
- //This one is shown in 3/6P mode
- ThemeSaveStatic(Sing.StaticP1ThreeP, 'SingP1ThreePStatic');
- ThemeSaveText(Sing.TextP1ThreeP, 'SingP1ThreePText');
- ThemeSaveStatic(Sing.StaticP1ThreePScoreBG, 'SingP1ThreePStatic2');
- ThemeSaveText(Sing.TextP1ThreePScore, 'SingP1ThreePTextScore');
- //eoa
-
- ThemeSaveStatic(Sing.StaticP2R, 'SingP2RStatic');
- ThemeSaveText(Sing.TextP2R, 'SingP2RText');
- ThemeSaveStatic(Sing.StaticP2RScoreBG, 'SingP2RStatic2');
- ThemeSaveText(Sing.TextP2RScore, 'SingP2RTextScore');
-
- ThemeSaveStatic(Sing.StaticP2M, 'SingP2MStatic');
- ThemeSaveText(Sing.TextP2M, 'SingP2MText');
- ThemeSaveStatic(Sing.StaticP2MScoreBG, 'SingP2MStatic2');
- ThemeSaveText(Sing.TextP2MScore, 'SingP2MTextScore');
-
- ThemeSaveStatic(Sing.StaticP3R, 'SingP3RStatic');
- ThemeSaveText(Sing.TextP3R, 'SingP3RText');
- ThemeSaveStatic(Sing.StaticP3RScoreBG, 'SingP3RStatic2');
- 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.
+unit UThemes; + +interface + +{$IFDEF FPC} + {$MODE DELPHI} +{$ENDIF} + +uses + ULog, + IniFiles, + SysUtils, + Classes; + +type + TRGB = record + R: single; + G: single; + B: single; + end; + + TRGBA = record + R, G, B, A: Double; + 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; + //Reflection Mod + Reflection: boolean; + Reflectionspacing: Real; + end; + AThemeStatic = array of TThemeStatic; + + TThemeText = record + X: integer; + Y: integer; + W: 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; + Z: Real; + 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; + + Visible: Boolean; + + //Reflection Mod + Reflection: boolean; + Reflectionspacing: Real; + //Fade Mod + SelectH: integer; + SelectW: integer; + Fade: boolean; + FadeText: boolean; + DeSelectReflectionspacing : Real; + FadeTex: string; + FadeTexPos: integer; + + //Button Collection Mod + Parent: Byte; //Number of the Button Collection this Button is assigned to. IF 0: No Assignement + end; + + //Button Collection Mod + TThemeButtonCollection = record + Style: TThemeButton; + ChildCount: Byte; //No of assigned Childs + FirstChild: Byte; //No of Child on whose Interaction Position the Button should be + end; + + AThemeButtonCollection = array of TThemeButtonCollection; + PAThemeButtonCollection = ^AThemeButtonCollection; + + 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; + Z: real; + + TextSize: integer; + + //SBGW Mod + SBGW: 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; + + PThemeBasic = ^TThemeBasic; + TThemeBasic = class + Background: TThemeBackground; + Text: AThemeText; + Static: AThemeStatic; + + //Button Collection Mod + ButtonCollection: AThemeButtonCollection; + end; + + TThemeLoading = class(TThemeBasic) + StaticAnimation: TThemeStatic; + TextLoading: TThemeText; + end; + + TThemeMain = class(TThemeBasic) + ButtonSolo: TThemeButton; + ButtonMulti: TThemeButton; + ButtonStat: TThemeButton; + ButtonEditor: TThemeButton; + ButtonOptions: TThemeButton; + ButtonExit: TThemeButton; + + TextDescription: TThemeText; + TextDescriptionLong: TThemeText; + Description: array[0..5] of string; + DescriptionLong: array[0..5] 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; + + //Video Icon Mod + VideoIcon: TThemeStatic; + + //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 and Non Party specific Statics and Texts + StaticParty: AThemeStatic; + TextParty: AThemeText; + + StaticNonParty: AThemeStatic; + TextNonParty: AThemeText; + + //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) + + //TimeBar mod + StaticTimeProgress: TThemeStatic; + TextTimeText : TThemeText; + //eoa TimeBar mod + + StaticP1: TThemeStatic; + TextP1: TThemeText; + StaticP1ScoreBG: TThemeStatic; //Static for ScoreBG + TextP1Score: TThemeText; + + //moveable singbar mod + StaticP1SingBar: TThemeStatic; + StaticP1ThreePSingBar: TThemeStatic; + StaticP1TwoPSingBar: TThemeStatic; + StaticP2RSingBar: TThemeStatic; + StaticP2MSingBar: TThemeStatic; + StaticP3SingBar: TThemeStatic; + //eoa moveable singbar + + //added for ps3 skin + //game in 2/4 player modi + StaticP1TwoP: TThemeStatic; + StaticP1TwoPScoreBG: TThemeStatic; //Static for ScoreBG + TextP1TwoP: TThemeText; + TextP1TwoPScore: TThemeText; + //game in 3/6 player modi + StaticP1ThreeP: TThemeStatic; + StaticP1ThreePScoreBG: TThemeStatic; //Static for ScoreBG + TextP1ThreeP: TThemeText; + TextP1ThreePScore: TThemeText; + //eoa + + 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; + + //Linebonus Translations + LineBonusText: Array [0..8] of String; + end; + + TThemeScore = class(TThemeBasic) + TextArtist: TThemeText; + TextTitle: TThemeText; + + TextArtistTitle: TThemeText; + + PlayerStatic: array[1..6] of AThemeStatic; + PlayerTexts: array[1..6] of AThemeText; + + 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; + ButtonAdvanced: TThemeButton; + ButtonExit: TThemeButton; + + TextDescription: TThemeText; + Description: array[0..7] 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; + //Song Preview + SelectSlidePreviewVolume: TThemeSelectSlide; + SelectSlidePreviewFading: TThemeSelectSlide; + 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; + + TThemeOptionsAdvanced = class(TThemeBasic) + SelectLoadAnimation: TThemeSelect; + SelectEffectSing: TThemeSelect; + SelectScreenFade: TThemeSelect; + SelectLineBonus: TThemeSelect; + SelectAskbeforeDel: TThemeSelect; + SelectOnSongClick: TThemeSelectSlide; + SelectPartyPopup: TThemeSelect; + ButtonExit: TThemeButton; + end; + + //Error- and Check-Popup + TThemeError = class(TThemeBasic) + Button1: TThemeButton; + TextError: TThemeText; + end; + + TThemeCheck = class(TThemeBasic) + Button1: TThemeButton; + Button2: TThemeButton; + TextCheck: TThemeText; + end; + + + //ScreenSong Menue + TThemeSongMenu = class(TThemeBasic) + Button1: TThemeButton; + Button2: TThemeButton; + Button3: TThemeButton; + Button4: TThemeButton; + + SelectSlide3: TThemeSelectSlide; + + TextMenu: TThemeText; + end; + + TThemeSongJumpTo = class(TThemeBasic) + ButtonSearchText: TThemeButton; + SelectSlideType: TThemeSelectSlide; + TextFound: TThemeText; + + //Translated Texts + Songsfound: String; + NoSongsfound: String; + CatText: String; + IType: array [0..2] of String; + 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; + TextTeam1Players: TThemeText; + TextTeam2Players: TThemeText; + TextTeam3Players: TThemeText; + + StaticTeam1: TThemeStatic; + StaticTeam2: TThemeStatic; + StaticTeam3: TThemeStatic; + StaticNextPlayer1: TThemeStatic; + StaticNextPlayer2: TThemeStatic; + StaticNextPlayer3: TThemeStatic; + end; + + TThemePartyScore = class(TThemeBasic) + TextScoreTeam1: TThemeText; + TextScoreTeam2: TThemeText; + TextScoreTeam3: TThemeText; + TextNameTeam1: TThemeText; + TextNameTeam2: TThemeText; + TextNameTeam3: TThemeText; + StaticTeam1: TThemeStatic; + StaticTeam1BG: TThemeStatic; + StaticTeam1Deco: TThemeStatic; + StaticTeam2: TThemeStatic; + StaticTeam2BG: TThemeStatic; + StaticTeam2Deco: TThemeStatic; + StaticTeam3: TThemeStatic; + StaticTeam3BG: TThemeStatic; + StaticTeam3Deco: TThemeStatic; + + DecoTextures: record + ChangeTextures: Boolean; + + FirstTexture: String; + FirstTyp: String; + FirstColor: String; + + SecondTexture: String; + SecondTyp: String; + SecondColor: String; + + ThirdTexture: String; + ThirdTyp: String; + ThirdColor: String; + end; + + + TextWinner: TThemeText; + end; + + TThemePartyWin = class(TThemeBasic) + TextScoreTeam1: TThemeText; + TextScoreTeam2: TThemeText; + TextScoreTeam3: TThemeText; + TextNameTeam1: TThemeText; + TextNameTeam2: TThemeText; + TextNameTeam3: TThemeText; + StaticTeam1: TThemeStatic; + StaticTeam1BG: TThemeStatic; + StaticTeam1Deco: TThemeStatic; + StaticTeam2: TThemeStatic; + StaticTeam2BG: TThemeStatic; + StaticTeam2Deco: TThemeStatic; + StaticTeam3: TThemeStatic; + StaticTeam3BG: TThemeStatic; + StaticTeam3Deco: 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; + + //Stats Screens + TThemeStatMain = class(TThemeBasic) + ButtonScores: TThemeButton; + ButtonSingers: TThemeButton; + ButtonSongs: TThemeButton; + ButtonBands: TThemeButton; + ButtonExit: TThemeButton; + + TextOverview: TThemeText; + end; + + TThemeStatDetail = class(TThemeBasic) + ButtonNext: TThemeButton; + ButtonPrev: TThemeButton; + ButtonReverse: TThemeButton; + ButtonExit: TThemeButton; + + TextDescription: TThemeText; + TextPage: TThemeText; + TextList: AThemeText; + + Description: array[0..3] of string; + DescriptionR: array[0..3] of string; + FormatStr: array[0..3] of string; + PageStr: String; + end; + + //Playlist Translations + TThemePlaylist = record + CatText: string; + end; + + TTheme = class + private + {$IFDEF THEMESAVE} + ThemeIni: TIniFile; + {$ELSE} + ThemeIni: TMemIniFile; + {$ENDIF} + + LastThemeBasic: TThemeBasic; + public + + 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; + OptionsAdvanced: TThemeOptionsAdvanced; + //error and check popup + ErrorPopup: TThemeError; + CheckPopup: TThemeCheck; + //ScreenSong extensions + SongMenu: TThemeSongMenu; + SongJumpto: TThemeSongJumpTo; + //Party Screens: + PartyNewRound: TThemePartyNewRound; + PartyScore: TThemePartyScore; + PartyWin: TThemePartyWin; + PartyOptions: TThemePartyOptions; + PartyPlayer: TThemePartyPlayer; + + //Stats Screens: + StatMain: TThemeStatMain; + StatDetail: TThemeStatDetail; + + Playlist: TThemePlaylist; + + ILevel: array[0..2] of String; + + 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; const Collections: PAThemeButtonCollection = nil); + procedure ThemeLoadButtonCollection(var Collection: TThemeButtonCollection; Name: string); + procedure ThemeLoadButtonCollections(var Collections: AThemeButtonCollection; 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 + UCommon, + ULanguage, + 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; + OptionsAdvanced := TThemeOptionsAdvanced.Create; + + ErrorPopup := TThemeError.Create; + CheckPopup := TThemeCheck.Create; + + SongMenu := TThemeSongMenu.Create; + SongJumpto := TThemeSongJumpto.Create; + //Party Screens + PartyNewRound := TThemePartyNewRound.Create; + PartyWin := TThemePartyWin.Create; + PartyScore := TThemePartyScore.Create; + PartyOptions := TThemePartyOptions.Create; + PartyPlayer := TThemePartyPlayer.Create; + + //Stats Screens: + StatMain := TThemeStatMain.Create; + StatDetail := TThemeStatDetail.Create; + + LoadTheme(FileName, Color); + +end; + + +function TTheme.LoadTheme(FileName: string; sColor: integer): boolean; +var + I: integer; + Path: string; +begin + Result := false; + + FileName := AdaptFilePaths( FileName ); + + if not FileExists(FileName) then + begin + {$ifndef win32} + writeln( 'ERROR !!! Theme does not exist ('+ FileName +')' ); + {$endif} + + Log.LogStatus( 'ERROR !!! Theme does not exist ('+ FileName +')' , 'TTheme.LoadTheme'); + end; + + 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'); + ThemeLoadText(Loading.TextLoading, 'LoadingTextLoading'); + ThemeLoadStatic(Loading.StaticAnimation, 'LoadingStaticAnimation'); + + // Main + ThemeLoadBasic(Main, 'Main'); + + ThemeLoadText(Main.TextDescription, 'MainTextDescription'); + ThemeLoadText(Main.TextDescriptionLong, 'MainTextDescriptionLong'); + ThemeLoadButton(Main.ButtonSolo, 'MainButtonSolo'); + ThemeLoadButton(Main.ButtonMulti, 'MainButtonMulti'); + ThemeLoadButton(Main.ButtonStat, 'MainButtonStats'); + ThemeLoadButton(Main.ButtonEditor, 'MainButtonEditor'); + ThemeLoadButton(Main.ButtonOptions, 'MainButtonOptions'); + ThemeLoadButton(Main.ButtonExit, 'MainButtonExit'); + + //Main Desc 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_MULTI'); + Main.DescriptionLong[1] := Language.Translate('SING_MULTI_DESC'); + Main.Description[2] := Language.Translate('SING_STATS'); + Main.DescriptionLong[2] := Language.Translate('SING_STATS_DESC'); + Main.Description[3] := Language.Translate('SING_EDITOR'); + Main.DescriptionLong[3] := Language.Translate('SING_EDITOR_DESC'); + Main.Description[4] := Language.Translate('SING_GAME_OPTIONS'); + Main.DescriptionLong[4] := Language.Translate('SING_GAME_OPTIONS_DESC'); + Main.Description[5] := Language.Translate('SING_EXIT'); + Main.DescriptionLong[5] := Language.Translate('SING_EXIT_DESC'); + //{$ENDIF} + + //Main Desc 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'); + + //Video Icon Mod + ThemeLoadStatic(Song.VideoIcon, 'SongVideoIcon'); + + //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', 300); + Song.Cover.Y := ThemeIni.ReadInteger('SongCover', 'Y', 190); + Song.Cover.W := ThemeIni.ReadInteger('SongCover', 'W', 300); + Song.Cover.H := ThemeIni.ReadInteger('SongCover', 'H', 200); + Song.Cover.Style := ThemeIni.ReadInteger('SongCover', 'Style', 4); + 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', 0); + Song.Equalizer.Y := ThemeIni.ReadInteger('SongEqualizer', 'Y', 0); + 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); + + //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 + else begin + Song.Equalizer.ColR := 0; + Song.Equalizer.ColG := 0; + Song.Equalizer.ColB := 0; + end; + //Load Equalizer Pos and Size from Theme Mod End + + //Party and Non Party specific Statics and Texts + ThemeLoadStatics (Song.StaticParty, 'SongStaticParty'); + ThemeLoadTexts (Song.TextParty, 'SongTextParty'); + + ThemeLoadStatics (Song.StaticNonParty, 'SongStaticNonParty'); + ThemeLoadTexts (Song.TextNonParty, 'SongTextNonParty'); + + //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'); + + + // Sing + ThemeLoadBasic(Sing, 'Sing'); + + //TimeBar mod + ThemeLoadStatic(Sing.StaticTimeProgress, 'SingTimeProgress'); + ThemeLoadText(Sing.TextTimeText, 'SingTimeText'); + //eoa TimeBar mod + + //moveable singbar mod + ThemeLoadStatic(Sing.StaticP1SingBar, 'SingP1SingBar'); + ThemeLoadStatic(Sing.StaticP1TwoPSingBar, 'SingP1TwoPSingBar'); + ThemeLoadStatic(Sing.StaticP1ThreePSingBar, 'SingP1ThreePSingBar'); + ThemeLoadStatic(Sing.StaticP2RSingBar, 'SingP2RSingBar'); + ThemeLoadStatic(Sing.StaticP2MSingBar, 'SingP2MSingBar'); + ThemeLoadStatic(Sing.StaticP3SingBar, 'SingP3SingBar'); + //eoa moveable singbar + + ThemeLoadStatic(Sing.StaticP1, 'SingP1Static'); + ThemeLoadText(Sing.TextP1, 'SingP1Text'); + ThemeLoadStatic(Sing.StaticP1ScoreBG, 'SingP1Static2'); + ThemeLoadText(Sing.TextP1Score, 'SingP1TextScore'); + //Added for ps3 skin + //This one is shown in 2/4P mode + //if it exists, otherwise the one Player equivaltents are used + if (ThemeIni.SectionExists('SingP1TwoPTextScore')) then + begin + ThemeLoadStatic(Sing.StaticP1TwoP, 'SingP1TwoPStatic'); + ThemeLoadText(Sing.TextP1TwoP, 'SingP1TwoPText'); + ThemeLoadStatic(Sing.StaticP1TwoPScoreBG, 'SingP1TwoPStatic2'); + ThemeLoadText(Sing.TextP1TwoPScore, 'SingP1TwoPTextScore'); + end + else + begin + Sing.StaticP1TwoP := Sing.StaticP1; + Sing.TextP1TwoP := Sing.TextP1; + Sing.StaticP1TwoPScoreBG := Sing.StaticP1ScoreBG; + Sing.TextP1TwoPScore := Sing.TextP1Score; + end; + + //This one is shown in 3/6P mode + //if it exists, otherwise the one Player equivaltents are used + if (ThemeIni.SectionExists('SingP1TwoPTextScore')) then + begin + ThemeLoadStatic(Sing.StaticP1ThreeP, 'SingP1ThreePStatic'); + ThemeLoadText(Sing.TextP1ThreeP, 'SingP1ThreePText'); + ThemeLoadStatic(Sing.StaticP1ThreePScoreBG, 'SingP1ThreePStatic2'); + ThemeLoadText(Sing.TextP1ThreePScore, 'SingP1ThreePTextScore'); + end + else + begin + Sing.StaticP1ThreeP := Sing.StaticP1; + Sing.TextP1ThreeP := Sing.TextP1; + Sing.StaticP1ThreePScoreBG := Sing.StaticP1ScoreBG; + Sing.TextP1ThreePScore := Sing.TextP1Score; + end; + //eoa + ThemeLoadStatic(Sing.StaticP2R, 'SingP2RStatic'); + ThemeLoadText(Sing.TextP2R, 'SingP2RText'); + ThemeLoadStatic(Sing.StaticP2RScoreBG, 'SingP2RStatic2'); + ThemeLoadText(Sing.TextP2RScore, 'SingP2RTextScore'); + + ThemeLoadStatic(Sing.StaticP2M, 'SingP2MStatic'); + ThemeLoadText(Sing.TextP2M, 'SingP2MText'); + ThemeLoadStatic(Sing.StaticP2MScoreBG, 'SingP2MStatic2'); + ThemeLoadText(Sing.TextP2MScore, 'SingP2MTextScore'); + + ThemeLoadStatic(Sing.StaticP3R, 'SingP3RStatic'); + ThemeLoadText(Sing.TextP3R, 'SingP3RText'); + ThemeLoadStatic(Sing.StaticP3RScoreBG, 'SingP3RStatic2'); + ThemeLoadText(Sing.TextP3RScore, 'SingP3RTextScore'); + + //Line Bonus Texts + Sing.LineBonusText[0] := Language.Translate('POPUP_AWFUL'); + Sing.LineBonusText[1] := Sing.LineBonusText[0]; + Sing.LineBonusText[2] := Language.Translate('POPUP_POOR'); + Sing.LineBonusText[3] := Language.Translate('POPUP_BAD'); + Sing.LineBonusText[4] := Language.Translate('POPUP_NOTBAD'); + Sing.LineBonusText[5] := Language.Translate('POPUP_GOOD'); + Sing.LineBonusText[6] := Language.Translate('POPUP_GREAT'); + Sing.LineBonusText[7] := Language.Translate('POPUP_AWESOME'); + Sing.LineBonusText[8] := Language.Translate('POPUP_PERFECT'); + + // Score + ThemeLoadBasic(Score, 'Score'); + + ThemeLoadText(Score.TextArtist, 'ScoreTextArtist'); + ThemeLoadText(Score.TextTitle, 'ScoreTextTitle'); + ThemeLoadText(Score.TextArtistTitle, 'ScoreTextArtistTitle'); + + for I := 1 to 6 do begin + ThemeLoadStatics(Score.PlayerStatic[I], 'ScorePlayer' + IntToStr(I) + 'Static'); + ThemeLoadTexts(Score.PlayerTexts[I], 'ScorePlayer' + IntToStr(I) + 'Text'); + + 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.ButtonAdvanced, 'OptionsButtonAdvanced'); + 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_ADVANCED'); + Options.Description[7] := 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'); + //Song Preview + ThemeLoadSelectSlide(OptionsSound.SelectSlidePreviewVolume, 'OptionsSoundSelectSlidePreviewVolume'); + ThemeLoadSelectSlide(OptionsSound.SelectSlidePreviewFading, 'OptionsSoundSelectSlidePreviewFading'); + + 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'); + + //Options Advanced + ThemeLoadBasic(OptionsAdvanced, 'OptionsAdvanced'); + + ThemeLoadSelect (OptionsAdvanced.SelectLoadAnimation, 'OptionsAdvancedSelectLoadAnimation'); + ThemeLoadSelect (OptionsAdvanced.SelectScreenFade, 'OptionsAdvancedSelectScreenFade'); + ThemeLoadSelect (OptionsAdvanced.SelectEffectSing, 'OptionsAdvancedSelectEffectSing'); + ThemeLoadSelect (OptionsAdvanced.SelectLineBonus, 'OptionsAdvancedSelectLineBonus'); + ThemeLoadSelectSlide (OptionsAdvanced.SelectOnSongClick, 'OptionsAdvancedSelectSlideOnSongClick'); + ThemeLoadSelect (OptionsAdvanced.SelectAskbeforeDel, 'OptionsAdvancedSelectAskbeforeDel'); + ThemeLoadSelect (OptionsAdvanced.SelectPartyPopup, 'OptionsAdvancedSelectPartyPopup'); + ThemeLoadButton (OptionsAdvanced.ButtonExit, 'OptionsAdvancedButtonExit'); + + //error and check popup + ThemeLoadBasic (ErrorPopup, 'ErrorPopup'); + ThemeLoadButton(ErrorPopup.Button1, 'ErrorPopupButton1'); + ThemeLoadText (ErrorPopup.TextError,'ErrorPopupText'); + ThemeLoadBasic (CheckPopup, 'CheckPopup'); + ThemeLoadButton(CheckPopup.Button1, 'CheckPopupButton1'); + ThemeLoadButton(CheckPopup.Button2, 'CheckPopupButton2'); + ThemeLoadText(CheckPopup.TextCheck , 'CheckPopupText'); + + //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'); + + //Song Jumpto + ThemeLoadBasic (SongJumpto, 'SongJumpto'); + ThemeLoadButton(SongJumpto.ButtonSearchText, 'SongJumptoButtonSearchText'); + ThemeLoadSelectSlide(SongJumpto.SelectSlideType, 'SongJumptoSelectSlideType'); + ThemeLoadText(SongJumpto.TextFound, 'SongJumptoTextFound'); + //Translations + SongJumpto.IType[0] := Language.Translate('SONG_JUMPTO_TYPE1'); + SongJumpto.IType[1] := Language.Translate('SONG_JUMPTO_TYPE2'); + SongJumpto.IType[2] := Language.Translate('SONG_JUMPTO_TYPE3'); + SongJumpto.SongsFound := Language.Translate('SONG_JUMPTO_SONGSFOUND'); + SongJumpto.NoSongsFound := Language.Translate('SONG_JUMPTO_NOSONGSFOUND'); + SongJumpto.CatText := Language.Translate('SONG_JUMPTO_CATTEXT'); + + //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'); + + ThemeLoadText (PartyNewRound.TextTeam1Players, 'PartyNewRoundTextTeam1Players'); + ThemeLoadText (PartyNewRound.TextTeam2Players, 'PartyNewRoundTextTeam2Players'); + ThemeLoadText (PartyNewRound.TextTeam3Players, 'PartyNewRoundTextTeam3Players'); + + ThemeLoadStatic (PartyNewRound.StaticTeam1, 'PartyNewRoundStaticTeam1'); + ThemeLoadStatic (PartyNewRound.StaticTeam2, 'PartyNewRoundStaticTeam2'); + ThemeLoadStatic (PartyNewRound.StaticTeam3, 'PartyNewRoundStaticTeam3'); + ThemeLoadStatic (PartyNewRound.StaticNextPlayer1, 'PartyNewRoundStaticNextPlayer1'); + ThemeLoadStatic (PartyNewRound.StaticNextPlayer2, 'PartyNewRoundStaticNextPlayer2'); + ThemeLoadStatic (PartyNewRound.StaticNextPlayer3, 'PartyNewRoundStaticNextPlayer3'); + + //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.StaticTeam1BG, 'PartyScoreStaticTeam1BG'); + ThemeLoadStatic (PartyScore.StaticTeam1Deco, 'PartyScoreStaticTeam1Deco'); + ThemeLoadStatic (PartyScore.StaticTeam2, 'PartyScoreStaticTeam2'); + ThemeLoadStatic (PartyScore.StaticTeam2BG, 'PartyScoreStaticTeam2BG'); + ThemeLoadStatic (PartyScore.StaticTeam2Deco, 'PartyScoreStaticTeam2Deco'); + ThemeLoadStatic (PartyScore.StaticTeam3, 'PartyScoreStaticTeam3'); + ThemeLoadStatic (PartyScore.StaticTeam3BG, 'PartyScoreStaticTeam3BG'); + ThemeLoadStatic (PartyScore.StaticTeam3Deco, 'PartyScoreStaticTeam3Deco'); + + //Load Party Score DecoTextures Object + PartyScore.DecoTextures.ChangeTextures := (ThemeIni.ReadInteger('PartyScoreDecoTextures', 'ChangeTextures', 0) = 1); + + PartyScore.DecoTextures.FirstTexture := ThemeIni.ReadString('PartyScoreDecoTextures', 'FirstTexture', ''); + PartyScore.DecoTextures.FirstTyp := ThemeIni.ReadString('PartyScoreDecoTextures', 'FirstTyp', 'Note Black'); + PartyScore.DecoTextures.FirstColor := ThemeIni.ReadString('PartyScoreDecoTextures', 'FirstColor', 'Black'); + + PartyScore.DecoTextures.SecondTexture := ThemeIni.ReadString('PartyScoreDecoTextures', 'SecondTexture', ''); + PartyScore.DecoTextures.SecondTyp := ThemeIni.ReadString('PartyScoreDecoTextures', 'SecondTyp', 'Note Black'); + PartyScore.DecoTextures.SecondColor := ThemeIni.ReadString('PartyScoreDecoTextures', 'SecondColor', 'Black'); + + PartyScore.DecoTextures.ThirdTexture := ThemeIni.ReadString('PartyScoreDecoTextures', 'ThirdTexture', ''); + PartyScore.DecoTextures.ThirdTyp := ThemeIni.ReadString('PartyScoreDecoTextures', 'ThirdTyp', 'Note Black'); + PartyScore.DecoTextures.ThirdColor := ThemeIni.ReadString('PartyScoreDecoTextures', 'ThirdColor', 'Black'); + + 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.StaticTeam1BG, 'PartyWinStaticTeam1BG'); + ThemeLoadStatic (PartyWin.StaticTeam1Deco, 'PartyWinStaticTeam1Deco'); + ThemeLoadStatic (PartyWin.StaticTeam2, 'PartyWinStaticTeam2'); + ThemeLoadStatic (PartyWin.StaticTeam2BG, 'PartyWinStaticTeam2BG'); + ThemeLoadStatic (PartyWin.StaticTeam2Deco, 'PartyWinStaticTeam2Deco'); + ThemeLoadStatic (PartyWin.StaticTeam3, 'PartyWinStaticTeam3'); + ThemeLoadStatic (PartyWin.StaticTeam3BG, 'PartyWinStaticTeam3BG'); + ThemeLoadStatic (PartyWin.StaticTeam3Deco, 'PartyWinStaticTeam3Deco'); + + 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');} + + ThemeLoadBasic(StatMain, 'StatMain'); + + ThemeLoadButton(StatMain.ButtonScores, 'StatMainButtonScores'); + ThemeLoadButton(StatMain.ButtonSingers, 'StatMainButtonSingers'); + ThemeLoadButton(StatMain.ButtonSongs, 'StatMainButtonSongs'); + ThemeLoadButton(StatMain.ButtonBands, 'StatMainButtonBands'); + ThemeLoadButton(StatMain.ButtonExit, 'StatMainButtonExit'); + + ThemeLoadText (StatMain.TextOverview, 'StatMainTextOverview'); + + + ThemeLoadBasic(StatDetail, 'StatDetail'); + + ThemeLoadButton(StatDetail.ButtonNext, 'StatDetailButtonNext'); + ThemeLoadButton(StatDetail.ButtonPrev, 'StatDetailButtonPrev'); + ThemeLoadButton(StatDetail.ButtonReverse, 'StatDetailButtonReverse'); + ThemeLoadButton(StatDetail.ButtonExit, 'StatDetailButtonExit'); + + ThemeLoadText (StatDetail.TextDescription, 'StatDetailTextDescription'); + ThemeLoadText (StatDetail.TextPage, 'StatDetailTextPage'); + ThemeLoadTexts(StatDetail.TextList, 'StatDetailTextList'); + + //Translate Texts + StatDetail.Description[0] := Language.Translate('STAT_DESC_SCORES'); + StatDetail.Description[1] := Language.Translate('STAT_DESC_SINGERS'); + StatDetail.Description[2] := Language.Translate('STAT_DESC_SONGS'); + StatDetail.Description[3] := Language.Translate('STAT_DESC_BANDS'); + + StatDetail.DescriptionR[0] := Language.Translate('STAT_DESC_SCORES_REVERSED'); + StatDetail.DescriptionR[1] := Language.Translate('STAT_DESC_SINGERS_REVERSED'); + StatDetail.DescriptionR[2] := Language.Translate('STAT_DESC_SONGS_REVERSED'); + StatDetail.DescriptionR[3] := Language.Translate('STAT_DESC_BANDS_REVERSED'); + + StatDetail.FormatStr[0] := Language.Translate('STAT_FORMAT_SCORES'); + StatDetail.FormatStr[1] := Language.Translate('STAT_FORMAT_SINGERS'); + StatDetail.FormatStr[2] := Language.Translate('STAT_FORMAT_SONGS'); + StatDetail.FormatStr[3] := Language.Translate('STAT_FORMAT_BANDS'); + + StatDetail.PageStr := Language.Translate('STAT_PAGE'); + + //Playlist Translations + Playlist.CatText := Language.Translate('PLAYLIST_CATTEXT'); + + //Level Translations + //Fill ILevel + ILevel[0] := Language.Translate('SING_EASY'); + ILevel[1] := Language.Translate('SING_MEDIUM'); + ILevel[2] := Language.Translate('SING_HARD'); + 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'); + ThemeLoadButtonCollections(Theme.ButtonCollection, Name + 'ButtonCollection'); + + LastThemeBasic := Theme; +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.W := ThemeIni.ReadInteger(Name, 'W', 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); + + ThemeText.Text := Language.Translate(ThemeIni.ReadString(Name, 'Text', '')); + 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); + + //Reflection Mod + ThemeStatic.Reflection := (ThemeIni.ReadInteger(Name, 'Reflection', 0) = 1); + ThemeStatic.ReflectionSpacing := ThemeIni.ReadFloat(Name, 'ReflectionSpacing', 15); + + 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; + +//Button Collection Mod +procedure TTheme.ThemeLoadButtonCollection(var Collection: TThemeButtonCollection; Name: string); +var T: Integer; +begin + //Load Collection Style + ThemeLoadButton(Collection.Style, Name); + + //Load Other Attributes + T := ThemeIni.ReadInteger (Name, 'FirstChild', 0); + if (T > 0) And (T < 256) then + Collection.FirstChild := T + else + Collection.FirstChild := 0; +end; + +procedure TTheme.ThemeLoadButtonCollections(var Collections: AThemeButtonCollection; Name: string); +var + I: integer; +begin + I := 1; + while ThemeIni.SectionExists(Name + IntToStr(I)) do begin + SetLength(Collections, I); + ThemeLoadButtonCollection(Collections[I-1], Name + IntToStr(I)); + Inc(I); + end; +end; +//End Button Collection Mod + +procedure TTheme.ThemeLoadButton(var ThemeButton: TThemeButton; Name: string; const Collections: PAThemeButtonCollection); +var + C: integer; + TLen: integer; + T: integer; + Collections2: PAThemeButtonCollection; +begin + if not ThemeIni.SectionExists(Name) then + begin + ThemeButton.Visible := False; + exit; + end; + DecimalSeparator := '.'; + ThemeButton.Tex := ThemeIni.ReadString(Name, 'Tex', ''); + ThemeButton.X := ThemeIni.ReadInteger (Name, 'X', 0); + ThemeButton.Y := ThemeIni.ReadInteger (Name, 'Y', 0); + ThemeButton.Z := ThemeIni.ReadFloat (Name, 'Z', 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.ReflectionSpacing := ThemeIni.ReadFloat(Name, 'ReflectionSpacing', 15); + + 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; + + ThemeButton.Visible := (ThemeIni.ReadInteger(Name, 'Visible', 1) = 1); + + //Fade Mod + ThemeButton.SelectH := ThemeIni.ReadInteger (Name, 'SelectH', ThemeButton.H); + ThemeButton.SelectW := ThemeIni.ReadInteger (Name, 'SelectW', ThemeButton.W); + + ThemeButton.DeSelectReflectionspacing := ThemeIni.ReadFloat(Name, 'DeSelectReflectionSpacing', ThemeButton.Reflectionspacing); + + ThemeButton.Fade := (ThemeIni.ReadInteger(Name, 'Fade', 0) = 1); + ThemeButton.FadeText := (ThemeIni.ReadInteger(Name, 'FadeText', 0) = 1); + + + ThemeButton.FadeTex := ThemeIni.ReadString(Name, 'FadeTex', ''); + ThemeButton.FadeTexPos:= ThemeIni.ReadInteger(Name, 'FadeTexPos', 0); + if (ThemeButton.FadeTexPos > 4) Or (ThemeButton.FadeTexPos < 0) then + ThemeButton.FadeTexPos := 0; + + //Button Collection Mod + T := ThemeIni.ReadInteger(Name, 'Parent', 0); + + //Set Collections to Last Basic Collections if no valid Value + if (Collections = nil) then + Collections2 := @LastThemeBasic.ButtonCollection + else + Collections2 := Collections; + //Test for valid Value + if (Collections2 <> nil) AND (T > 0) AND (T <= Length(Collections2^)) then + begin + Inc(Collections2^[T-1].ChildCount); + ThemeButton.Parent := T; + end + else + ThemeButton.Parent := 0; + + //Read ButtonTexts + 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.Z := ThemeIni.ReadFloat(Name, 'Z', 0); + + ThemeSelectS.TextSize := ThemeIni.ReadInteger(Name, 'TextSize', 10); + + ThemeSelectS.SkipX := ThemeIni.ReadInteger(Name, 'SkipX', 0); + + ThemeSelectS.SBGW := ThemeIni.ReadInteger(Name, 'SBGW', 450); + + 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; +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'); + + //TimeBar mod + ThemeSaveStatic(Sing.StaticTimeProgress, 'SingTimeProgress'); + ThemeSaveText(Sing.TextTimeText, 'SingTimeText'); + //eoa TimeBar mod + + ThemeSaveStatic(Sing.StaticP1, 'SingP1Static'); + ThemeSaveText(Sing.TextP1, 'SingP1Text'); + ThemeSaveStatic(Sing.StaticP1ScoreBG, 'SingP1Static2'); + ThemeSaveText(Sing.TextP1Score, 'SingP1TextScore'); + + //moveable singbar mod + ThemeSaveStatic(Sing.StaticP1SingBar, 'SingP1SingBar'); + ThemeSaveStatic(Sing.StaticP1TwoPSingBar, 'SingP1TwoPSingBar'); + ThemeSaveStatic(Sing.StaticP1ThreePSingBar, 'SingP1ThreePSingBar'); + ThemeSaveStatic(Sing.StaticP2RSingBar, 'SingP2RSingBar'); + ThemeSaveStatic(Sing.StaticP2MSingBar, 'SingP2MSingBar'); + ThemeSaveStatic(Sing.StaticP3SingBar, 'SingP3SingBar'); + //eoa moveable singbar + + //Added for ps3 skin + //This one is shown in 2/4P mode + ThemeSaveStatic(Sing.StaticP1TwoP, 'SingP1TwoPStatic'); + ThemeSaveText(Sing.TextP1TwoP, 'SingP1TwoPText'); + ThemeSaveStatic(Sing.StaticP1TwoPScoreBG, 'SingP1TwoPStatic2'); + ThemeSaveText(Sing.TextP1TwoPScore, 'SingP1TwoPTextScore'); + + //This one is shown in 3/6P mode + ThemeSaveStatic(Sing.StaticP1ThreeP, 'SingP1ThreePStatic'); + ThemeSaveText(Sing.TextP1ThreeP, 'SingP1ThreePText'); + ThemeSaveStatic(Sing.StaticP1ThreePScoreBG, 'SingP1ThreePStatic2'); + ThemeSaveText(Sing.TextP1ThreePScore, 'SingP1ThreePTextScore'); + //eoa + + ThemeSaveStatic(Sing.StaticP2R, 'SingP2RStatic'); + ThemeSaveText(Sing.TextP2R, 'SingP2RText'); + ThemeSaveStatic(Sing.StaticP2RScoreBG, 'SingP2RStatic2'); + ThemeSaveText(Sing.TextP2RScore, 'SingP2RTextScore'); + + ThemeSaveStatic(Sing.StaticP2M, 'SingP2MStatic'); + ThemeSaveText(Sing.TextP2M, 'SingP2MText'); + ThemeSaveStatic(Sing.StaticP2MScoreBG, 'SingP2MStatic2'); + ThemeSaveText(Sing.TextP2MScore, 'SingP2MTextScore'); + + ThemeSaveStatic(Sing.StaticP3R, 'SingP3RStatic'); + ThemeSaveText(Sing.TextP3R, 'SingP3RText'); + ThemeSaveStatic(Sing.StaticP3RScoreBG, 'SingP3RStatic2'); + 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.pas b/Game/Code/Classes/UTime.pas index 87d4f922..d06628cc 100644 --- a/Game/Code/Classes/UTime.pas +++ b/Game/Code/Classes/UTime.pas @@ -69,7 +69,11 @@ begin TimeNew := CurrentSec100OfDay(); // TODO - JB_Linux will prob need looking at {$ENDIF} - TimeSkip := (TimeNew-TimeOld)/TimeFreq; + if ( TimeNew-TimeOld > 0 ) AND + ( TimeFreq > 0 ) THEN + begin + TimeSkip := (TimeNew-TimeOld)/TimeFreq; + end; end; procedure CountMidTime; diff --git a/Game/Code/Menu/UDisplay.pas b/Game/Code/Menu/UDisplay.pas index 077342d3..c83d3c37 100644 --- a/Game/Code/Menu/UDisplay.pas +++ b/Game/Code/Menu/UDisplay.pas @@ -19,45 +19,41 @@ uses {$IFDEF win32} type TDisplay = class - ActualScreen: PMenu; - NextScreen: PMenu; + ActualScreen : PMenu; + NextScreen : PMenu; //fade-to-black-hack BlackScreen: Boolean; + //popup hack NextScreenWithCheck: Pmenu; - CheckOK: Boolean; + CheckOK : Boolean; - h_DC: HDC; - h_RC: HGLRC; + h_DC : HDC; + h_RC : HGLRC; - Fade: Real; - // fade-mod - doFade: Boolean; - canFade: Boolean; - myFade: integer; - lastTime: Cardinal; + Fade : Real; + doFade : Boolean; + canFade : Boolean; + myFade : integer; + lastTime : Cardinal; pTexData : Pointer; - pTex : array[1..2] of glUInt; - // end + pTex : array[1..2] of glUInt; - //FPS Counter - FPSCounter: Cardinal; - LastFPS: Cardinal; - NextFPSSwap:Cardinal; + FPSCounter : Cardinal; + LastFPS : Cardinal; + NextFPSSwap : Cardinal; - //For Debug OSD - OSD_LastError: String; + OSD_LastError : String; + public + constructor Create; + destructor Destroy; override; - function Draw: Boolean; procedure PrintScreen; - constructor Create; - // fade mod - destructor Destroy; override; - // end procedure ScreenShot; - procedure DrawDebugInformation; + + function Draw: Boolean; end; var @@ -76,7 +72,7 @@ uses {$ENDIF} graphics, TextGL, - // UFiles, +// ULog, UMain, UTexture, UIni, @@ -85,15 +81,17 @@ uses UCommandLine; constructor TDisplay.Create; -var i: integer; +var + i: integer; + begin inherited Create; //popup hack - CheckOK:=False; - NextScreen:=NIL; - NextScreenWithCheck:=NIL; - BlackScreen:=False; + CheckOK := False; + NextScreen := NIL; + NextScreenWithCheck := NIL; + BlackScreen := False; // fade mod myfade:=0; @@ -106,24 +104,37 @@ begin canFade:=True; // generate texture for fading between screens GetMem(pTexData, 512*512*4); + if pTexData <> NIL then for i:= 1 to 2 do begin - glGenTextures(1, pTex[i]); - if glGetError <> GL_NO_ERROR then canFade := False; + + glGenTextures(1, @pTex[i] ); + + if glGetError <> GL_NO_ERROR then + canFade := False; + glBindTexture(GL_TEXTURE_2D, pTex[i]); - if glGetError <> GL_NO_ERROR then canFade := False; + if glGetError <> GL_NO_ERROR then + canFade := False; + glTexImage2D(GL_TEXTURE_2D, 0, 4, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, pTexData); - if glGetError <> GL_NO_ERROR then canFade := False; + if glGetError <> GL_NO_ERROR then + canFade := False; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - if glGetError <> GL_NO_ERROR then canFade := False; + if glGetError <> GL_NO_ERROR then + canFade := False; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - if glGetError <> GL_NO_ERROR then canFade := False; + if glGetError <> GL_NO_ERROR then + canFade := False; end else begin canFade:=False; end; + FreeMem(pTexData); // end @@ -131,25 +142,22 @@ begin OSD_LastError := 'No Errors'; end; -// fade mod destructor TDisplay.Destroy; begin if canFade then glDeleteTextures(1,@pTex); + inherited Destroy; end; -// end function TDisplay.Draw: Boolean; var S: integer; Col: Real; - // fade mod myFade2: Real; currentTime: Cardinal; glError: glEnum; glErrorStr: String; - // end begin Result := True; diff --git a/Game/Code/Menu/UMenu.pas b/Game/Code/Menu/UMenu.pas index 291dc201..2efae5e4 100644 --- a/Game/Code/Menu/UMenu.pas +++ b/Game/Code/Menu/UMenu.pas @@ -1,1529 +1,1544 @@ -unit UMenu;
-
-interface
-
-{$IFDEF FPC}
- {$MODE Delphi}
-{$ENDIF}
-
-uses OpenGL12, SysUtils, UTexture, UMenuStatic, UMenuText, UMenuButton, UMenuSelect, UMenuSelectSlide,
- UMenuInteract, UThemes, UMenuButtonCollection, Math;
-
-type
-{ Int16 = SmallInt;}
-
- PMenu = ^TMenu;
- TMenu = class
- protected
- ButtonPos: Integer;
-
- Interactions: array of TInteract;
- SelInteraction: integer;
- Button: array of TButton;
- Selects: array of TSelect;
- SelectsS: array of TSelectSlide;
- ButtonCollection: Array of TButtonCollection;
- BackImg: TTexture;
- BackW: integer;
- BackH: integer;
- public
- Text: array of TText;
- Static: array of TStatic;
- 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;
-
- //Procedure Load BG, Texts, Statics and Button Collections from ThemeBasic
- procedure LoadFromTheme(const ThemeBasic: TThemeBasic);
-
- procedure PrepareButtonCollections(const Collections: AThemeButtonCollection);
- procedure AddButtonCollection(const ThemeCollection: TThemeButtonCollection; Const Num: Byte);
-
- // 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; Reflection: Boolean; ReflectionSpacing: Real): 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, W: real; Style: integer; Size, ColR, ColG, ColB: real; Align: integer; Tekst: string): integer; overload;
-
- // button
- Procedure SetButtonLength(Length: Cardinal); //Function that Set Length of Button Array in one Step instead of register new Memory for every 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; ReflectionSpacing, DeSelectReflectionSpacing: Real): 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;
- procedure AddButtonText(CustomButton: TButton; 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, SBGW, 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);
- //popup hack
- procedure CheckFadeTo(Screen: PMenu; msg: String);
-
- 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;
-
- function IsSelectable(Int: Cardinal): Boolean;
-
- 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;
- iBCollectionChild = 5;
-
-// 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;
-
- //Set ButtonPos to Autoset Length
- ButtonPos := -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;
-
- //Set ButtonPos to Autoset Length
- ButtonPos := -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;
-
- NewNum := Interactions[Num].Num;
- NewTyp := Interactions[Num].Typ;
-
- case OldTyp of
- iButton: Button[OldNum].Selected := False;
- iSelect: Selects[OldNum].Selected := False;
- iText: Text[OldNum].Selected := False;
- iSelectS: SelectsS[OldNum].Selected := False;
- //Button Collection Mod
- iBCollectionChild:
- begin
- Button[OldNum].Selected := False;
-
- //Deselect Collection if Next Button is Not from Collection
- if (NewTyp <> iButton) Or (Button[NewNum].Parent <> Button[OldNum].Parent) then
- ButtonCollection[Button[OldNum].Parent-1].Selected := False;
- end;
- end;
-
- // set active
- SelInteraction := Num;
- case NewTyp of
- iButton: Button[NewNum].Selected := True;
- iSelect: Selects[NewNum].Selected := True;
- iText: Text[NewNum].Selected := True;
- iSelectS: SelectsS[NewNum].Selected := True;
-
- //Button Collection Mod
- iBCollectionChild:
- begin
- Button[NewNum].Selected := True;
- ButtonCollection[Button[NewNum].Parent-1].Selected := True;
- end;
- end;
-end;
-
-//----------------------
-//LoadFromTheme - Load BG, Texts, Statics and
-//Button Collections from ThemeBasic
-//----------------------
-procedure TMenu.LoadFromTheme(const ThemeBasic: TThemeBasic);
-var
- I: Integer;
-begin
- //Add Button Collections (Set Button CollectionsLength)
- //Button Collections are Created when the first ChildButton is Created
- PrepareButtonCollections(ThemeBasic.ButtonCollection);
-
-
- //Add Background
- AddBackground(ThemeBasic.Background.Tex);
-
- //Add Statics and Texts
- for I := 0 to High(ThemeBasic.Static) do
- AddStatic(ThemeBasic.Static[I]);
-
- for I := 0 to High(ThemeBasic.Text) do
- AddText(ThemeBasic.Text[I]);
-end;
-
-procedure TMenu.AddBackground(Name: string);
-var
- lFileName : string;
-begin
- if Name <> '' then
- begin
-// BackImg := Texture.LoadTexture(false, PChar(Skin.SkinPath + FileName), 'JPG', 'Plain', 0); // new theme system
- lFileName := Skin.GetTextureFileName(Name);
-
- if lFileName <> '' then
- begin
- BackImg := Texture.GetTexture( lFileName , 'Plain');
-
- BackImg.W := 800;
- BackImg.H := 600;
- BackW := 1;
- BackH := 1;
- end;
- end;
-end;
-
-//----------------------
-//PrepareButtonCollections:
-//Add Button Collections (Set Button CollectionsLength)
-//----------------------
-procedure TMenu.PrepareButtonCollections(const Collections: AThemeButtonCollection);
-var
- I: Integer;
-begin
- SetLength(ButtonCollection, Length(Collections));
- For I := 0 to High(ButtonCollection) do
- AddButtonCollection(Collections[I], I);
-end;
-
-//----------------------
-//AddButtonCollection:
-//Create a Button Collection;
-//----------------------
-procedure TMenu.AddButtonCollection(const ThemeCollection: TThemeButtonCollection; Const Num: Byte);
-var
- BT, BTLen: Integer;
- TempR, TempG, TempB, TempR2, TempG2, TempB2: Cardinal;
-
-begin
- if (Num > High(ButtonCollection)) then
- exit;
-
-// colorize hack
-if ThemeCollection.Style.Typ='Colorized' then
-begin
- TempR:=floor(255*ThemeCollection.Style.ColR);
- TempG:=floor(255*ThemeCollection.Style.ColG);
- TempB:=floor(255*ThemeCollection.Style.ColB);
- TempR2:=floor(255*ThemeCollection.Style.DColR);
- TempG2:=floor(255*ThemeCollection.Style.DColG);
- TempB2:=floor(255*ThemeCollection.Style.DColB);
- // give encoded color to loadtexture
- ButtonCollection[Num] := TButtonCollection.Create(Texture.LoadTexture(PChar(Skin.GetTextureFileName(ThemeCollection.Style.Tex)), 'JPG', 'Colorized', ((((TempR shl 8) or TempG) shl 8)or TempB)),
- Texture.LoadTexture(PChar(Skin.GetTextureFileName(ThemeCollection.Style.Tex)), 'JPG', 'Colorized', ((((TempR2 shl 8) or TempG2) shl 8)or TempB2)));
-
-// Button[Result] := TButton.Create(Texture.LoadTexture(PChar(Name), PChar(Format), PChar(Typ), ((((TempR2 shl 8) or TempG2) shl 8)or TempB2))); // use cache texture
-end
-else
- ButtonCollection[Num] := TButtonCollection.Create(Texture.GetTexture(Skin.GetTextureFileName(ThemeCollection.Style.Tex), ThemeCollection.Style.Typ, true)); // use cache texture
-
- //Set Parent menu
- ButtonCollection[Num].ScreenButton := @Self.Button;
-
- //Set Attributes
- ButtonCollection[Num].FirstChild := ThemeCollection.FirstChild;
- ButtonCollection[Num].CountChilds := ThemeCollection.ChildCount;
- ButtonCollection[Num].Parent := Num + 1;
-
- //Set Style
- ButtonCollection[Num].X := ThemeCollection.Style.X;
- ButtonCollection[Num].Y := ThemeCollection.Style.Y;
- ButtonCollection[Num].W := ThemeCollection.Style.W;
- ButtonCollection[Num].H := ThemeCollection.Style.H;
- if ThemeCollection.Style.Typ <> 'Colorized' then begin
- ButtonCollection[Num].SelectColR := ThemeCollection.Style.ColR;
- ButtonCollection[Num].SelectColG := ThemeCollection.Style.ColG;
- ButtonCollection[Num].SelectColB := ThemeCollection.Style.ColB;
- ButtonCollection[Num].DeselectColR := ThemeCollection.Style.DColR;
- ButtonCollection[Num].DeselectColG := ThemeCollection.Style.DColG;
- ButtonCollection[Num].DeselectColB := ThemeCollection.Style.DColB;
- end;
- ButtonCollection[Num].SelectInt := ThemeCollection.Style.Int;
- ButtonCollection[Num].DeselectInt := ThemeCollection.Style.DInt;
- ButtonCollection[Num].Texture.TexX1 := 0;
- ButtonCollection[Num].Texture.TexY1 := 0;
- ButtonCollection[Num].Texture.TexX2 := 1;
- ButtonCollection[Num].Texture.TexY2 := 1;
- ButtonCollection[Num].SetSelect(false);
-
- ButtonCollection[Num].Reflection := ThemeCollection.Style.Reflection;
- ButtonCollection[Num].Reflectionspacing := ThemeCollection.Style.ReflectionSpacing;
- ButtonCollection[Num].DeSelectReflectionspacing := ThemeCollection.Style.DeSelectReflectionSpacing;
-
- ButtonCollection[Num].Z := ThemeCollection.Style.Z;
-
- //Some Things from ButtonFading
- ButtonCollection[Num].SelectH := ThemeCollection.Style.SelectH;
- ButtonCollection[Num].SelectW := ThemeCollection.Style.SelectW;
-
- ButtonCollection[Num].Fade := ThemeCollection.Style.Fade;
- ButtonCollection[Num].FadeText := ThemeCollection.Style.FadeText;
- if ThemeCollection.Style.Typ='Colorized' then
- ButtonCollection[Num].FadeTex := Texture.LoadTexture(PChar(Skin.GetTextureFileName(ThemeCollection.Style.FadeTex)), 'JPG', 'Colorized', ((((TempR shl 8) or TempG) shl 8)or TempB))
- else
- ButtonCollection[Num].FadeTex := Texture.GetTexture(Skin.GetTextureFileName(ThemeCollection.Style.FadeTex), ThemeCollection.Style.Typ, true);
- ButtonCollection[Num].FadeTexPos := ThemeCollection.Style.FadeTexPos;
-
-
- BTLen := Length(ThemeCollection.Style.Text);
- for BT := 0 to BTLen-1 do begin
- AddButtonText(ButtonCollection[Num], ThemeCollection.Style.Text[BT].X, ThemeCollection.Style.Text[BT].Y,
- ThemeCollection.Style.Text[BT].ColR, ThemeCollection.Style.Text[BT].ColG, ThemeCollection.Style.Text[BT].ColB,
- ThemeCollection.Style.Text[BT].Font, ThemeCollection.Style.Text[BT].Size, ThemeCollection.Style.Text[BT].Align,
- ThemeCollection.Style.Text[BT].Text);
- 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, ThemeStatic.Reflection, ThemeStatic.Reflectionspacing);
- //'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, False, 0);
-//
-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; Reflection: Boolean; ReflectionSpacing: Real): integer;
-var
- StatNum: integer;
- TempR, TempG, TempB: Cardinal;
- TempCol: Cardinal;
-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
-
-// colorize hack
-if Typ='Colorized' then
-begin
- TempR:=floor(255*ColR);
- TempG:=floor(255*ColG);
- TempB:=floor(255*ColB);
- // give encoded color to loadtexture
- Static[StatNum] := TStatic.Create(Texture.LoadTexture(PChar(Name), PChar(Format), PChar(Typ), ((((TempR shl 8) or TempG) shl 8)or TempB)));
-end
-else
- 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;
- if Typ <> 'Colorized' then begin
- Static[StatNum].Texture.ColR := ColR;
- Static[StatNum].Texture.ColG := ColG;
- Static[StatNum].Texture.ColB := ColB;
- end;
- 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;
-
- //ReflectionMod
- Static[StatNum].Reflection := Reflection;
- Static[StatNum].ReflectionSpacing := ReflectionSpacing;
-
- Result := StatNum;
-end;
-
-function TMenu.AddText(ThemeText: TThemeText): integer;
-begin
- Result := AddText(ThemeText.X, ThemeText.Y, ThemeText.W, 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, 0, Style, Size, ColR, ColG, ColB, 0, Tekst);
-end;
-
-function TMenu.AddText(X, Y, W: 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, W, Style, Size, ColR, ColG, ColB, Align, Tekst);
- Result := TextNum;
-end;
-
-//Function that Set Length of Button Array in one Step instead of register new Memory for every Button
-Procedure TMenu.SetButtonLength(Length: Cardinal);
-begin
- if (ButtonPos = -1) AND (Length > 0) then
- begin
- //Set Length of Button
- SetLength(Button, Length);
-
- //Set ButtonPos to start with 0
- ButtonPos := 0;
- end;
-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;
- TempR, TempG, TempB, TempR2, TempG2, TempB2: Cardinal;
-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, ThemeButton.Reflectionspacing, ThemeButton.DeSelectReflectionspacing);
-
- Button[Result].Z := ThemeButton.Z;
-
- //Button Visibility
- Button[Result].Visible := ThemeButton.Visible;
-
- //Some Things from ButtonFading
- Button[Result].SelectH := ThemeButton.SelectH;
- Button[Result].SelectW := ThemeButton.SelectW;
-
- Button[Result].Fade := ThemeButton.Fade;
- Button[Result].FadeText := ThemeButton.FadeText;
- if ThemeButton.Typ='Colorized' then begin
- TempR:=floor(255*ThemeButton.ColR);
- TempG:=floor(255*ThemeButton.ColG);
- TempB:=floor(255*ThemeButton.ColB);
- Button[Result].FadeTex := Texture.LoadTexture(PChar(Skin.GetTextureFileName(ThemeButton.FadeTex)), 'JPG', 'Colorized', ((((TempR shl 8) or TempG) shl 8)or TempB));
- end
- else
- Button[Result].FadeTex := Texture.GetTexture(Skin.GetTextureFileName(ThemeButton.FadeTex), ThemeButton.Typ, true);
- Button[Result].FadeTexPos := ThemeButton.FadeTexPos;
-
-
- 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;
-
- //BAutton Collection Mod
- if (ThemeButton.Parent <> 0) then
- begin
- //If Collection Exists then Change Interaction to Child Button
- if (@ButtonCollection[ThemeButton.Parent-1] <> nil) then
- begin
- Interactions[High(Interactions)].Typ := iBCollectionChild;
- Button[Result].Visible := False;
-
- for BT := 0 to BTLen-1 do
- Button[Result].Text[BT].Alpha := 0;
-
- Button[Result].Parent := ThemeButton.Parent;
- if (ButtonCollection[ThemeButton.Parent-1].Fade) then
- Button[Result].Texture.Alpha := 0;
- end;
- 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, 15, 15);
-end;
-
-function TMenu.AddButton(X, Y, W, H, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt: real; Name, Format, Typ: String; Reflection: Boolean; ReflectionSpacing, DeSelectReflectionSpacing: Real): integer;
-var TempR, TempG, TempB, TempR2, TempG2, TempB2: Cardinal;
-begin
- // adds button
- //SetLength is used once to reduce Memory usement
- if (ButtonPos <> -1) then
- begin
- Result := ButtonPos;
- Inc(ButtonPos)
- end
- else //Old Method -> Reserve new Memory for every Button
- begin
- Result := Length(Button);
- SetLength(Button, Result + 1);
- end;
-// Button[Result] := 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
-// colorize hack
-if Typ='Colorized' then
-begin
- TempR:=floor(255*ColR);
- TempG:=floor(255*ColG);
- TempB:=floor(255*ColB);
- TempR2:=floor(255*DColR);
- TempG2:=floor(255*DColG);
- TempB2:=floor(255*DColB);
- // give encoded color to loadtexture
- Button[Result] := TButton.Create(Texture.LoadTexture(PChar(Name), PChar(Format), PChar(Typ), ((((TempR shl 8) or TempG) shl 8)or TempB)),
- Texture.LoadTexture(PChar(Name), PChar(Format), PChar(Typ), ((((TempR2 shl 8) or TempG2) shl 8)or TempB2)));
-
-// Button[Result] := TButton.Create(Texture.LoadTexture(PChar(Name), PChar(Format), PChar(Typ), ((((TempR2 shl 8) or TempG2) shl 8)or TempB2))); // use cache texture
-end
-else
-
- Button[Result] := TButton.Create(Texture.GetTexture(Name, Typ, true)); // use cache texture
-// else
-// Button[Result] := TButton.Create(Texture.GetTexture(Name, Typ, false)); // don't use cache texture}
-
- // configures button
- Button[Result].X := X;
- Button[Result].Y := Y;
- Button[Result].W := W;
- Button[Result].H := H;
- if Typ <> 'Colorized' then begin
- Button[Result].SelectColR := ColR;
- Button[Result].SelectColG := ColG;
- Button[Result].SelectColB := ColB;
- Button[Result].DeselectColR := DColR;
- Button[Result].DeselectColG := DColG;
- Button[Result].DeselectColB := DColB;
- end;
- Button[Result].SelectInt := Int;
- Button[Result].DeselectInt := DInt;
- Button[Result].Texture.TexX1 := 0;
- Button[Result].Texture.TexY1 := 0;
- Button[Result].Texture.TexX2 := 1;
- Button[Result].Texture.TexY2 := 1;
- Button[Result].SetSelect(false);
-
- Button[Result].Reflection := Reflection;
- Button[Result].Reflectionspacing := ReflectionSpacing;
- Button[Result].DeSelectReflectionspacing := DeSelectReflectionSpacing;
-
- //Button Collection Mod
- Button[Result].Parent := 0;
-
-
- // adds interaction
- AddInteraction(iButton, Result);
- 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
- 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
- // does anyone know what these loops were for?
-{ // 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}
- BackImg.X:=BackW;
- BackImg.Y:=BackW;
- DrawTexture(BackImg);
- 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;
-
-
- // Draw all ButtonCollections
- For J := 0 to High(ButtonCollection) do
- ButtonCollection[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;}
-
-function TMenu.IsSelectable(Int: Cardinal): Boolean;
-begin
- Result := True;
- Case Interactions[Int].Typ of
- //Button
- iButton: Result := Button[Interactions[Int].Num].Visible and Button[Interactions[Int].Num].Selectable;
- //Select
- iSelect: Result := True;
- //Select Slide
- iSelectS: Result := SelectsS[Interactions[Int].Num].Visible;
-
- //ButtonCollection Child
- iBCollectionChild:
- Result := (ButtonCollection[Button[Interactions[Int].Num].Parent - 1].FirstChild - 1 = Int) AND ((Interactions[Interaction].Typ <> iBCollectionChild) OR (Button[Interactions[Interaction].Num].Parent <> Button[Interactions[Int].Num].Parent));
- end;
-end;
-
-procedure TMenu.InteractNext;
-var
- Int: Integer;
-begin
- Int := Interaction;
-
- // change interaction as long as it's needed
- repeat
- Int := (Int + 1) Mod Length(Interactions);
-
- //If no Interaction is Selectable Simply Select Next
- if (Int = Interaction) then
- begin
- Int := (Int + 1) Mod Length(Interactions);
- Break;
- end;
- Until IsSelectable(Int);
-
- //Set Interaction
- Interaction := Int;
-end;
-
-
-procedure TMenu.InteractPrev;
-var
- Int: Integer;
-begin
- Int := Interaction;
-
- // change interaction as long as it's needed
- repeat
- Int := Int - 1;
- if Int = -1 then Int := High(Interactions);
-
- //If no Interaction is Selectable Simply Select Next
- if (Int = Interaction) then
- begin
- Int := SelInteraction - 1;
- if Int = -1 then Int := High(Interactions);
- Break;
- end;
- Until IsSelectable(Int);
-
- //Set Interaction
- Interaction := Int
-end;
-
-
-procedure TMenu.InteractCustom(CustomSwitch: integer);
-var
- Num: integer;
- Typ: integer;
- Again: boolean;
-begin
- //Code Commented atm, because it needs to be Rewritten
- //it doesn't work with Button Collections
- {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;
-
-//popup hack
-procedure TMenu.CheckFadeTo(Screen: PMenu; msg: String);
-begin
- Display.Fade := 0;
- Display.NextScreenWithCheck := Screen;
- Display.CheckOK:=False;
- ScreenPopupCheck.ShowPopup(msg);
-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;
-
-procedure TMenu.AddButtonText(CustomButton: TButton; AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; AddText: string);
-var
- Il: integer;
-begin
- with CustomButton 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.SBGW,
- 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]);
-
- SelectsS[High(SelectsS)].Text.Size := ThemeSelectS.TextSize;
-
- SelectsS[High(SelectsS)].Texture.Z := ThemeSelectS.Z;
- SelectsS[High(SelectsS)].TextureSBG.Z := ThemeSelectS.Z;
-
- //Generate Lines
- SelectsS[High(SelectsS)].GenLines;
-
- SelectsS[High(SelectsS)].SelectedOption := SelectsS[High(SelectsS)].SelectOptInt; // refresh
-end;
-
-function TMenu.AddSelectSlide(X, Y, W, H, SkipX, SBGW, 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].SBGW := SBGW;
- 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 + (SelectsS[S].TextureSBG.H / 2) - 15;
- 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;
- //Button Collection Mod
- iBCollectionChild:
- begin
-
- //Select Next Button in Collection
- For Num := 1 to High(Button) do
- begin
- Value := (Interaction + Num) Mod Length(Button);
- if Value = 0 then
- begin
- InteractNext;
- Break;
- end;
- if (Button[Value].Parent = Button[Interaction].Parent) then
- begin
- Interaction := Value;
- Break;
- end;
- end;
- end;
- //interact Next if there is Nothing to Change
- else InteractNext;
- 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;
- //Button Collection Mod
- iBCollectionChild:
- begin
- //Select Prev Button in Collection
- For Num := High(Button) downto 1 do
- begin
- Value := (Interaction + Num) Mod Length(Button);
- if Value = High(Button) then
- begin
- InteractPrev;
- Break;
- end;
- if (Button[Value].Parent = Button[Interaction].Parent) then
- begin
- Interaction := Value;
- Break;
- end;
- end;
- end;
- //interact Prev if there is Nothing to Change
- else
- begin
- InteractPrev;
- //If ButtonCollection with more than 1 Entry then Select Last Entry
- if (Button[Interactions[Interaction].Num].Parent <> 0) AND (ButtonCollection[Button[Interactions[Interaction].Num].Parent-1].CountChilds > 1) then
- begin
- //Select Last Child
- For Num := High(Button) downto 1 do
- begin
- Value := (Interaction + Num) Mod Length(Button);
- if (Button[Value].Parent = Button[Interaction].Parent) then
- begin
- Interaction := Value;
- Break;
- end;
- end;
- end;
- 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.
-
+unit UMenu; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +uses OpenGL12, SysUtils, UTexture, UMenuStatic, UMenuText, UMenuButton, UMenuSelect, UMenuSelectSlide, + UMenuInteract, UThemes, UMenuButtonCollection, Math; + +type +{ Int16 = SmallInt;} + + PMenu = ^TMenu; + TMenu = class + protected + ButtonPos: Integer; + + Interactions: array of TInteract; + SelInteraction: integer; + Button: array of TButton; + Selects: array of TSelect; + SelectsS: array of TSelectSlide; + ButtonCollection: Array of TButtonCollection; + BackImg: TTexture; + BackW: integer; + BackH: integer; + public + Text: array of TText; + Static: array of TStatic; + 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; + + //Procedure Load BG, Texts, Statics and Button Collections from ThemeBasic + procedure LoadFromTheme(const ThemeBasic: TThemeBasic); + + procedure PrepareButtonCollections(const Collections: AThemeButtonCollection); + procedure AddButtonCollection(const ThemeCollection: TThemeButtonCollection; Const Num: Byte); + + // 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; Reflection: Boolean; ReflectionSpacing: Real): 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, W: real; Style: integer; Size, ColR, ColG, ColB: real; Align: integer; Tekst: string): integer; overload; + + // button + Procedure SetButtonLength(Length: Cardinal); //Function that Set Length of Button Array in one Step instead of register new Memory for every 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; ReflectionSpacing, DeSelectReflectionSpacing: Real): 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; + procedure AddButtonText(CustomButton: TButton; 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, SBGW, 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); + //popup hack + procedure CheckFadeTo(Screen: PMenu; msg: String); + + 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; + + function IsSelectable(Int: Cardinal): Boolean; + + 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; + iBCollectionChild = 5; + +// fBlack = 0; // fade type +// fWhite = 1; + +implementation + +uses UCommon, + 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; + + //Set ButtonPos to Autoset Length + ButtonPos := -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; + + //Set ButtonPos to Autoset Length + ButtonPos := -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; + + NewNum := Interactions[Num].Num; + NewTyp := Interactions[Num].Typ; + + case OldTyp of + iButton: Button[OldNum].Selected := False; + iSelect: Selects[OldNum].Selected := False; + iText: Text[OldNum].Selected := False; + iSelectS: SelectsS[OldNum].Selected := False; + //Button Collection Mod + iBCollectionChild: + begin + Button[OldNum].Selected := False; + + //Deselect Collection if Next Button is Not from Collection + if (NewTyp <> iButton) Or (Button[NewNum].Parent <> Button[OldNum].Parent) then + ButtonCollection[Button[OldNum].Parent-1].Selected := False; + end; + end; + + // set active + SelInteraction := Num; + case NewTyp of + iButton: Button[NewNum].Selected := True; + iSelect: Selects[NewNum].Selected := True; + iText: Text[NewNum].Selected := True; + iSelectS: SelectsS[NewNum].Selected := True; + + //Button Collection Mod + iBCollectionChild: + begin + Button[NewNum].Selected := True; + ButtonCollection[Button[NewNum].Parent-1].Selected := True; + end; + end; +end; + +//---------------------- +//LoadFromTheme - Load BG, Texts, Statics and +//Button Collections from ThemeBasic +//---------------------- +procedure TMenu.LoadFromTheme(const ThemeBasic: TThemeBasic); +var + I: Integer; +begin + //Add Button Collections (Set Button CollectionsLength) + //Button Collections are Created when the first ChildButton is Created + PrepareButtonCollections(ThemeBasic.ButtonCollection); + + {$ifdef fpc} + writeln(' TMenu.LoadFromThem : '+ThemeBasic.Background.Tex ); + {$endif} + + //Add Background + AddBackground(ThemeBasic.Background.Tex); + + //Add Statics and Texts + for I := 0 to High(ThemeBasic.Static) do + AddStatic(ThemeBasic.Static[I]); + + for I := 0 to High(ThemeBasic.Text) do + AddText(ThemeBasic.Text[I]); +end; + +procedure TMenu.AddBackground(Name: string); +var + lFileName : string; +begin + if Name <> '' then + begin +// BackImg := Texture.LoadTexture(false, PChar(Skin.SkinPath + FileName), 'JPG', 'Plain', 0); // new theme system + lFileName := Skin.GetTextureFileName(Name); + lFileName := AdaptFilePaths( lFileName ); + + {$ifdef fpc} + writeln(' TMenu.AddBackground : '+Name+ ' - '+ lFileName ); + {$endif} + +// if lFileName <> '' then + if fileexists( lFileName ) then + begin + BackImg := Texture.GetTexture( lFileName , 'Plain'); + + {$ifdef fpc} + writeln(' TMenu.AddBackground : '+ lFileName +' - LOADED'); + {$endif} + + + BackImg.W := 800; + BackImg.H := 600; + BackW := 1; + BackH := 1; + end; + end; +end; + +//---------------------- +//PrepareButtonCollections: +//Add Button Collections (Set Button CollectionsLength) +//---------------------- +procedure TMenu.PrepareButtonCollections(const Collections: AThemeButtonCollection); +var + I: Integer; +begin + SetLength(ButtonCollection, Length(Collections)); + For I := 0 to High(ButtonCollection) do + AddButtonCollection(Collections[I], I); +end; + +//---------------------- +//AddButtonCollection: +//Create a Button Collection; +//---------------------- +procedure TMenu.AddButtonCollection(const ThemeCollection: TThemeButtonCollection; Const Num: Byte); +var + BT, BTLen: Integer; + TempR, TempG, TempB, TempR2, TempG2, TempB2: Cardinal; + +begin + if (Num > High(ButtonCollection)) then + exit; + +// colorize hack +if ThemeCollection.Style.Typ='Colorized' then +begin + TempR:=floor(255*ThemeCollection.Style.ColR); + TempG:=floor(255*ThemeCollection.Style.ColG); + TempB:=floor(255*ThemeCollection.Style.ColB); + TempR2:=floor(255*ThemeCollection.Style.DColR); + TempG2:=floor(255*ThemeCollection.Style.DColG); + TempB2:=floor(255*ThemeCollection.Style.DColB); + // give encoded color to loadtexture + ButtonCollection[Num] := TButtonCollection.Create(Texture.LoadTexture(PChar(Skin.GetTextureFileName(ThemeCollection.Style.Tex)), 'JPG', 'Colorized', ((((TempR shl 8) or TempG) shl 8)or TempB)), + Texture.LoadTexture(PChar(Skin.GetTextureFileName(ThemeCollection.Style.Tex)), 'JPG', 'Colorized', ((((TempR2 shl 8) or TempG2) shl 8)or TempB2))); + +// Button[Result] := TButton.Create(Texture.LoadTexture(PChar(Name), PChar(Format), PChar(Typ), ((((TempR2 shl 8) or TempG2) shl 8)or TempB2))); // use cache texture +end +else + ButtonCollection[Num] := TButtonCollection.Create(Texture.GetTexture(Skin.GetTextureFileName(ThemeCollection.Style.Tex), ThemeCollection.Style.Typ, true)); // use cache texture + + //Set Parent menu + ButtonCollection[Num].ScreenButton := @Self.Button; + + //Set Attributes + ButtonCollection[Num].FirstChild := ThemeCollection.FirstChild; + ButtonCollection[Num].CountChilds := ThemeCollection.ChildCount; + ButtonCollection[Num].Parent := Num + 1; + + //Set Style + ButtonCollection[Num].X := ThemeCollection.Style.X; + ButtonCollection[Num].Y := ThemeCollection.Style.Y; + ButtonCollection[Num].W := ThemeCollection.Style.W; + ButtonCollection[Num].H := ThemeCollection.Style.H; + if ThemeCollection.Style.Typ <> 'Colorized' then begin + ButtonCollection[Num].SelectColR := ThemeCollection.Style.ColR; + ButtonCollection[Num].SelectColG := ThemeCollection.Style.ColG; + ButtonCollection[Num].SelectColB := ThemeCollection.Style.ColB; + ButtonCollection[Num].DeselectColR := ThemeCollection.Style.DColR; + ButtonCollection[Num].DeselectColG := ThemeCollection.Style.DColG; + ButtonCollection[Num].DeselectColB := ThemeCollection.Style.DColB; + end; + ButtonCollection[Num].SelectInt := ThemeCollection.Style.Int; + ButtonCollection[Num].DeselectInt := ThemeCollection.Style.DInt; + ButtonCollection[Num].Texture.TexX1 := 0; + ButtonCollection[Num].Texture.TexY1 := 0; + ButtonCollection[Num].Texture.TexX2 := 1; + ButtonCollection[Num].Texture.TexY2 := 1; + ButtonCollection[Num].SetSelect(false); + + ButtonCollection[Num].Reflection := ThemeCollection.Style.Reflection; + ButtonCollection[Num].Reflectionspacing := ThemeCollection.Style.ReflectionSpacing; + ButtonCollection[Num].DeSelectReflectionspacing := ThemeCollection.Style.DeSelectReflectionSpacing; + + ButtonCollection[Num].Z := ThemeCollection.Style.Z; + + //Some Things from ButtonFading + ButtonCollection[Num].SelectH := ThemeCollection.Style.SelectH; + ButtonCollection[Num].SelectW := ThemeCollection.Style.SelectW; + + ButtonCollection[Num].Fade := ThemeCollection.Style.Fade; + ButtonCollection[Num].FadeText := ThemeCollection.Style.FadeText; + if ThemeCollection.Style.Typ='Colorized' then + ButtonCollection[Num].FadeTex := Texture.LoadTexture(PChar(Skin.GetTextureFileName(ThemeCollection.Style.FadeTex)), 'JPG', 'Colorized', ((((TempR shl 8) or TempG) shl 8)or TempB)) + else + ButtonCollection[Num].FadeTex := Texture.GetTexture(Skin.GetTextureFileName(ThemeCollection.Style.FadeTex), ThemeCollection.Style.Typ, true); + ButtonCollection[Num].FadeTexPos := ThemeCollection.Style.FadeTexPos; + + + BTLen := Length(ThemeCollection.Style.Text); + for BT := 0 to BTLen-1 do begin + AddButtonText(ButtonCollection[Num], ThemeCollection.Style.Text[BT].X, ThemeCollection.Style.Text[BT].Y, + ThemeCollection.Style.Text[BT].ColR, ThemeCollection.Style.Text[BT].ColG, ThemeCollection.Style.Text[BT].ColB, + ThemeCollection.Style.Text[BT].Font, ThemeCollection.Style.Text[BT].Size, ThemeCollection.Style.Text[BT].Align, + ThemeCollection.Style.Text[BT].Text); + 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, ThemeStatic.Reflection, ThemeStatic.Reflectionspacing); + //'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, False, 0); +// +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; Reflection: Boolean; ReflectionSpacing: Real): integer; +var + StatNum: integer; + TempR, TempG, TempB: Cardinal; + TempCol: Cardinal; +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 + +// colorize hack +if Typ='Colorized' then +begin + TempR:=floor(255*ColR); + TempG:=floor(255*ColG); + TempB:=floor(255*ColB); + // give encoded color to loadtexture + Static[StatNum] := TStatic.Create(Texture.LoadTexture(PChar(Name), PChar(Format), PChar(Typ), ((((TempR shl 8) or TempG) shl 8)or TempB))); +end +else + 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; + if Typ <> 'Colorized' then begin + Static[StatNum].Texture.ColR := ColR; + Static[StatNum].Texture.ColG := ColG; + Static[StatNum].Texture.ColB := ColB; + end; + 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; + + //ReflectionMod + Static[StatNum].Reflection := Reflection; + Static[StatNum].ReflectionSpacing := ReflectionSpacing; + + Result := StatNum; +end; + +function TMenu.AddText(ThemeText: TThemeText): integer; +begin + Result := AddText(ThemeText.X, ThemeText.Y, ThemeText.W, 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, 0, Style, Size, ColR, ColG, ColB, 0, Tekst); +end; + +function TMenu.AddText(X, Y, W: 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, W, Style, Size, ColR, ColG, ColB, Align, Tekst); + Result := TextNum; +end; + +//Function that Set Length of Button Array in one Step instead of register new Memory for every Button +Procedure TMenu.SetButtonLength(Length: Cardinal); +begin + if (ButtonPos = -1) AND (Length > 0) then + begin + //Set Length of Button + SetLength(Button, Length); + + //Set ButtonPos to start with 0 + ButtonPos := 0; + end; +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; + TempR, TempG, TempB, TempR2, TempG2, TempB2: Cardinal; +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, ThemeButton.Reflectionspacing, ThemeButton.DeSelectReflectionspacing); + + Button[Result].Z := ThemeButton.Z; + + //Button Visibility + Button[Result].Visible := ThemeButton.Visible; + + //Some Things from ButtonFading + Button[Result].SelectH := ThemeButton.SelectH; + Button[Result].SelectW := ThemeButton.SelectW; + + Button[Result].Fade := ThemeButton.Fade; + Button[Result].FadeText := ThemeButton.FadeText; + if ThemeButton.Typ='Colorized' then begin + TempR:=floor(255*ThemeButton.ColR); + TempG:=floor(255*ThemeButton.ColG); + TempB:=floor(255*ThemeButton.ColB); + Button[Result].FadeTex := Texture.LoadTexture(PChar(Skin.GetTextureFileName(ThemeButton.FadeTex)), 'JPG', 'Colorized', ((((TempR shl 8) or TempG) shl 8)or TempB)); + end + else + Button[Result].FadeTex := Texture.GetTexture(Skin.GetTextureFileName(ThemeButton.FadeTex), ThemeButton.Typ, true); + Button[Result].FadeTexPos := ThemeButton.FadeTexPos; + + + 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; + + //BAutton Collection Mod + if (ThemeButton.Parent <> 0) then + begin + //If Collection Exists then Change Interaction to Child Button + if (@ButtonCollection[ThemeButton.Parent-1] <> nil) then + begin + Interactions[High(Interactions)].Typ := iBCollectionChild; + Button[Result].Visible := False; + + for BT := 0 to BTLen-1 do + Button[Result].Text[BT].Alpha := 0; + + Button[Result].Parent := ThemeButton.Parent; + if (ButtonCollection[ThemeButton.Parent-1].Fade) then + Button[Result].Texture.Alpha := 0; + end; + 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, 15, 15); +end; + +function TMenu.AddButton(X, Y, W, H, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt: real; Name, Format, Typ: String; Reflection: Boolean; ReflectionSpacing, DeSelectReflectionSpacing: Real): integer; +var TempR, TempG, TempB, TempR2, TempG2, TempB2: Cardinal; +begin + // adds button + //SetLength is used once to reduce Memory usement + if (ButtonPos <> -1) then + begin + Result := ButtonPos; + Inc(ButtonPos) + end + else //Old Method -> Reserve new Memory for every Button + begin + Result := Length(Button); + SetLength(Button, Result + 1); + end; +// Button[Result] := 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 +// colorize hack +if Typ='Colorized' then +begin + TempR:=floor(255*ColR); + TempG:=floor(255*ColG); + TempB:=floor(255*ColB); + TempR2:=floor(255*DColR); + TempG2:=floor(255*DColG); + TempB2:=floor(255*DColB); + // give encoded color to loadtexture + Button[Result] := TButton.Create(Texture.LoadTexture(PChar(Name), PChar(Format), PChar(Typ), ((((TempR shl 8) or TempG) shl 8)or TempB)), + Texture.LoadTexture(PChar(Name), PChar(Format), PChar(Typ), ((((TempR2 shl 8) or TempG2) shl 8)or TempB2))); + +// Button[Result] := TButton.Create(Texture.LoadTexture(PChar(Name), PChar(Format), PChar(Typ), ((((TempR2 shl 8) or TempG2) shl 8)or TempB2))); // use cache texture +end +else + + Button[Result] := TButton.Create(Texture.GetTexture(Name, Typ, true)); // use cache texture +// else +// Button[Result] := TButton.Create(Texture.GetTexture(Name, Typ, false)); // don't use cache texture} + + // configures button + Button[Result].X := X; + Button[Result].Y := Y; + Button[Result].W := W; + Button[Result].H := H; + if Typ <> 'Colorized' then begin + Button[Result].SelectColR := ColR; + Button[Result].SelectColG := ColG; + Button[Result].SelectColB := ColB; + Button[Result].DeselectColR := DColR; + Button[Result].DeselectColG := DColG; + Button[Result].DeselectColB := DColB; + end; + Button[Result].SelectInt := Int; + Button[Result].DeselectInt := DInt; + Button[Result].Texture.TexX1 := 0; + Button[Result].Texture.TexY1 := 0; + Button[Result].Texture.TexX2 := 1; + Button[Result].Texture.TexY2 := 1; + Button[Result].SetSelect(false); + + Button[Result].Reflection := Reflection; + Button[Result].Reflectionspacing := ReflectionSpacing; + Button[Result].DeSelectReflectionspacing := DeSelectReflectionSpacing; + + //Button Collection Mod + Button[Result].Parent := 0; + + + // adds interaction + AddInteraction(iButton, Result); + 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 + 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 + // does anyone know what these loops were for? +{ // 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} + BackImg.X:=BackW; + BackImg.Y:=BackW; + DrawTexture(BackImg); + 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; + + + // Draw all ButtonCollections + For J := 0 to High(ButtonCollection) do + ButtonCollection[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;} + +function TMenu.IsSelectable(Int: Cardinal): Boolean; +begin + Result := True; + Case Interactions[Int].Typ of + //Button + iButton: Result := Button[Interactions[Int].Num].Visible and Button[Interactions[Int].Num].Selectable; + //Select + iSelect: Result := True; + //Select Slide + iSelectS: Result := SelectsS[Interactions[Int].Num].Visible; + + //ButtonCollection Child + iBCollectionChild: + Result := (ButtonCollection[Button[Interactions[Int].Num].Parent - 1].FirstChild - 1 = Int) AND ((Interactions[Interaction].Typ <> iBCollectionChild) OR (Button[Interactions[Interaction].Num].Parent <> Button[Interactions[Int].Num].Parent)); + end; +end; + +procedure TMenu.InteractNext; +var + Int: Integer; +begin + Int := Interaction; + + // change interaction as long as it's needed + repeat + Int := (Int + 1) Mod Length(Interactions); + + //If no Interaction is Selectable Simply Select Next + if (Int = Interaction) then + begin + Int := (Int + 1) Mod Length(Interactions); + Break; + end; + Until IsSelectable(Int); + + //Set Interaction + Interaction := Int; +end; + + +procedure TMenu.InteractPrev; +var + Int: Integer; +begin + Int := Interaction; + + // change interaction as long as it's needed + repeat + Int := Int - 1; + if Int = -1 then Int := High(Interactions); + + //If no Interaction is Selectable Simply Select Next + if (Int = Interaction) then + begin + Int := SelInteraction - 1; + if Int = -1 then Int := High(Interactions); + Break; + end; + Until IsSelectable(Int); + + //Set Interaction + Interaction := Int +end; + + +procedure TMenu.InteractCustom(CustomSwitch: integer); +var + Num: integer; + Typ: integer; + Again: boolean; +begin + //Code Commented atm, because it needs to be Rewritten + //it doesn't work with Button Collections + {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; + +//popup hack +procedure TMenu.CheckFadeTo(Screen: PMenu; msg: String); +begin + Display.Fade := 0; + Display.NextScreenWithCheck := Screen; + Display.CheckOK:=False; + ScreenPopupCheck.ShowPopup(msg); +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; + +procedure TMenu.AddButtonText(CustomButton: TButton; AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; AddText: string); +var + Il: integer; +begin + with CustomButton 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.SBGW, + 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]); + + SelectsS[High(SelectsS)].Text.Size := ThemeSelectS.TextSize; + + SelectsS[High(SelectsS)].Texture.Z := ThemeSelectS.Z; + SelectsS[High(SelectsS)].TextureSBG.Z := ThemeSelectS.Z; + + //Generate Lines + SelectsS[High(SelectsS)].GenLines; + + SelectsS[High(SelectsS)].SelectedOption := SelectsS[High(SelectsS)].SelectOptInt; // refresh +end; + +function TMenu.AddSelectSlide(X, Y, W, H, SkipX, SBGW, 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].SBGW := SBGW; + 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 + (SelectsS[S].TextureSBG.H / 2) - 15; + 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; + //Button Collection Mod + iBCollectionChild: + begin + + //Select Next Button in Collection + For Num := 1 to High(Button) do + begin + Value := (Interaction + Num) Mod Length(Button); + if Value = 0 then + begin + InteractNext; + Break; + end; + if (Button[Value].Parent = Button[Interaction].Parent) then + begin + Interaction := Value; + Break; + end; + end; + end; + //interact Next if there is Nothing to Change + else InteractNext; + 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; + //Button Collection Mod + iBCollectionChild: + begin + //Select Prev Button in Collection + For Num := High(Button) downto 1 do + begin + Value := (Interaction + Num) Mod Length(Button); + if Value = High(Button) then + begin + InteractPrev; + Break; + end; + if (Button[Value].Parent = Button[Interaction].Parent) then + begin + Interaction := Value; + Break; + end; + end; + end; + //interact Prev if there is Nothing to Change + else + begin + InteractPrev; + //If ButtonCollection with more than 1 Entry then Select Last Entry + if (Button[Interactions[Interaction].Num].Parent <> 0) AND (ButtonCollection[Button[Interactions[Interaction].Num].Parent-1].CountChilds > 1) then + begin + //Select Last Child + For Num := High(Button) downto 1 do + begin + Value := (Interaction + Num) Mod Length(Button); + if (Button[Value].Parent = Button[Interaction].Parent) then + begin + Interaction := Value; + Break; + end; + end; + end; + 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/Screens/UScreenOptionsRecord.pas b/Game/Code/Screens/UScreenOptionsRecord.pas index 2ff989fa..ef8b31d1 100644 --- a/Game/Code/Screens/UScreenOptionsRecord.pas +++ b/Game/Code/Screens/UScreenOptionsRecord.pas @@ -1,132 +1,138 @@ -unit UScreenOptionsRecord;
-
-interface
-
-uses
- UMenu, SDL, UDisplay, UMusic, UFiles, 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_Q:
- begin
- Result := false;
- end;
- 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
- inherited Create;
-
- LoadFromTheme(Theme.OptionsRecord);
-
- 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);
- if (Length(Button[0].Text)=0) then
- AddButtonText(14, 20, Theme.Options.Description[7]);
-
- 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 +unit UScreenOptionsRecord; + +interface + +uses + UMenu, SDL, UDisplay, UMusic, UFiles, 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_Q: + begin + Result := false; + end; + 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 + inherited Create; + + LoadFromTheme(Theme.OptionsRecord); + + 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 + + {$IFDEF win32} + // TODO : JB_Linux .... Audio Input ... had to remove to get it to run ??? + + 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); + + {$ENDIF} + + + AddButton(Theme.OptionsRecord.ButtonExit); + if (Length(Button[0].Text)=0) then + AddButtonText(14, 20, Theme.Options.Description[7]); + + 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. diff --git a/Game/Code/Screens/UScreenScore.pas b/Game/Code/Screens/UScreenScore.pas index 0182bbd2..c53e8b32 100644 --- a/Game/Code/Screens/UScreenScore.pas +++ b/Game/Code/Screens/UScreenScore.pas @@ -1,663 +1,672 @@ -unit UScreenScore;
-
-interface
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-uses
- UMenu,
- SDL,
- SysUtils,
- UDisplay,
- UMusic,
- USongs,
- UThemes,
- OpenGL12,
- Windows,
- math,
- ULCD;
-
-// OpenGL;
-
-type
- TScreenScore = class(TMenu)
- public
- TextArtist: integer;
- TextTitle: integer;
-
- TextArtistTitle : 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;
- PlayerTexts : 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;
-
- BarScore_ActualHeight : array[1..6] of real;
- BarPhrase_ActualHeight : array[1..6] of real;
- BarGolden_ActualHeight : array[1..6] of real;
-
- BarScore_EaseOut_Step : real;
- BarPhrase_EaseOut_Step : real;
- BarGolden_EaseOut_Step : real;
-
- TextScore_ActualValue : array[1..6] of integer;
- TextPhrase_ActualValue : array[1..6] of integer;
- TextGolden_ActualValue : array[1..6] of integer;
-
- EaseOut_MaxSteps : real;
-
- constructor Create; override;
- function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override;
- procedure onShow; override;
- procedure onShowFinish; override;
- function Draw: boolean; override;
- procedure FillPlayer(Item, P: integer);
-
- function RaiseBar(PlayerNumber: integer; BarStartPosY: Single; ActualHeight: real; Score: integer; ColorBrightness : String; EaseOut_Step: Real) : real;
- function IncrementScore(PlayerNumber: integer; ActualScoreValue: Integer; ScoreReached: integer; EaseOut_Step: Real) : 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,
- SDLK_BACKSPACE :
-
- 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;
-var
- P: integer;
- I, C: integer;
-begin
- inherited Create;
-
- LoadFromTheme(Theme.Score);
-
- TextArtist := AddText(Theme.Score.TextArtist);
- TextTitle := AddText(Theme.Score.TextTitle);
-
- TextArtistTitle := AddText(Theme.Score.TextArtistTitle);
-
- 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]));
-
- SetLength(PlayerTexts[P], Length(Theme.Score.PlayerTexts[P]));
-
- for I := 0 to High(Theme.Score.PlayerStatic[P]) do
- PlayerStatic[P, I] := AddStatic(Theme.Score.PlayerStatic[P, I]);
-
-
- //added by mog
- for C := 0 to High(Theme.Score.PlayerTexts[P]) do
- PlayerTexts[P, C] := AddText(Theme.Score.PlayerTexts[P, C]);
- // more skinable now
-
- 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;
- Text[TextArtistTitle].Text := AktSong.Artist + ' - ' + 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];
-
- // We set alpha to 0 , so we can nicely blend them in when we need them
- Text[TextScore[P]].Alpha := 0;
- Text[TextNotesScore[P]].Alpha := 0;
- Text[TextNotes[P]].Alpha := 0;
- Text[TextLineBonus[P]].Alpha := 0;
- Text[TextLineBonusScore[P]].Alpha := 0;
- Text[TextGoldenNotes[P]].Alpha := 0;
- Text[TextGoldenNotesScore[P]].Alpha := 0;
- Text[TextTotal[P]].Alpha := 0;
- Text[TextTotalScore[P]].Alpha := 0;
-
- 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];
-
- for I := 0 to high(PlayerTexts[P]) do
- Text[PlayerTexts[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 := false; //V[P];
- Static[StaticBackLevelRound[P]].Visible := false; //V[P];
- Static[StaticLevel[P]].Visible := false; //V[P];
- Static[StaticLevelRound[P]].Visible := false; //V[P];
- end;
-
-end;
-
-procedure TScreenScore.onShowFinish;
-var
- index : integer;
-begin
-for index := 1 to 2 do
- begin
- BarScore_ActualHeight[index] := 0;
- BarPhrase_ActualHeight[index] := 0;
- BarGolden_ActualHeight[index] := 0;
-
- TextScore_ActualValue[index] := 0;
- TextPhrase_ActualValue[index] := 0;
- TextGolden_ActualValue[index] := 0;
- end;
-
-
- BarScore_EaseOut_Step := 1;
- BarPhrase_EaseOut_Step := 1;
- BarGolden_EaseOut_Step := 1;
-
- EaseOut_MaxSteps := 100;
-end;
-
-function TScreenScore.Draw: boolean;
-var
-{ Min: real;
- Max: real;
- Wsp: real;
- Wsp2: real;
- Pet: integer;}
-
- ActualTime, OldTime : Integer;
-
- Item: integer;
- P: integer;
- C: integer;
-
- katze : integer;
-begin
-
- // 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;
-{
- player[1].ScoreI := 7000;
- player[1].ScoreLineI := 2000;
- player[1].ScoreGoldenI := 1000;
-
- player[2].ScoreI := 2500;
- player[2].ScoreLineI := 1100;
- player[2].ScoreGoldenI := 900;
- }
-// Let's arise the bars
- ActualTime := GetTickCount div 33;
- if ((ActualTime <> OldTime) and ShowFinish )then
- begin
- OldTime := ActualTime;
-
- For katze:= 0 to 5 do
- begin
-
- // We actually araise them in the right order, but we have to draw them in reverse order (golden -> phrase -> mainscore)
- Case BarScore_EaseOut_Step < EaseOut_MaxSteps * 10 of
- true : BarScore_EaseOut_Step := BarScore_EaseOut_Step + 1;
- end;
-
- // PhrasenBonus
- if (BarScore_EaseOut_Step >= (EaseOut_MaxSteps * 10)) then
- begin
- Case BarPhrase_EaseOut_Step < EaseOut_MaxSteps * 10 of
- true : BarPhrase_EaseOut_Step := BarPhrase_EaseOut_Step + 1;
- end;
-
- // GoldenNotebonus
- if (BarPhrase_EaseOut_Step >= (EaseOut_MaxSteps * 10)) then
- begin
- Case BarGolden_EaseOut_Step < EaseOut_MaxSteps * 10 of
- true : BarGolden_EaseOut_Step := BarGolden_EaseOut_Step + 1;
- end;
-
- //########################
- // Draw golden score bar #
- //########################
-
- BarGolden_ActualHeight[katze] := RaiseBar(katze,
- Static[StaticBackLevel[katze+1]].Texture.y - BarScore_ActualHeight[katze] - BarPhrase_ActualHeight[katze],
- BarGolden_ActualHeight[katze],
- player[katze+1].ScoreGoldenI,
- 'Lightest',
- BarGolden_EaseOut_Step);
-
- // Increment and show total score and plain score
- TextGolden_ActualValue[katze] := IncrementScore(katze,
- TextGolden_ActualValue[katze],
- Player[katze+1].ScoreGoldenI,
- BarGolden_EaseOut_Step);
- Text[TextGoldenNotesScore[katze+1]].Text := IntToStr(TextGolden_ActualValue[katze]);
-
- // Blend in
- Text[TextGoldenNotesScore[katze+1]].Alpha := (BarGolden_EaseOut_Step / 100);
- Text[TextGoldenNotes[katze+1]].Alpha := (BarGolden_EaseOut_Step / 100);
-
- end;
- //########################
- // Draw phrase score bar #
- //########################
- BarPhrase_ActualHeight[katze] := RaiseBar(katze,
- Static[StaticBackLevel[katze+1]].Texture.y - BarScore_ActualHeight[katze],
- BarPhrase_ActualHeight[katze],
- Player[katze+1].ScoreLineI,
- 'Light',
- BarPhrase_EaseOut_Step);
-
- // Increment and show total score and plain score
- TextPhrase_ActualValue[katze] := IncrementScore(katze,
- TextPhrase_ActualValue[katze],
- Player[katze+1].ScoreLineI,
- BarPhrase_EaseOut_Step);
- Text[TextLineBonusScore[katze+1]].Text := IntToStr(TextPhrase_ActualValue[katze]);
-
- //Blend in
- Text[TextLineBonusScore[katze+1]].Alpha := (BarPhrase_EaseOut_Step / 100);
- Text[TextLineBonus[katze+1]].Alpha := (BarPhrase_EaseOut_Step / 100);
-
-
- end;
- //#######################
- // Draw plain score bar #
- //#######################
- BarScore_ActualHeight[katze] := RaiseBar(katze,
- Static[StaticBackLevel[katze+1]].Texture.y,
- BarScore_ActualHeight[katze],
- Player[katze+1].ScoreI,
- 'Dark',
- BarScore_EaseOut_Step);
- // Increment and show total score and plain score
- TextScore_ActualValue[katze] := IncrementScore(katze,
- TextScore_ActualValue[katze],
- Player[katze+1].ScoreI,
- BarScore_EaseOut_Step);
- Text[TextNotesScore[katze+1]].Text := IntToStr(TextScore_ActualValue[katze]);
-
- Text[TextTotalScore[katze+1]].Text := IntToStr(TextScore_ActualValue[katze] + TextPhrase_ActualValue[katze] + TextGolden_ActualValue[katze]);
-
- //Blend em in
- Text[TextTotalScore[katze+1]].Alpha := (BarScore_EaseOut_Step / 100);
- Text[TextTotal[katze+1]].Alpha := (BarScore_EaseOut_Step / 100);
- Text[TextNotesScore[katze+1]].Alpha := (BarScore_EaseOut_Step / 100);
- Text[TextNotes[katze+1]].Alpha := (BarScore_EaseOut_Step / 100);
- Text[TextScore[katze+1]].Alpha := (BarScore_EaseOut_Step / 100);
-
- end; // me loop
- end;
-end;
-
-
-function TscreenScore.RaiseBar(PlayerNumber: integer; BarStartPosY: Single; ActualHeight: real; Score: integer; ColorBrightness : String; EaseOut_Step: Real) : real;
-const
- RaiseSmoothness : integer = 100;
-var
- MaxHeight : real;
- NewHeight : real;
- Width : real;
-
- Height2Reach : real;
-
- RaiseStep : real;
-
- BarStartPosX : Single;
-
- R,G,B : real;
-begin
-
- MaxHeight := Static[StaticBackLevel[PlayerNumber + 1]].Texture.H;
- Width := Static[StaticBackLevel[PlayerNumber + 1]].Texture.W;
-
- BarStartPosX := Static[StaticBackLevel[PlayerNumber + 1]].Texture.X;
-
- BarStartPosY := BarStartPosY + MaxHeight; // The texture starts in the upper left corner, so let's subtract the height - so we can arise it
-
- // the height dependend of the score
- Height2Reach := (Score / 10000) * MaxHeight;
-
- // EaseOut_Step is the actual step in the raising process, like the 20iest step of EaseOut_MaxSteps
- RaiseStep := EaseOut_Step;
-
- if (ActualHeight < Height2Reach) then
- begin
- // Check http://proto.layer51.com/d.aspx?f=400 for more info on easing functions
- // Calculate the actual step according to the maxsteps
- RaiseStep := RaiseStep / EaseOut_MaxSteps;
-
- // quadratic easing out - decelerating to zero velocity
- // -end_position * current_time * ( current_time - 2 ) + start_postion
- NewHeight := (-Height2Reach * RaiseStep * (RaiseStep - 20) + BarStartPosY) / RaiseSmoothness;
- end
- else
- begin
- NewHeight := Height2Reach;
- end;
- //+1
- LoadColor(R, G, B, 'P' + inttostr(PlayerNumber+1) + ColorBrightness); //dark, light, lightest
- glColor4f(R, G, B, 1);
-
- //the actual bar
- glBindTexture(GL_TEXTURE_2D, Static[StaticLevel[PlayerNumber + 1]].Texture.TexNum);
-
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(BarStartPosX, BarStartPosY - NewHeight);
- glTexCoord2f(1, 0); glVertex2f(BarStartPosX + Width, BarStartPosY - NewHeight);
- glTexCoord2f(1, 1); glVertex2f(BarStartPosX + Width, BarStartPosY);
- glTexCoord2f(0, 1); glVertex2f(BarStartPosX, BarStartPosY);
- glEnd;
-
- //the round thing on top
- glBindTexture(GL_TEXTURE_2D, Static[StaticLevelRound[PlayerNumber + 1]].Texture.TexNum);
-
- glEnable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
-
- glBegin(GL_QUADS);
- glTexCoord2f(0, 0); glVertex2f(BarStartPosX, (BarStartPosY - Static[StaticLevelRound[PlayerNumber + 1]].Texture.h) - NewHeight);
- glTexCoord2f(1, 0); glVertex2f(BarStartPosX + Width, (BarStartPosY - Static[StaticLevelRound[PlayerNumber + 1]].Texture.h) - NewHeight);
- glTexCoord2f(1, 1); glVertex2f(BarStartPosX + Width, BarStartPosY - NewHeight);
- glTexCoord2f(0, 1); glVertex2f(BarStartPosX, BarStartPosY - NewHeight);
- glEnd;
-
- Result := NewHeight;
-end;
-
-function TScreenScore.IncrementScore(PlayerNumber: integer; ActualScoreValue: Integer; ScoreReached: integer; EaseOut_Step: Real) : integer;
-const
- RaiseSmoothness : integer = 100;
-var
- RaiseStep : Real;
- lTmpA : Real;
-begin
- // EaseOut_Step is the actual step in the raising process, like the 20iest step of EaseOut_MaxSteps
- RaiseStep := EaseOut_Step;
-
- if (ActualScoreValue < ScoreReached) then
- begin
- // Calculate the actual step according to the maxsteps
- RaiseStep := RaiseStep / EaseOut_MaxSteps;
-
- // quadratic easing out - decelerating to zero velocity
- // -end_position * current_time * ( current_time - 2 ) + start_postion
- lTmpA := (-ScoreReached * RaiseStep * (RaiseStep - 20));
- if ( lTmpA > 0 ) AND
- ( RaiseSmoothness > 0 ) THEN
- begin
- Result := floor( lTmpA / RaiseSmoothness);
- end;
- end
- else
- begin
- Result := ScoreReached;
- end;
-
-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;
-
-//fixed: line bonus and golden notes don't show up,
-// another bug: total score was shown without added golden-, linebonus
- S := IntToStr(Player[P].ScoreTotalI);
- while (Length(S)<5) do S := '0' + S;
- Text[TextTotalScore[Item]].Text := S;
-
- S := IntToStr(Player[P].ScoreLineI);
- while (Length(S)<4) do S := '0' + S;
- Text[TextLineBonusScore[Item]].Text := S;
-
- S := IntToStr(Player[P].ScoreGoldenI);
- while (Length(S)<4) do S := '0' + S;
- Text[TextGoldenNotesScore[Item]].Text := S;
-//end of fix
-
- 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.
+unit UScreenScore; + +interface + +{$IFDEF FPC} + {$MODE DELPHI} +{$ENDIF} + +uses + UMenu, + SDL, + SysUtils, + UDisplay, + UMusic, + USongs, + UThemes, + OpenGL12, + {$ifdef win32} + Windows, + {$endif} + math, + ULCD; + +// OpenGL; + +type + TScreenScore = class(TMenu) + public + TextArtist: integer; + TextTitle: integer; + + TextArtistTitle : 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; + PlayerTexts : 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; + + BarScore_ActualHeight : array[1..6] of real; + BarPhrase_ActualHeight : array[1..6] of real; + BarGolden_ActualHeight : array[1..6] of real; + + BarScore_EaseOut_Step : real; + BarPhrase_EaseOut_Step : real; + BarGolden_EaseOut_Step : real; + + TextScore_ActualValue : array[1..6] of integer; + TextPhrase_ActualValue : array[1..6] of integer; + TextGolden_ActualValue : array[1..6] of integer; + + EaseOut_MaxSteps : real; + + constructor Create; override; + function ParseInput(PressedKey: Cardinal; ScanCode: byte; PressedDown: Boolean): Boolean; override; + procedure onShow; override; + procedure onShowFinish; override; + function Draw: boolean; override; + procedure FillPlayer(Item, P: integer); + + function RaiseBar(PlayerNumber: integer; BarStartPosY: Single; ActualHeight: real; Score: integer; ColorBrightness : String; EaseOut_Step: Real) : real; + function IncrementScore(PlayerNumber: integer; ActualScoreValue: Integer; ScoreReached: integer; EaseOut_Step: Real) : integer; + end; + +implementation + + +uses UGraphic, + UScreenSong, + UMenuStatic, + UTime, + UMain, + UIni, + {$IFNDEF win32} + lclintf, + {$ENDIF} + ULanguage; + +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, + SDLK_BACKSPACE : + + 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; +var + P: integer; + I, C: integer; +begin + inherited Create; + + LoadFromTheme(Theme.Score); + + TextArtist := AddText(Theme.Score.TextArtist); + TextTitle := AddText(Theme.Score.TextTitle); + + TextArtistTitle := AddText(Theme.Score.TextArtistTitle); + + 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])); + + SetLength(PlayerTexts[P], Length(Theme.Score.PlayerTexts[P])); + + for I := 0 to High(Theme.Score.PlayerStatic[P]) do + PlayerStatic[P, I] := AddStatic(Theme.Score.PlayerStatic[P, I]); + + + //added by mog + for C := 0 to High(Theme.Score.PlayerTexts[P]) do + PlayerTexts[P, C] := AddText(Theme.Score.PlayerTexts[P, C]); + // more skinable now + + 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; + Text[TextArtistTitle].Text := AktSong.Artist + ' - ' + 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]; + + // We set alpha to 0 , so we can nicely blend them in when we need them + Text[TextScore[P]].Alpha := 0; + Text[TextNotesScore[P]].Alpha := 0; + Text[TextNotes[P]].Alpha := 0; + Text[TextLineBonus[P]].Alpha := 0; + Text[TextLineBonusScore[P]].Alpha := 0; + Text[TextGoldenNotes[P]].Alpha := 0; + Text[TextGoldenNotesScore[P]].Alpha := 0; + Text[TextTotal[P]].Alpha := 0; + Text[TextTotalScore[P]].Alpha := 0; + + 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]; + + for I := 0 to high(PlayerTexts[P]) do + Text[PlayerTexts[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 := false; //V[P]; + Static[StaticBackLevelRound[P]].Visible := false; //V[P]; + Static[StaticLevel[P]].Visible := false; //V[P]; + Static[StaticLevelRound[P]].Visible := false; //V[P]; + end; + +end; + +procedure TScreenScore.onShowFinish; +var + index : integer; +begin +for index := 1 to 2 do + begin + BarScore_ActualHeight[index] := 0; + BarPhrase_ActualHeight[index] := 0; + BarGolden_ActualHeight[index] := 0; + + TextScore_ActualValue[index] := 0; + TextPhrase_ActualValue[index] := 0; + TextGolden_ActualValue[index] := 0; + end; + + + BarScore_EaseOut_Step := 1; + BarPhrase_EaseOut_Step := 1; + BarGolden_EaseOut_Step := 1; + + EaseOut_MaxSteps := 100; +end; + +function TScreenScore.Draw: boolean; +var +{ Min: real; + Max: real; + Wsp: real; + Wsp2: real; + Pet: integer;} + + ActualTime, OldTime : Integer; + + Item: integer; + P: integer; + C: integer; + + katze : integer; +begin + + // 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; +{ + player[1].ScoreI := 7000; + player[1].ScoreLineI := 2000; + player[1].ScoreGoldenI := 1000; + + player[2].ScoreI := 2500; + player[2].ScoreLineI := 1100; + player[2].ScoreGoldenI := 900; + } +// Let's arise the bars + ActualTime := GetTickCount div 33; + if ((ActualTime <> OldTime) and ShowFinish )then + begin + OldTime := ActualTime; + + For katze:= 0 to 5 do + begin + + // We actually araise them in the right order, but we have to draw them in reverse order (golden -> phrase -> mainscore) + Case BarScore_EaseOut_Step < EaseOut_MaxSteps * 10 of + true : BarScore_EaseOut_Step := BarScore_EaseOut_Step + 1; + end; + + // PhrasenBonus + if (BarScore_EaseOut_Step >= (EaseOut_MaxSteps * 10)) then + begin + Case BarPhrase_EaseOut_Step < EaseOut_MaxSteps * 10 of + true : BarPhrase_EaseOut_Step := BarPhrase_EaseOut_Step + 1; + end; + + // GoldenNotebonus + if (BarPhrase_EaseOut_Step >= (EaseOut_MaxSteps * 10)) then + begin + Case BarGolden_EaseOut_Step < EaseOut_MaxSteps * 10 of + true : BarGolden_EaseOut_Step := BarGolden_EaseOut_Step + 1; + end; + + //######################## + // Draw golden score bar # + //######################## + + BarGolden_ActualHeight[katze] := RaiseBar(katze, + Static[StaticBackLevel[katze+1]].Texture.y - BarScore_ActualHeight[katze] - BarPhrase_ActualHeight[katze], + BarGolden_ActualHeight[katze], + player[katze+1].ScoreGoldenI, + 'Lightest', + BarGolden_EaseOut_Step); + + // Increment and show total score and plain score + TextGolden_ActualValue[katze] := IncrementScore(katze, + TextGolden_ActualValue[katze], + Player[katze+1].ScoreGoldenI, + BarGolden_EaseOut_Step); + Text[TextGoldenNotesScore[katze+1]].Text := IntToStr(TextGolden_ActualValue[katze]); + + // Blend in + Text[TextGoldenNotesScore[katze+1]].Alpha := (BarGolden_EaseOut_Step / 100); + Text[TextGoldenNotes[katze+1]].Alpha := (BarGolden_EaseOut_Step / 100); + + end; + //######################## + // Draw phrase score bar # + //######################## + BarPhrase_ActualHeight[katze] := RaiseBar(katze, + Static[StaticBackLevel[katze+1]].Texture.y - BarScore_ActualHeight[katze], + BarPhrase_ActualHeight[katze], + Player[katze+1].ScoreLineI, + 'Light', + BarPhrase_EaseOut_Step); + + // Increment and show total score and plain score + TextPhrase_ActualValue[katze] := IncrementScore(katze, + TextPhrase_ActualValue[katze], + Player[katze+1].ScoreLineI, + BarPhrase_EaseOut_Step); + Text[TextLineBonusScore[katze+1]].Text := IntToStr(TextPhrase_ActualValue[katze]); + + //Blend in + Text[TextLineBonusScore[katze+1]].Alpha := (BarPhrase_EaseOut_Step / 100); + Text[TextLineBonus[katze+1]].Alpha := (BarPhrase_EaseOut_Step / 100); + + + end; + //####################### + // Draw plain score bar # + //####################### + BarScore_ActualHeight[katze] := RaiseBar(katze, + Static[StaticBackLevel[katze+1]].Texture.y, + BarScore_ActualHeight[katze], + Player[katze+1].ScoreI, + 'Dark', + BarScore_EaseOut_Step); + // Increment and show total score and plain score + TextScore_ActualValue[katze] := IncrementScore(katze, + TextScore_ActualValue[katze], + Player[katze+1].ScoreI, + BarScore_EaseOut_Step); + Text[TextNotesScore[katze+1]].Text := IntToStr(TextScore_ActualValue[katze]); + + Text[TextTotalScore[katze+1]].Text := IntToStr(TextScore_ActualValue[katze] + TextPhrase_ActualValue[katze] + TextGolden_ActualValue[katze]); + + //Blend em in + Text[TextTotalScore[katze+1]].Alpha := (BarScore_EaseOut_Step / 100); + Text[TextTotal[katze+1]].Alpha := (BarScore_EaseOut_Step / 100); + Text[TextNotesScore[katze+1]].Alpha := (BarScore_EaseOut_Step / 100); + Text[TextNotes[katze+1]].Alpha := (BarScore_EaseOut_Step / 100); + Text[TextScore[katze+1]].Alpha := (BarScore_EaseOut_Step / 100); + + end; // me loop + end; +end; + + +function TscreenScore.RaiseBar(PlayerNumber: integer; BarStartPosY: Single; ActualHeight: real; Score: integer; ColorBrightness : String; EaseOut_Step: Real) : real; +const + RaiseSmoothness : integer = 100; +var + MaxHeight : real; + NewHeight : real; + Width : real; + + Height2Reach : real; + + RaiseStep : real; + + BarStartPosX : Single; + + R,G,B : real; +begin + + MaxHeight := Static[StaticBackLevel[PlayerNumber + 1]].Texture.H; + Width := Static[StaticBackLevel[PlayerNumber + 1]].Texture.W; + + BarStartPosX := Static[StaticBackLevel[PlayerNumber + 1]].Texture.X; + + BarStartPosY := BarStartPosY + MaxHeight; // The texture starts in the upper left corner, so let's subtract the height - so we can arise it + + // the height dependend of the score + Height2Reach := (Score / 10000) * MaxHeight; + + // EaseOut_Step is the actual step in the raising process, like the 20iest step of EaseOut_MaxSteps + RaiseStep := EaseOut_Step; + + if (ActualHeight < Height2Reach) then + begin + // Check http://proto.layer51.com/d.aspx?f=400 for more info on easing functions + // Calculate the actual step according to the maxsteps + RaiseStep := RaiseStep / EaseOut_MaxSteps; + + // quadratic easing out - decelerating to zero velocity + // -end_position * current_time * ( current_time - 2 ) + start_postion + NewHeight := (-Height2Reach * RaiseStep * (RaiseStep - 20) + BarStartPosY) / RaiseSmoothness; + end + else + begin + NewHeight := Height2Reach; + end; + //+1 + LoadColor(R, G, B, 'P' + inttostr(PlayerNumber+1) + ColorBrightness); //dark, light, lightest + glColor4f(R, G, B, 1); + + //the actual bar + glBindTexture(GL_TEXTURE_2D, Static[StaticLevel[PlayerNumber + 1]].Texture.TexNum); + + glEnable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(BarStartPosX, BarStartPosY - NewHeight); + glTexCoord2f(1, 0); glVertex2f(BarStartPosX + Width, BarStartPosY - NewHeight); + glTexCoord2f(1, 1); glVertex2f(BarStartPosX + Width, BarStartPosY); + glTexCoord2f(0, 1); glVertex2f(BarStartPosX, BarStartPosY); + glEnd; + + //the round thing on top + glBindTexture(GL_TEXTURE_2D, Static[StaticLevelRound[PlayerNumber + 1]].Texture.TexNum); + + glEnable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2f(BarStartPosX, (BarStartPosY - Static[StaticLevelRound[PlayerNumber + 1]].Texture.h) - NewHeight); + glTexCoord2f(1, 0); glVertex2f(BarStartPosX + Width, (BarStartPosY - Static[StaticLevelRound[PlayerNumber + 1]].Texture.h) - NewHeight); + glTexCoord2f(1, 1); glVertex2f(BarStartPosX + Width, BarStartPosY - NewHeight); + glTexCoord2f(0, 1); glVertex2f(BarStartPosX, BarStartPosY - NewHeight); + glEnd; + + Result := NewHeight; +end; + +function TScreenScore.IncrementScore(PlayerNumber: integer; ActualScoreValue: Integer; ScoreReached: integer; EaseOut_Step: Real) : integer; +const + RaiseSmoothness : integer = 100; +var + RaiseStep : Real; + lTmpA : Real; +begin + // EaseOut_Step is the actual step in the raising process, like the 20iest step of EaseOut_MaxSteps + RaiseStep := EaseOut_Step; + + if (ActualScoreValue < ScoreReached) then + begin + // Calculate the actual step according to the maxsteps + RaiseStep := RaiseStep / EaseOut_MaxSteps; + + // quadratic easing out - decelerating to zero velocity + // -end_position * current_time * ( current_time - 2 ) + start_postion + lTmpA := (-ScoreReached * RaiseStep * (RaiseStep - 20)); + if ( lTmpA > 0 ) AND + ( RaiseSmoothness > 0 ) THEN + begin + Result := floor( lTmpA / RaiseSmoothness); + end; + end + else + begin + Result := ScoreReached; + end; + +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; + +//fixed: line bonus and golden notes don't show up, +// another bug: total score was shown without added golden-, linebonus + S := IntToStr(Player[P].ScoreTotalI); + while (Length(S)<5) do S := '0' + S; + Text[TextTotalScore[Item]].Text := S; + + S := IntToStr(Player[P].ScoreLineI); + while (Length(S)<4) do S := '0' + S; + Text[TextLineBonusScore[Item]].Text := S; + + S := IntToStr(Player[P].ScoreGoldenI); + while (Length(S)<4) do S := '0' + S; + Text[TextGoldenNotesScore[Item]].Text := S; +//end of fix + + 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/UScreenTop5.pas b/Game/Code/Screens/UScreenTop5.pas index 4971d12a..d0fe15c8 100644 --- a/Game/Code/Screens/UScreenTop5.pas +++ b/Game/Code/Screens/UScreenTop5.pas @@ -1,168 +1,168 @@ -unit UScreenTop5;
-
-interface
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ENDIF}
-
-
-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, UDataBase, 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_BACKSPACE,
- 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;
-
- LoadFromTheme(Theme.Top5);
-
-
- 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
- DataBase.AddScore(AktSong, Ini.Difficulty, Ini.Name[I], Round(Player[I].ScoreTotalI));
-
- DataBase.WriteScore(AktSong);
- DataBase.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.
+unit UScreenTop5; + +interface + +{$IFDEF FPC} + {$MODE DELPHI} +{$ENDIF} + + +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, UDataBase, 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_BACKSPACE, + 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; + + LoadFromTheme(Theme.Top5); + + + 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 + DataBase.AddScore(AktSong, Ini.Difficulty, Ini.Name[I], Round(Player[I].ScoreTotalI)); + + DataBase.WriteScore(AktSong); + DataBase.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/UltraStar.lpr b/Game/Code/UltraStar.lpr index 026d0d69..ce006d54 100644 --- a/Game/Code/UltraStar.lpr +++ b/Game/Code/UltraStar.lpr @@ -1,428 +1,428 @@ -program UltraStar;
-
-{$DEFINE TRANSLATE}
-
-{$IFDEF FPC}
- {$MODE DELPHI}
-{$ELSE}
- {$R 'UltraStar.res' 'UltraStar.rc'}
-{$ENDIF}
-
-{$I switches.inc}
-
-uses
-
- // ***************************************************************************
- //
- // Developers PLEASE NOTE !!!!!!!
- //
- // As of september 2007, I am working towards porting Ultrastar-DX to run
- // on Linux. I will be modifiying the source to make it compile in lazarus
- // on windows & linux and I will make sure that it compiles in delphi still
- // To help me in this endevour, please can you make a point of remembering
- // that linux is CASE SENSATIVE, and file / unit names must be as per
- // the filename exactly.
- //
- // EG : opengl12.pas must not be OpenGL in the uses cluase.
- //
- // thanks for your help...
- //
- // ***************************************************************************
-
- // Interesting stuff... :)
- // http://burningsmell.org/sdl_audioin/
-
-
- //------------------------------
- //Includes - 3rd Party Libraries
- //------------------------------
-
- // SDL / OpenGL
- moduleloader in 'lib\JEDI-SDLv1.0\SDL\Pas\moduleloader.pas',
- opengl12 in 'lib\JEDI-SDLv1.0\OpenGL\Pas\opengl12.pas',
- sdl in 'lib\JEDI-SDLv1.0\SDL\Pas\sdl.pas',
- sdl_image in 'lib\JEDI-SDLv1.0\SDL_Image\Pas\sdl_image.pas',
- sdl_ttf in 'lib\JEDI-SDLv1.0\SDL_ttf\Pas\sdl_ttf.pas',
- sdlutils in 'lib\JEDI-SDLv1.0\SDL\Pas\sdlutils.pas',
-
-
- // Bass
- {$IFDEF UseBASS}
- bass in 'lib\bass\delphi\bass.pas',
- {$ENDIF}
-
- // Midi Units
- {$IFDEF UseMIDIPort}
- Circbuf in 'lib\midi\CIRCBUF.PAS',
- Delphmcb in 'lib\midi\Delphmcb.PAS',
- MidiCons in 'lib\midi\MidiCons.PAS',
- MidiDefs in 'lib\midi\MidiDefs.PAS',
- MidiFile in 'lib\midi\MidiFile.PAS',
- midiin in 'lib\midi\midiin.pas',
- midiout in 'lib\midi\midiout.pas',
- MidiType in 'lib\midi\MidiType.PAS',
- {$ENDIF}
-
- // FFMpeg units
- avcodec in 'lib\ffmpeg\avcodec.pas',
- avformat in 'lib\ffmpeg\avformat.pas',
- avio in 'lib\ffmpeg\avio.pas',
- avutil in 'lib\ffmpeg\avutil.pas',
- opt in 'lib\ffmpeg\opt.pas',
- rational in 'lib\ffmpeg\rational.pas',
-
-
- // Sql Lite
- SQLiteTable3 in 'lib\SQLite\SQLiteTable3.pas',
- SQLite3 in 'lib\SQLite\SQLite3.pas',
-
-
- //------------------------------
- //Includes - Menu System
- //------------------------------
-
- UDisplay in 'Menu\UDisplay.pas',
- UDrawTexture in 'Menu\UDrawTexture.pas',
- UMenu in 'Menu\UMenu.pas',
- UMenuButton in 'Menu\UMenuButton.pas',
- UMenuButtonCollection in 'Menu\UMenuButtonCollection.pas',
- UMenuInteract in 'Menu\UMenuInteract.pas',
- UMenuSelect in 'Menu\UMenuSelect.pas',
- UMenuSelectSlide in 'Menu\UMenuSelectSlide.pas',
- UMenuStatic in 'Menu\UMenuStatic.pas',
- UMenuText in 'Menu\UMenuText.pas',
-
- //------------------------------
- //Includes - Classes
- //------------------------------
-
- {$IFDEF FPC}
- ulazjpeg in 'Classes\ulazjpeg.pas',
- {$ENDIF}
-
- TextGL in 'Classes\TextGL.pas',
- UCatCovers in 'Classes\UCatCovers.pas',
- UCommandLine in 'Classes\UCommandLine.pas',
- UCommon in 'Classes\UCommon.pas',
- UCovers in 'Classes\UCovers.pas',
- UDataBase in 'Classes\UDataBase.pas',
- UDLLManager in 'Classes\UDLLManager.pas',
- UDraw in 'Classes\UDraw.pas',
- UFiles in 'Classes\UFiles.pas',
- UGraphic in 'Classes\UGraphic.pas',
- UGraphicClasses in 'Classes\UGraphicClasses.pas',
- UIni in 'Classes\UIni.pas',
- UJoystick in 'Classes\UJoystick.pas',
- ULanguage in 'Classes\ULanguage.pas',
- ULCD in 'Classes\ULCD.pas',
- ULight in 'Classes\ULight.pas',
- ULog in 'Classes\ULog.pas',
- ULyrics in 'Classes\ULyrics.pas',
- ULyrics_bak in 'Classes\ULyrics_bak.pas',
- UMain in 'Classes\UMain.pas',
- UMusic in 'Classes\UMusic.pas',
- UParty in 'Classes\UParty.pas',
- UPlaylist in 'Classes\UPlaylist.pas',
- URecord in 'Classes\URecord.pas',
- USkins in 'Classes\USkins.pas',
- USingScores in 'Classes\USingScores.pas',
- USongs in 'Classes\USongs.pas',
- UTexture in 'Classes\UTexture.pas',
- UThemes in 'Classes\UThemes.pas',
- UTime in 'Classes\UTime.pas',
- USingNotes in 'Classes\USingNotes.pas',
-
-
- //------------------------------
- //Includes - Video Support
- //------------------------------
- UVideo in 'Classes\UVideo.pas',
-
-
- //------------------------------
- //Includes - Screens
- //------------------------------
- UScreenCredits in 'Screens\UScreenCredits.pas',
- UScreenEdit in 'Screens\UScreenEdit.pas',
- UScreenEditConvert in 'Screens\UScreenEditConvert.pas',
- UScreenEditHeader in 'Screens\UScreenEditHeader.pas',
- UScreenEditSub in 'Screens\UScreenEditSub.pas',
- UScreenLevel in 'Screens\UScreenLevel.pas',
- UScreenLoading in 'Screens\UScreenLoading.pas',
- UScreenMain in 'Screens\UScreenMain.pas',
- UScreenName in 'Screens\UScreenName.pas',
- UScreenOpen in 'Screens\UScreenOpen.pas',
- UScreenOptions in 'Screens\UScreenOptions.pas',
- UScreenOptionsAdvanced in 'Screens\UScreenOptionsAdvanced.pas',
- UScreenOptionsGame in 'Screens\UScreenOptionsGame.pas',
- UScreenOptionsGraphics in 'Screens\UScreenOptionsGraphics.pas',
- UScreenOptionsLyrics in 'Screens\UScreenOptionsLyrics.pas',
- UScreenOptionsRecord in 'Screens\UScreenOptionsRecord.pas',
- UScreenOptionsSound in 'Screens\UScreenOptionsSound.pas',
- UScreenOptionsThemes in 'Screens\UScreenOptionsThemes.pas',
- UScreenPopup in 'Screens\UScreenPopup.pas',
- UScreenScore in 'Screens\UScreenScore.pas',
- UScreenSing in 'Screens\UScreenSing.pas',
- UScreenSong in 'Screens\UScreenSong.pas',
- UScreenSongJumpto in 'Screens\UScreenSongJumpto.pas',
- UScreenSongMenu in 'Screens\UScreenSongMenu.pas',
- UScreenStatDetail in 'Screens\UScreenStatDetail.pas',
- UScreenStatMain in 'Screens\UScreenStatMain.pas',
- UScreenTop5 in 'Screens\UScreenTop5.pas',
- UScreenWelcome in 'Screens\UScreenWelcome.pas',
-
- //------------------------------
- //Includes - Screens PartyMode
- //------------------------------
- UScreenPartyNewRound in 'Screens\UScreenPartyNewRound.pas',
- UScreenPartyOptions in 'Screens\UScreenPartyOptions.pas',
- UScreenPartyPlayer in 'Screens\UScreenPartyPlayer.pas',
- UScreenPartyScore in 'Screens\UScreenPartyScore.pas',
- UScreenPartyWin in 'Screens\UScreenPartyWin.pas',
- UScreenSingModi in 'Screens\UScreenSingModi.pas',
-
- //------------------------------
- //Includes - Modi SDK
- //------------------------------
- ModiSDK in '..\..\Modis\SDK\ModiSDK.pas',
-
-
- //------------------------------
- //Includes - Delphi
- //------------------------------
- {$IFDEF win32}
- Windows,
- {$ENDIF}
- SysUtils;
-
-const
- Version = 'UltraStar Deluxe V 1.10 Alpha Build';
-
-var
- WndTitle: string;
- hWnd: THandle;
- I: Integer;
-
-begin
- WndTitle := Version;
-
-
- {$ifdef Win32}
- //------------------------------
- //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;
- {$endif}
-
- //------------------------------
- //StartUp - Create Classes and Load Files
- //------------------------------
- USTime := TTime.Create;
-
- // Commandline Parameter Parser
- Params := TCMDParams.Create;
-
- // Log + Benchmark
- Log := TLog.Create;
- Log.Title := WndTitle;
- Log.Enabled := Not Params.NoLog;
- Log.BenchmarkStart(0);
-
- // 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);
-
- // 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;
-
- //Load Languagefile
- if (Params.Language <> -1) then
- Language.ChangeLanguage(ILanguage[Params.Language])
- else
- 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;
- 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.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('DataBase System', 'Initialization');
- DataBase := TDataBaseSystem.Create;
-
- if (Params.ScoreFile = '') then
- DataBase.Init ('Ultrastar.db')
- else
- DataBase.Init (Params.ScoreFile);
-
- Log.BenchmarkEnd(1);
- Log.LogBenchmark('Loading DataBase System', 1);
-
- //Playlist Manager
- Log.BenchmarkStart(1);
- Log.LogStatus('Playlist Manager', 'Initialization');
- PlaylistMan := TPlaylistManager.Create;
- Log.BenchmarkEnd(1);
- Log.LogBenchmark('Loading Playlist Manager', 1);
-
- //GoldenStarsTwinkleMod
- Log.BenchmarkStart(1);
- Log.LogStatus('Effect Manager', 'Initialization');
- GoldenRec := TEffectManager.Create;
- Log.BenchmarkEnd(1);
- Log.LogBenchmark('Loading Particel System', 1);
-
- // Joypad
- if (Ini.Joypad = 1) OR (Params.Joypad) then begin
- Log.BenchmarkStart(1);
- Log.LogStatus('Initialize Joystick', 'Initialization'); Joy := TJoy.Create;
- Log.BenchmarkEnd(1);
- Log.LogBenchmark('Initializing Joystick', 1);
- end;
-
- Log.BenchmarkEnd(0);
- Log.LogBenchmark('Loading Time', 0);
-
-
- //------------------------------
- //Start- Mainloop
- //------------------------------
- //Music.SetLoop(true);
- //Music.SetVolume(50);
- //Music.Open(SkinPath + 'Menu Music 3.mp3');
- //Music.Play;
- Log.LogStatus('Main Loop', 'Initialization'); MainLoop;
-
- Log.LogStatus('Cleanup', 'Done');
-
- //------------------------------
- //Finish Application
- //------------------------------
- if Ini.LPT = 1 then LCD.Clear;
- if Ini.LPT = 2 then Light.TurnOff;
-
- // Insignificant change..
-
- Log.Free;
-end.
+program UltraStar; + +{$DEFINE TRANSLATE} + +{$IFDEF FPC} + {$MODE DELPHI} +{$ELSE} + {$R 'UltraStar.res' 'UltraStar.rc'} +{$ENDIF} + +{$I switches.inc} + +uses + + // *************************************************************************** + // + // Developers PLEASE NOTE !!!!!!! + // + // As of september 2007, I am working towards porting Ultrastar-DX to run + // on Linux. I will be modifiying the source to make it compile in lazarus + // on windows & linux and I will make sure that it compiles in delphi still + // To help me in this endevour, please can you make a point of remembering + // that linux is CASE SENSATIVE, and file / unit names must be as per + // the filename exactly. + // + // EG : opengl12.pas must not be OpenGL in the uses cluase. + // + // thanks for your help... + // + // *************************************************************************** + + // Interesting stuff... :) + // http://burningsmell.org/sdl_audioin/ + + + //------------------------------ + //Includes - 3rd Party Libraries + //------------------------------ + + // SDL / OpenGL + moduleloader in 'lib\JEDI-SDLv1.0\SDL\Pas\moduleloader.pas', + opengl12 in 'lib\JEDI-SDLv1.0\OpenGL\Pas\opengl12.pas', + sdl in 'lib\JEDI-SDLv1.0\SDL\Pas\sdl.pas', + sdl_image in 'lib\JEDI-SDLv1.0\SDL_Image\Pas\sdl_image.pas', + sdl_ttf in 'lib\JEDI-SDLv1.0\SDL_ttf\Pas\sdl_ttf.pas', + sdlutils in 'lib\JEDI-SDLv1.0\SDL\Pas\sdlutils.pas', + + + // Bass + {$IFDEF UseBASS} + bass in 'lib\bass\delphi\bass.pas', + {$ENDIF} + + // Midi Units + {$IFDEF UseMIDIPort} + Circbuf in 'lib\midi\CIRCBUF.PAS', + Delphmcb in 'lib\midi\Delphmcb.PAS', + MidiCons in 'lib\midi\MidiCons.PAS', + MidiDefs in 'lib\midi\MidiDefs.PAS', + MidiFile in 'lib\midi\MidiFile.PAS', + midiin in 'lib\midi\midiin.pas', + midiout in 'lib\midi\midiout.pas', + MidiType in 'lib\midi\MidiType.PAS', + {$ENDIF} + + // FFMpeg units + avcodec in 'lib\ffmpeg\avcodec.pas', + avformat in 'lib\ffmpeg\avformat.pas', + avio in 'lib\ffmpeg\avio.pas', + avutil in 'lib\ffmpeg\avutil.pas', + opt in 'lib\ffmpeg\opt.pas', + rational in 'lib\ffmpeg\rational.pas', + + + // Sql Lite + SQLiteTable3 in 'lib\SQLite\SQLiteTable3.pas', + SQLite3 in 'lib\SQLite\SQLite3.pas', + + + //------------------------------ + //Includes - Menu System + //------------------------------ + + UDisplay in 'Menu\UDisplay.pas', + UDrawTexture in 'Menu\UDrawTexture.pas', + UMenu in 'Menu\UMenu.pas', + UMenuButton in 'Menu\UMenuButton.pas', + UMenuButtonCollection in 'Menu\UMenuButtonCollection.pas', + UMenuInteract in 'Menu\UMenuInteract.pas', + UMenuSelect in 'Menu\UMenuSelect.pas', + UMenuSelectSlide in 'Menu\UMenuSelectSlide.pas', + UMenuStatic in 'Menu\UMenuStatic.pas', + UMenuText in 'Menu\UMenuText.pas', + + //------------------------------ + //Includes - Classes + //------------------------------ + + {$IFDEF FPC} + ulazjpeg in 'Classes\ulazjpeg.pas', + {$ENDIF} + + TextGL in 'Classes\TextGL.pas', + UCatCovers in 'Classes\UCatCovers.pas', + UCommandLine in 'Classes\UCommandLine.pas', + UCommon in 'Classes\UCommon.pas', + UCovers in 'Classes\UCovers.pas', + UDataBase in 'Classes\UDataBase.pas', + UDLLManager in 'Classes\UDLLManager.pas', + UDraw in 'Classes\UDraw.pas', + UFiles in 'Classes\UFiles.pas', + UGraphic in 'Classes\UGraphic.pas', + UGraphicClasses in 'Classes\UGraphicClasses.pas', + UIni in 'Classes\UIni.pas', + UJoystick in 'Classes\UJoystick.pas', + ULanguage in 'Classes\ULanguage.pas', + ULCD in 'Classes\ULCD.pas', + ULight in 'Classes\ULight.pas', + ULog in 'Classes\ULog.pas', + ULyrics in 'Classes\ULyrics.pas', + ULyrics_bak in 'Classes\ULyrics_bak.pas', + UMain in 'Classes\UMain.pas', + UMusic in 'Classes\UMusic.pas', + UParty in 'Classes\UParty.pas', + UPlaylist in 'Classes\UPlaylist.pas', + URecord in 'Classes\URecord.pas', + USkins in 'Classes\USkins.pas', + USingScores in 'Classes\USingScores.pas', + USongs in 'Classes\USongs.pas', + UTexture in 'Classes\UTexture.pas', + UThemes in 'Classes\UThemes.pas', + UTime in 'Classes\UTime.pas', + USingNotes in 'Classes\USingNotes.pas', + + + //------------------------------ + //Includes - Video Support + //------------------------------ + UVideo in 'Classes\UVideo.pas', + + + //------------------------------ + //Includes - Screens + //------------------------------ + UScreenCredits in 'Screens\UScreenCredits.pas', + UScreenEdit in 'Screens\UScreenEdit.pas', + UScreenEditConvert in 'Screens\UScreenEditConvert.pas', + UScreenEditHeader in 'Screens\UScreenEditHeader.pas', + UScreenEditSub in 'Screens\UScreenEditSub.pas', + UScreenLevel in 'Screens\UScreenLevel.pas', + UScreenLoading in 'Screens\UScreenLoading.pas', + UScreenMain in 'Screens\UScreenMain.pas', + UScreenName in 'Screens\UScreenName.pas', + UScreenOpen in 'Screens\UScreenOpen.pas', + UScreenOptions in 'Screens\UScreenOptions.pas', + UScreenOptionsAdvanced in 'Screens\UScreenOptionsAdvanced.pas', + UScreenOptionsGame in 'Screens\UScreenOptionsGame.pas', + UScreenOptionsGraphics in 'Screens\UScreenOptionsGraphics.pas', + UScreenOptionsLyrics in 'Screens\UScreenOptionsLyrics.pas', + UScreenOptionsRecord in 'Screens\UScreenOptionsRecord.pas', + UScreenOptionsSound in 'Screens\UScreenOptionsSound.pas', + UScreenOptionsThemes in 'Screens\UScreenOptionsThemes.pas', + UScreenPopup in 'Screens\UScreenPopup.pas', + UScreenScore in 'Screens\UScreenScore.pas', + UScreenSing in 'Screens\UScreenSing.pas', + UScreenSong in 'Screens\UScreenSong.pas', + UScreenSongJumpto in 'Screens\UScreenSongJumpto.pas', + UScreenSongMenu in 'Screens\UScreenSongMenu.pas', + UScreenStatDetail in 'Screens\UScreenStatDetail.pas', + UScreenStatMain in 'Screens\UScreenStatMain.pas', + UScreenTop5 in 'Screens\UScreenTop5.pas', + UScreenWelcome in 'Screens\UScreenWelcome.pas', + + //------------------------------ + //Includes - Screens PartyMode + //------------------------------ + UScreenPartyNewRound in 'Screens\UScreenPartyNewRound.pas', + UScreenPartyOptions in 'Screens\UScreenPartyOptions.pas', + UScreenPartyPlayer in 'Screens\UScreenPartyPlayer.pas', + UScreenPartyScore in 'Screens\UScreenPartyScore.pas', + UScreenPartyWin in 'Screens\UScreenPartyWin.pas', + UScreenSingModi in 'Screens\UScreenSingModi.pas', + + //------------------------------ + //Includes - Modi SDK + //------------------------------ + ModiSDK in '..\..\Modis\SDK\ModiSDK.pas', + + + //------------------------------ + //Includes - Delphi + //------------------------------ + {$IFDEF win32} + Windows, + {$ENDIF} + SysUtils; + +const + Version = 'UltraStar Deluxe V 1.10 Alpha Build'; + +var + WndTitle: string; + hWnd: THandle; + I: Integer; + +begin + WndTitle := Version; + + + {$ifdef Win32} + //------------------------------ + //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; + {$endif} + + //------------------------------ + //StartUp - Create Classes and Load Files + //------------------------------ + USTime := TTime.Create; + + // Commandline Parameter Parser + Params := TCMDParams.Create; + + // Log + Benchmark + Log := TLog.Create; + Log.Title := WndTitle; + Log.Enabled := Not Params.NoLog; + Log.BenchmarkStart(0); + + // 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); + + // 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; + + //Load Languagefile + if (Params.Language <> -1) then + Language.ChangeLanguage(ILanguage[Params.Language]) + else + 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; + 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.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('DataBase System', 'Initialization'); + DataBase := TDataBaseSystem.Create; + + if (Params.ScoreFile = '') then + DataBase.Init ('Ultrastar.db') + else + DataBase.Init (Params.ScoreFile); + + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading DataBase System', 1); + + //Playlist Manager + Log.BenchmarkStart(1); + Log.LogStatus('Playlist Manager', 'Initialization'); + PlaylistMan := TPlaylistManager.Create; + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading Playlist Manager', 1); + + //GoldenStarsTwinkleMod + Log.BenchmarkStart(1); + Log.LogStatus('Effect Manager', 'Initialization'); + GoldenRec := TEffectManager.Create; + Log.BenchmarkEnd(1); + Log.LogBenchmark('Loading Particel System', 1); + + // Joypad + if (Ini.Joypad = 1) OR (Params.Joypad) then begin + Log.BenchmarkStart(1); + Log.LogStatus('Initialize Joystick', 'Initialization'); Joy := TJoy.Create; + Log.BenchmarkEnd(1); + Log.LogBenchmark('Initializing Joystick', 1); + end; + + Log.BenchmarkEnd(0); + Log.LogBenchmark('Loading Time', 0); + + + //------------------------------ + //Start- Mainloop + //------------------------------ + //Music.SetLoop(true); + //Music.SetVolume(50); + //Music.Open(SkinPath + 'Menu Music 3.mp3'); + //Music.Play; + Log.LogStatus('Main Loop', 'Initialization'); MainLoop; + + Log.LogStatus('Cleanup', 'Done'); + + //------------------------------ + //Finish Application + //------------------------------ + if Ini.LPT = 1 then LCD.Clear; + if Ini.LPT = 2 then Light.TurnOff; + + // Insignificant change.. + + Log.Free; +end. diff --git a/Game/Code/UltraStar.rc b/Game/Code/UltraStar.rc index cc12eb51..4bd9145d 100644 --- a/Game/Code/UltraStar.rc +++ b/Game/Code/UltraStar.rc @@ -1,17 +1,17 @@ -Font TEX "..\Fonts\Normal\eurostar_regular.png"
-Font FNT "..\Fonts\Normal\eurostar_regular.dat"
+Font TEX "..\Fonts\Normal\eurostar_regular.png"
+Font FNT "..\Fonts\Normal\eurostar_regular.dat"
-FontB TEX "..\Fonts\Bold\eurostar_regular_bold.png"
-FontB FNT "..\Fonts\Bold\eurostar_regular_bold.dat"
+FontB TEX "..\Fonts\Bold\eurostar_regular_bold.png"
+FontB FNT "..\Fonts\Bold\eurostar_regular_bold.dat"
-FontO TEX "..\Fonts\Outline 1\Outline 1.png"
-FontO FNT "..\Fonts\Outline 1\Outline 1.dat"
+FontO TEX "..\Fonts\Outline 1\Outline 1.png"
+FontO FNT "..\Fonts\Outline 1\Outline 1.dat"
-FontO2 TEX "..\Fonts\Outline 2\Outline 2.png"
-FontO2 FNT "..\Fonts\Outline 2\Outline 2.dat"
+FontO2 TEX "..\Fonts\Outline 2\Outline 2.png"
+FontO2 FNT "..\Fonts\Outline 2\Outline 2.dat"
-MAINICON ICON "..\Graphics\ustar-icon_v01.ico"
-//MAINICON ICON "..\Graphics\us.ico"
+MAINICON ICON "..\Graphics\ustar-icon_v01.ico"
+//MAINICON ICON "..\Graphics\us.ico"
CRDTS_BG TEX "..\Graphics\credits_v5_bg.png"
CRDTS_OVL TEX "..\Graphics\credits_v5_overlay.png"
@@ -35,4 +35,4 @@ INTRO_L08 TEX "..\Graphics\intro-l-08.png" INTRO_L09 TEX "..\Graphics\intro-l-09.png"
OUTRO_BG TEX "..\Graphics\outro-bg.png"
OUTRO_ESC TEX "..\Graphics\outro-esc.png"
-OUTRO_EXD TEX "..\Graphics\outro-exit-dark.png"
\ No newline at end of file +OUTRO_EXD TEX "..\Graphics\outro-exit-dark.png" diff --git a/Game/Code/lib/requirements.txt b/Game/Code/lib/requirements.txt index 49aad6ba..e4b14060 100644 --- a/Game/Code/lib/requirements.txt +++ b/Game/Code/lib/requirements.txt @@ -37,3 +37,7 @@ ffmpeg : sqlite : sudo apt-get install libsqlite3-dev + +sdl development libraries : + sudo apt-get install libsdl-ttf2.0-dev + THERE WILL be more of them... oops I forgot to list them :P |