From b29759fbfdd8a013e3d0a85b578934ebec028c41 Mon Sep 17 00:00:00 2001 From: jaybinks Date: Tue, 2 Oct 2007 04:39:22 +0000 Subject: 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 --- Game/Code/Classes/TextGL.pas | 1108 +++---- Game/Code/Classes/UCommon.pas | 341 ++- Game/Code/Classes/UGraphic.pas | 1391 ++++----- Game/Code/Classes/UIni.pas | 22 +- Game/Code/Classes/ULyrics.pas | 1094 +++---- Game/Code/Classes/UMain.pas | 1584 +++++----- Game/Code/Classes/UMusic.pas | 1473 +++++----- Game/Code/Classes/USkins.pas | 345 +-- Game/Code/Classes/UTexture.pas | 2249 +++++++------- Game/Code/Classes/UThemes.pas | 4412 ++++++++++++++-------------- Game/Code/Classes/UTime.pas | 6 +- Game/Code/Menu/UDisplay.pas | 90 +- Game/Code/Menu/UMenu.pas | 3073 +++++++++---------- Game/Code/Screens/UScreenOptionsRecord.pas | 270 +- Game/Code/Screens/UScreenScore.pas | 1335 ++++----- Game/Code/Screens/UScreenTop5.pas | 336 +-- Game/Code/UltraStar.lpr | 856 +++--- Game/Code/UltraStar.rc | 22 +- 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 -- cgit v1.2.3