diff options
Diffstat (limited to 'cmake/src/menu')
-rw-r--r-- | cmake/src/menu/UDisplay.pas | 415 | ||||
-rw-r--r-- | cmake/src/menu/UDrawTexture.pas | 139 | ||||
-rw-r--r-- | cmake/src/menu/UMenu.pas | 1580 | ||||
-rw-r--r-- | cmake/src/menu/UMenuBackground.pas | 83 | ||||
-rw-r--r-- | cmake/src/menu/UMenuBackgroundColor.pas | 73 | ||||
-rw-r--r-- | cmake/src/menu/UMenuBackgroundFade.pas | 176 | ||||
-rw-r--r-- | cmake/src/menu/UMenuBackgroundNone.pas | 70 | ||||
-rw-r--r-- | cmake/src/menu/UMenuBackgroundTexture.pas | 125 | ||||
-rw-r--r-- | cmake/src/menu/UMenuBackgroundVideo.pas | 204 | ||||
-rw-r--r-- | cmake/src/menu/UMenuButton.pas | 601 | ||||
-rw-r--r-- | cmake/src/menu/UMenuButtonCollection.pas | 101 | ||||
-rw-r--r-- | cmake/src/menu/UMenuEqualizer.pas | 320 | ||||
-rw-r--r-- | cmake/src/menu/UMenuInteract.pas | 45 | ||||
-rw-r--r-- | cmake/src/menu/UMenuSelectSlide.pas | 388 | ||||
-rw-r--r-- | cmake/src/menu/UMenuStatic.pas | 117 | ||||
-rw-r--r-- | cmake/src/menu/UMenuText.pas | 377 |
16 files changed, 4814 insertions, 0 deletions
diff --git a/cmake/src/menu/UDisplay.pas b/cmake/src/menu/UDisplay.pas new file mode 100644 index 00000000..58c416db --- /dev/null +++ b/cmake/src/menu/UDisplay.pas @@ -0,0 +1,415 @@ +{* UltraStar Deluxe - Karaoke Game + * + * UltraStar Deluxe is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + *} + +unit UDisplay; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses + UCommon, + SDL, + UMenu, + gl, + glu, + SysUtils; + +type + TDisplay = class + private + //fade-to-black-hack + BlackScreen: boolean; + + FadeEnabled: boolean; // true if fading is enabled + FadeFailed: boolean; // true if fading is possible (enough memory, etc.) + FadeState: integer; // fading state, 0 means that the fade texture must be initialized + LastFadeTime: cardinal; // last fade update time + + FadeTex: array[1..2] of GLuint; + + FPSCounter: cardinal; + LastFPS: cardinal; + NextFPSSwap: cardinal; + + OSD_LastError: string; + + procedure DrawDebugInformation; + public + NextScreen: PMenu; + CurrentScreen: PMenu; + + //popup data + NextScreenWithCheck: Pmenu; + CheckOK: boolean; + + // FIXME: Fade is set to 0 in UMain and other files but not used here anymore. + Fade: real; + + constructor Create; + destructor Destroy; override; + + procedure SaveScreenShot; + + function Draw: boolean; + end; + +var + Display: TDisplay; + +implementation + +uses + TextGL, + UCommandLine, + UGraphic, + UIni, + UImage, + ULog, + UMain, + UTexture, + UTime, + UPath; + +constructor TDisplay.Create; +var + i: integer; +begin + inherited Create; + + //popup hack + CheckOK := false; + NextScreen := nil; + NextScreenWithCheck := nil; + BlackScreen := false; + + // fade mod + FadeState := 0; + FadeEnabled := (Ini.ScreenFade = 1); + FadeFailed:= false; + + glGenTextures(2, @FadeTex); + + for i := 1 to 2 do + begin + glBindTexture(GL_TEXTURE_2D, FadeTex[i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + end; + + //Set LastError for OSD to No Error + OSD_LastError := 'No Errors'; +end; + +destructor TDisplay.Destroy; +begin + glDeleteTextures(2, @FadeTex); + inherited Destroy; +end; + +function TDisplay.Draw: boolean; +var + S: integer; + FadeStateSquare: real; + currentTime: cardinal; + glError: glEnum; +begin + Result := true; + + //We don't need this here anymore, + //Because the background care about cleaning the buffers + //glClearColor(1, 1, 1 , 0); + //glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); + + for S := 1 to Screens do + begin + ScreenAct := S; + + //if Screens = 1 then ScreenX := 0; + //if (Screens = 2) and (S = 1) then ScreenX := -1; + //if (Screens = 2) and (S = 2) then ScreenX := 1; + ScreenX := 0; + + glViewPort((S-1) * ScreenW div Screens, 0, ScreenW div Screens, ScreenH); + + // popup hack + // check was successful... move on + if CheckOK then + begin + if assigned(NextScreenWithCheck) then + begin + NextScreen := NextScreenWithCheck; + NextScreenWithCheck := nil; + CheckOk := false; + end + else + begin + // on end of game fade to black before exit + BlackScreen := true; + end; + end; + + if (not assigned(NextScreen)) and (not BlackScreen) then + begin + CurrentScreen.Draw; + + //popup mod + if (ScreenPopupError <> nil) and ScreenPopupError.Visible then + ScreenPopupError.Draw + else if (ScreenPopupCheck <> nil) and ScreenPopupCheck.Visible then + ScreenPopupCheck.Draw; + + // fade mod + FadeState := 0; + if ((Ini.ScreenFade = 1) and (not FadeFailed)) then + FadeEnabled := true + else if (Ini.ScreenFade = 0) then + FadeEnabled := false; + end + else + begin + // disable fading if initialization failed + if (FadeEnabled and FadeFailed) then + begin + FadeEnabled := false; + end; + + if (FadeEnabled and not FadeFailed) then + begin + //Create Fading texture if we're just starting + if FadeState = 0 then + begin + // save old viewport and resize to fit texture + glPushAttrib(GL_VIEWPORT_BIT); + glViewPort(0, 0, 512, 512); + + // draw screen that will be faded + CurrentScreen.Draw; + + // clear OpenGL errors, otherwise fading might be disabled due to some + // older errors in previous OpenGL calls. + glGetError(); + + // copy screen to texture + glBindTexture(GL_TEXTURE_2D, FadeTex[S]); + glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 512, 512, 0); + glError := glGetError(); + if (glError <> GL_NO_ERROR) then + begin + FadeFailed := true; + Log.LogWarn('Fading disabled: ' + gluErrorString(glError), 'TDisplay.Draw'); + end; + + // restore viewport + glPopAttrib(); + + // blackscreen-hack + if not BlackScreen then + NextScreen.onShow; + + // update fade state + LastFadeTime := SDL_GetTicks(); + if (S = 2) or (Screens = 1) then + FadeState := FadeState + 1; + end; // end texture creation in first fading step + + //do some time-based fading + currentTime := SDL_GetTicks(); + if (currentTime > LastFadeTime+30) and (S = 1) then + begin + FadeState := FadeState + 4; + LastFadeTime := currentTime; + end; + + // blackscreen-hack + if not BlackScreen then + NextScreen.Draw // draw next screen + else if ScreenAct = 1 then + begin + glClearColor(0, 0, 0 , 0); + glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); + end; + + // and draw old screen over it... slowly fading out + + FadeStateSquare := (FadeState*FadeState)/10000; + + glBindTexture(GL_TEXTURE_2D, FadeTex[S]); + glColor4f(1, 1, 1, 1-FadeStateSquare); + + glEnable(GL_TEXTURE_2D); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glBegin(GL_QUADS); + glTexCoord2f(0+FadeStateSquare, 0+FadeStateSquare); glVertex2f(0, 600); + glTexCoord2f(0+FadeStateSquare, 1-FadeStateSquare); glVertex2f(0, 0); + glTexCoord2f(1-FadeStateSquare, 1-FadeStateSquare); glVertex2f(800, 0); + glTexCoord2f(1-FadeStateSquare, 0+FadeStateSquare); glVertex2f(800, 600); + glEnd; + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + end +// blackscreen hack + else if not BlackScreen then + begin + NextScreen.OnShow; + end; + + if ((FadeState > 40) or (not FadeEnabled) or FadeFailed) and (S = 1) then + begin + // fade out complete... + FadeState := 0; + CurrentScreen.onHide; + CurrentScreen.ShowFinish := false; + CurrentScreen := NextScreen; + NextScreen := nil; + if not BlackScreen then + begin + CurrentScreen.onShowFinish; + CurrentScreen.ShowFinish := true; + end + else + begin + Result := false; + Break; + end; + end; + end; // if + +// Draw OSD only on first Screen if Debug Mode is enabled + if ((Ini.Debug = 1) or (Params.Debug)) and (S = 1) then + DrawDebugInformation; + end; // for +end; + +procedure TDisplay.SaveScreenShot; +var + Num: integer; + FileName: string; + ScreenData: PChar; + Surface: PSDL_Surface; + Success: boolean; + Align: integer; + RowSize: integer; +begin +// Exit if Screenshot-path does not exist or read-only + if (ScreenshotsPath = '') then + Exit; + + for Num := 1 to 9999 do + begin + FileName := IntToStr(Num); + while Length(FileName) < 4 do + FileName := '0' + FileName; + FileName := ScreenshotsPath + 'screenshot' + FileName + '.png'; + if not FileExists(FileName) then + break + end; + +// we must take the row-alignment (4byte by default) into account + glGetIntegerv(GL_PACK_ALIGNMENT, @Align); +// calc aligned row-size + RowSize := ((ScreenW*3 + (Align-1)) div Align) * Align; + + GetMem(ScreenData, RowSize * ScreenH); + glReadPixels(0, 0, ScreenW, ScreenH, GL_RGB, GL_UNSIGNED_BYTE, ScreenData); +// on big endian machines (powerpc) this may need to be changed to +// Needs to be tests. KaMiSchi Sept 2008 +// in this case one may have to add " glext, " to the list of used units +// glReadPixels(0, 0, ScreenW, ScreenH, GL_BGR, GL_UNSIGNED_BYTE, ScreenData); + Surface := SDL_CreateRGBSurfaceFrom( + ScreenData, ScreenW, ScreenH, 24, RowSize, + $0000FF, $00FF00, $FF0000, 0); + +// Success := WriteJPGImage(FileName, Surface, 95); +// Success := WriteBMPImage(FileName, Surface); + Success := WritePNGImage(FileName, Surface); + if Success then + ScreenPopupError.ShowPopup('Screenshot saved: ' + ExtractFileName(FileName)) + else + ScreenPopupError.ShowPopup('Screenshot failed'); + + SDL_FreeSurface(Surface); + FreeMem(ScreenData); +end; + +//------------ +// DrawDebugInformation - Procedure draw FPS and some other Informations on Screen +//------------ +procedure TDisplay.DrawDebugInformation; +var Ticks: cardinal; +begin +// Some White Background for information + glEnable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + glColor4f(1, 1, 1, 0.5); + glBegin(GL_QUADS); + glVertex2f(690, 44); + glVertex2f(690, 0); + glVertex2f(800, 0); + glVertex2f(800, 44); + glEnd; + glDisable(GL_BLEND); + +// Set Font Specs + SetFontStyle(0); + SetFontSize(21); + SetFontItalic(false); + glColor4f(0, 0, 0, 1); + +// Calculate FPS + Ticks := SDL_GetTicks(); + if (Ticks >= NextFPSSwap) then + begin + LastFPS := FPSCounter * 4; + FPSCounter := 0; + NextFPSSwap := Ticks + 250; + end; + + Inc(FPSCounter); + +// Draw Text + +// FPS + SetFontPos(695, 0); + glPrint ('FPS: ' + InttoStr(LastFPS)); + +// RSpeed + SetFontPos(695, 13); + glPrint ('RSpeed: ' + InttoStr(Round(1000 * TimeMid))); + +// LastError + SetFontPos(695, 26); + glColor4f(1, 0, 0, 1); + glPrint (OSD_LastError); + + glColor4f(1, 1, 1, 1); +end; + +end. diff --git a/cmake/src/menu/UDrawTexture.pas b/cmake/src/menu/UDrawTexture.pas new file mode 100644 index 00000000..bc136f11 --- /dev/null +++ b/cmake/src/menu/UDrawTexture.pas @@ -0,0 +1,139 @@ +{* UltraStar Deluxe - Karaoke Game + * + * UltraStar Deluxe is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + *} + +unit UDrawTexture; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses + UTexture; + +procedure DrawLine(X1, Y1, X2, Y2, ColR, ColG, ColB: real); +procedure DrawQuad(X, Y, W, H, ColR, ColG, ColB: real); +procedure DrawTexture(Texture: TTexture); + +implementation + +uses + gl; + +procedure DrawLine(X1, Y1, X2, Y2, ColR, ColG, ColB: real); +begin + glColor3f(ColR, ColG, ColB); + glBegin(GL_LINES); + glVertex2f(x1, y1); + glVertex2f(x2, y2); + glEnd; +end; + +procedure DrawQuad(X, Y, W, H, ColR, ColG, ColB: real); +begin + glColor3f(ColR, ColG, ColB); + glBegin(GL_QUADS); + glVertex2f(x, y); + glVertex2f(x, y+h); + glVertex2f(x+w, y+h); + glVertex2f(x+w, y); + glEnd; +end; + +procedure DrawTexture(Texture: TTexture); +var + x1, x2, x3, x4: real; + y1, y2, y3, y4: real; + xt1, xt2, xt3, xt4: real; + yt1, yt2, yt3, yt4: real; +begin + with Texture do + begin + glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha); + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glDepthRange(0, 10); + glDepthFunc(GL_LEQUAL); +// glDepthFunc(GL_GEQUAL); + glEnable(GL_DEPTH_TEST); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); +// glBlendFunc(GL_SRC_COLOR, GL_ZERO); + glBindTexture(GL_TEXTURE_2D, TexNum); + + x1 := x; + x2 := x; + x3 := x+w*scaleW; + x4 := x+w*scaleW; + y1 := y; + y2 := y+h*scaleH; + y3 := y+h*scaleH; + y4 := y; + if Rot <> 0 then + begin + xt1 := x1 - (x + w/2); + xt2 := x2 - (x + w/2); + xt3 := x3 - (x + w/2); + xt4 := x4 - (x + w/2); + yt1 := y1 - (y + h/2); + yt2 := y2 - (y + h/2); + yt3 := y3 - (y + h/2); + yt4 := y4 - (y + h/2); + + x1 := (x + w/2) + xt1 * cos(Rot) - yt1 * sin(Rot); + x2 := (x + w/2) + xt2 * cos(Rot) - yt2 * sin(Rot); + x3 := (x + w/2) + xt3 * cos(Rot) - yt3 * sin(Rot); + x4 := (x + w/2) + xt4 * cos(Rot) - yt4 * sin(Rot); + + y1 := (y + h/2) + yt1 * cos(Rot) + xt1 * sin(Rot); + y2 := (y + h/2) + yt2 * cos(Rot) + xt2 * sin(Rot); + y3 := (y + h/2) + yt3 * cos(Rot) + xt3 * sin(Rot); + y4 := (y + h/2) + yt4 * cos(Rot) + xt4 * sin(Rot); + + end; + +{ + glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex3f(x1, y1, z); + glTexCoord2f(0, TexH); glVertex3f(x2, y2, z); + glTexCoord2f(TexW, TexH); glVertex3f(x3, y3, z); + glTexCoord2f(TexW, 0); glVertex3f(x4, y4, z); + glEnd; +} + + glBegin(GL_QUADS); + glTexCoord2f(TexX1*TexW, TexY1*TexH); glVertex3f(x1, y1, z); + glTexCoord2f(TexX1*TexW, TexY2*TexH); glVertex3f(x2, y2, z); + glTexCoord2f(TexX2*TexW, TexY2*TexH); glVertex3f(x3, y3, z); + glTexCoord2f(TexX2*TexW, TexY1*TexH); glVertex3f(x4, y4, z); + glEnd; + end; + glDisable(GL_DEPTH_TEST); + glDisable(GL_TEXTURE_2D); +end; + +end. diff --git a/cmake/src/menu/UMenu.pas b/cmake/src/menu/UMenu.pas new file mode 100644 index 00000000..f86746ed --- /dev/null +++ b/cmake/src/menu/UMenu.pas @@ -0,0 +1,1580 @@ +{* UltraStar Deluxe - Karaoke Game + * + * UltraStar Deluxe is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + *} + +unit UMenu; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses + gl, + SysUtils, + UTexture, + UMenuStatic, + UMenuText, + UMenuButton, + UMenuSelectSlide, + UMenuInteract, + UMenuBackground, + UThemes, + UMenuButtonCollection, + Math, + UMusic; + +type +{ Int16 = SmallInt;} + + PMenu = ^TMenu; + TMenu = class + protected + Background: TMenuBackground; + + Interactions: array of TInteract; + SelInteraction: integer; + + ButtonPos: integer; + Button: array of TButton; + + SelectsS: array of TSelectSlide; + ButtonCollection: array of TButtonCollection; + 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 + function WideCharUpperCase(wchar: WideChar) : WideString; + function WideStringUpperCase(wstring: WideString) : WideString; + 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(ThemedSettings: TThemeBackground); + + // static + function AddStatic(ThemeStatic: TThemeStatic): integer; overload; + function AddStatic(X, Y, W, H: real; const Name: string): integer; overload; + function AddStatic(X, Y, W, H: real; const Name: string; Typ: TTextureType): integer; overload; + function AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType): integer; overload; + function AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType): integer; overload; + function AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType; Color: integer): integer; overload; + function AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType; Color: integer): integer; overload; + function AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; TexX1, TexY1, TexX2, TexY2: real; const Name: string; Typ: TTextureType; Color: integer; Reflection: boolean; ReflectionSpacing: real): integer; overload; + + // text + function AddText(ThemeText: TThemeText): integer; overload; + function AddText(X, Y: real; const Text_: string): integer; overload; + function AddText(X, Y: real; Style: integer; Size, ColR, ColG, ColB: real; const Text: string): integer; overload; + function AddText(X, Y, W: real; Style: integer; Size, ColR, ColG, ColB: real; Align: integer; const Text_: string; Reflection_: boolean; ReflectionSpacing_: real; Z : real): 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; const Name: string): integer; overload; + function AddButton(X, Y, W, H: real; const Name: string; Typ: TTextureType; Reflection: boolean): integer; overload; + function AddButton(X, Y, W, H, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt: real; const Name: string; Typ: TTextureType; Reflection: boolean; ReflectionSpacing, DeSelectReflectionSpacing: real): integer; overload; + procedure ClearButtons; + procedure AddButtonText(AddX, AddY: real; const AddText: string); overload; + procedure AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; const AddText: string); overload; + procedure AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: string); overload; + procedure AddButtonText(CustomButton: TButton; AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: string); overload; + + // 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; + const Name: string; Typ: TTextureType; const SBGName: string; SBGTyp: TTextureType; + const Caption: string; var Data: integer): integer; overload; + procedure AddSelectSlideOption(const AddText: string); overload; + procedure AddSelectSlideOption(SelectNo: cardinal; const 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); overload; + procedure FadeTo(Screen: PMenu; aSound: TAudioPlaybackStream); overload; + //popup hack + procedure CheckFadeTo(Screen: PMenu; msg: string); + + function DrawBG: boolean; virtual; + function DrawFG: boolean; virtual; + function Draw: boolean; virtual; + function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown : boolean): boolean; virtual; + // FIXME: ParseMouse is not implemented in any subclass and not even used anywhere in the code + // -> do this before activation of this method + //function ParseMouse(Typ: integer; X: integer; Y: integer): boolean; virtual; abstract; + 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 InteractNextRow; virtual; // this is for the options screen, so button down makes sense + procedure InteractPrevRow; virtual; // this is for the options screen, so button up makes sense + procedure AddBox(X, Y, W, H: real); + end; + +const + pmMove = 1; + pmClick = 2; + pmUnClick = 3; + + iButton = 0; // interaction type + iText = 2; + iSelectS = 3; + iBCollectionChild = 5; + +// fBlack = 0; // fade type +// fWhite = 1; + +implementation + +uses + UCommon, + ULog, + UMain, + UDrawTexture, + UGraphic, + UDisplay, + UCovers, + UTime, + USkins, + //Background types + UMenuBackgroundNone, + UMenuBackgroundColor, + UMenuBackgroundTexture, + UMenuBackgroundVideo, + UMenuBackgroundFade; + +destructor TMenu.Destroy; +begin + if (Background <> nil) then + begin + Background.Destroy; + end; + //Log.LogError('Unloaded Succesful: ' + ClassName); + inherited; +end; + +constructor TMenu.Create; +begin + inherited; + + Fade := 0;//fWhite; + + SetLength(Static, 0); + SetLength(Button, 0); + + //Set ButtonPos to Autoset Length + ButtonPos := -1; + + Background := nil; +end; +{ +constructor TMenu.Create(Back: string); +begin + inherited Create; + + if Back <> '' then + begin +// BackImg := Texture.GetTexture(true, Back, TEXTURE_TYPE_PLAIN, 0); + BackImg := Texture.GetTexture(Back, TEXTURE_TYPE_PLAIN, 0); // new theme system + BackImg.W := 800;//640; + BackImg.H := 600;//480; + BackW := 1; + BackH := 1; + end + else + BackImg.TexNum := 0; + + //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; } + +function RGBFloatToInt(R, G, B: Double): cardinal; +begin + Result := (Trunc(255 * R) shl 16) or + (Trunc(255 * G) shl 8) or + Trunc(255 * B); +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; + 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; + 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); + + //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(ThemedSettings: TThemeBackground); + var + FileExt: string; + + function IsInArray(const Piece: string; const A: array of string): boolean; + var + I: integer; + begin + Result := false; + + for I := 0 to High(A) do + if (A[I] = Piece) then + begin + Result := true; + Exit; + end; + end; + + function TryBGCreate(Typ: cMenuBackground): boolean; + begin + Result := true; + + try + Background := Typ.Create(ThemedSettings); + except + on E: EMenuBackgroundError do + begin //Background failes to create + Freeandnil(Background); + Result := false; + end; + end; + end; + +begin + if (Background <> nil) then + begin + Background.Destroy; + Background := nil; + end; + + case ThemedSettings.BGType of + bgtAuto: begin //Automaticly choose one out of BGT_Texture, BGT_Video or BGT_Color + + if (Length(ThemedSettings.Tex) > 0) then + begin + + //At first some intelligent try to decide which BG to load + FileExt := lowercase(ExtractFileExt(Skin.GetTextureFileName(ThemedSettings.Tex))); + + if IsInArray(FileExt, SUPPORTED_EXTS_BACKGROUNDTEXTURE) then + TryBGCreate(TMenuBackgroundTexture) + else if IsInArray(FileExt, SUPPORTED_EXTS_BACKGROUNDVIDEO) then + TryBGCreate(TMenuBackgroundVideo); + + //If the intelligent method don't succeed + //do it by trial and error + if (Background = nil) then + begin + //Try Textured Bg + if not TryBGCreate(TMenuBackgroundTexture) then + TryBgCreate(TMenuBackgroundVideo); //Try Video BG + + //Color is fallback if Background = nil + end; + end; + end; + + bgtColor: begin + try + Background := TMenuBackgroundColor.Create(ThemedSettings); + except + on E: EMenuBackgroundError do + begin + Log.LogError(E.Message); + freeandnil(Background); + end; + end; + end; + + bgtTexture: begin + try + Background := TMenuBackgroundTexture.Create(ThemedSettings); + except + on E: EMenuBackgroundError do + begin + Log.LogError(E.Message); + freeandnil(Background); + end; + end; + end; + + bgtVideo: begin + try + Background := TMenuBackgroundVideo.Create(ThemedSettings); + except + on E: EMenuBackgroundError do + begin + Log.LogError(E.Message); + freeandnil(Background); + end; + end; + end; + + bgtNone: begin + try + Background := TMenuBackgroundNone.Create(ThemedSettings); + except + on E: EMenuBackgroundError do + begin + Log.LogError(E.Message); + freeandnil(Background); + end; + end; + end; + + bgtFade: begin + try + Background := TMenuBackgroundFade.Create(ThemedSettings); + except + on E: EMenuBackgroundError do + begin + Log.LogError(E.Message); + freeandnil(Background); + end; + end; + end; + end; + + //Fallback to None Background or Colored Background + if (Background = nil) then + begin + if (ThemedSettings.BGType = bgtColor) then + Background := TMenuBackgroundNone.Create(ThemedSettings) + else + Background := TMenuBackgroundColor.Create(ThemedSettings) + 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; + TempCol, TempDCol: cardinal; + +begin + if (Num > High(ButtonCollection)) then + exit; + + TempCol := 0; + + // colorize hack + if (ThemeCollection.Style.Typ = TEXTURE_TYPE_COLORIZED) then + begin + TempCol := RGBFloatToInt(ThemeCollection.Style.ColR, ThemeCollection.Style.ColG, ThemeCollection.Style.ColB); + TempDCol := RGBFloatToInt(ThemeCollection.Style.DColR, ThemeCollection.Style.DColG, ThemeCollection.Style.DColB); + // give encoded color to GetTexture() + ButtonCollection[Num] := TButtonCollection.Create( + Texture.GetTexture(Skin.GetTextureFileName(ThemeCollection.Style.Tex), TEXTURE_TYPE_COLORIZED, TempCol), + Texture.GetTexture(Skin.GetTextureFileName(ThemeCollection.Style.Tex), TEXTURE_TYPE_COLORIZED, TempDCol)); + end + else + begin + ButtonCollection[Num] := TButtonCollection.Create(Texture.GetTexture( + Skin.GetTextureFileName(ThemeCollection.Style.Tex), ThemeCollection.Style.Typ)); + end; + + //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 <> TEXTURE_TYPE_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 = TEXTURE_TYPE_COLORIZED) then + begin + ButtonCollection[Num].FadeTex := Texture.GetTexture( + Skin.GetTextureFileName(ThemeCollection.Style.FadeTex), TEXTURE_TYPE_COLORIZED, TempCol) + end + else + begin + ButtonCollection[Num].FadeTex := Texture.GetTexture( + Skin.GetTextureFileName(ThemeCollection.Style.FadeTex), ThemeCollection.Style.Typ); + end; + 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, + Skin.GetTextureFileName(ThemeStatic.Tex), + ThemeStatic.Typ, $FFFFFF, ThemeStatic.Reflection, ThemeStatic.Reflectionspacing); +end; + +function TMenu.AddStatic(X, Y, W, H: real; const Name: string): integer; +begin + Result := AddStatic(X, Y, W, H, Name, TEXTURE_TYPE_PLAIN); +end; + +function TMenu.AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType): integer; +begin + Result := AddStatic(X, Y, W, H, ColR, ColG, ColB, Name, Typ, $FFFFFF); +end; + +function TMenu.AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType): integer; +begin + Result := AddStatic(X, Y, W, H, Z, ColR, ColG, ColB, Name, Typ, $FFFFFF); +end; + +function TMenu.AddStatic(X, Y, W, H: real; const Name: string; Typ: TTextureType): integer; +var + StatNum: integer; +begin + // adds static + StatNum := Length(Static); + SetLength(Static, StatNum + 1); + Static[StatNum] := TStatic.Create(Texture.GetTexture(Name, 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; const Name: string; Typ: TTextureType; Color: integer): integer; +begin + Result := AddStatic(X, Y, W, H, 0, ColR, ColG, ColB, Name, Typ, Color); +end; + +function TMenu.AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; const Name: string; Typ: TTextureType; Color: integer): integer; +begin + Result := AddStatic(X, Y, W, H, Z, ColR, ColG, ColB, 0, 0, 1, 1, Name, Typ, Color, false, 0); +end; + +function TMenu.AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; TexX1, TexY1, TexX2, TexY2: real; const Name: string; Typ: TTextureType; Color: integer; Reflection: boolean; ReflectionSpacing: real): integer; +var + StatNum: integer; +begin + // adds static + StatNum := Length(Static); + SetLength(Static, StatNum + 1); + + // colorize hack + if (Typ = TEXTURE_TYPE_COLORIZED) then + begin + // give encoded color to GetTexture() + Static[StatNum] := TStatic.Create(Texture.GetTexture(Name, Typ, RGBFloatToInt(ColR, ColG, ColB))); + end + else + begin + Static[StatNum] := TStatic.Create(Texture.GetTexture(Name, Typ, Color)); // new skin + end; + + // 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 <> TEXTURE_TYPE_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, ThemeText.Reflection, ThemeText.ReflectionSpacing, ThemeText.Z); +end; + +function TMenu.AddText(X, Y: real; const Text_: string): integer; +var + TextNum: integer; +begin + // adds text + TextNum := Length(Text); + SetLength(Text, TextNum + 1); + Text[TextNum] := TText.Create(X, Y, Text_); + Result := TextNum; +end; + +function TMenu.AddText(X, Y: real; Style: integer; Size, ColR, ColG, ColB: real; const Text: string): integer; +begin + Result := AddText(X, Y, 0, Style, Size, ColR, ColG, ColB, 0, Text, false, 0, 0); +end; + +function TMenu.AddText(X, Y, W: real; Style: integer; Size, ColR, ColG, ColB: real; Align: integer; const Text_: string; Reflection_: boolean; ReflectionSpacing_: real; Z : real): 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, Text_, Reflection_, ReflectionSpacing_, Z); + Result := TextNum; +end; + +//Function that Set Length of Button boolean 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; +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, + Skin.GetTextureFileName(ThemeButton.Tex), 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 = TEXTURE_TYPE_COLORIZED) then + begin + Button[Result].FadeTex := Texture.GetTexture( + Skin.GetTextureFileName(ThemeButton.FadeTex), TEXTURE_TYPE_COLORIZED, + RGBFloatToInt(ThemeButton.ColR, ThemeButton.ColG, ThemeButton.ColB)); + end + else + begin + Button[Result].FadeTex := Texture.GetTexture( + Skin.GetTextureFileName(ThemeButton.FadeTex), ThemeButton.Typ); + end; + + 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; + Log.BenchmarkEnd(6); + Log.LogBenchmark('====> Screen Options32', 6); +end; + +function TMenu.AddButton(X, Y, W, H: real; const Name: string): integer; +begin + Result := AddButton(X, Y, W, H, Name, TEXTURE_TYPE_PLAIN, false); +end; + +function TMenu.AddButton(X, Y, W, H: real; const Name: string; Typ: TTextureType; Reflection: boolean): integer; +begin + Result := AddButton(X, Y, W, H, 1, 1, 1, 1, 1, 1, 1, 0.5, Name, TEXTURE_TYPE_PLAIN, Reflection, 15, 15); +end; + +function TMenu.AddButton(X, Y, W, H, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt: real; + const Name: string; Typ: TTextureType; + Reflection: boolean; ReflectionSpacing, DeSelectReflectionSpacing: real): integer; +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; + + // colorize hack + if (Typ = TEXTURE_TYPE_COLORIZED) then + begin + // give encoded color to GetTexture() + Button[Result] := TButton.Create(Texture.GetTexture(Name, Typ, RGBFloatToInt(ColR, ColG, ColB)), + Texture.GetTexture(Name, Typ, RGBFloatToInt(DColR, DColG, DColB))); + end + else + begin + Button[Result] := TButton.Create(Texture.GetTexture(Name, Typ)); + end; + + // configures button + Button[Result].X := X; + Button[Result].Y := Y; + Button[Result].W := W; + Button[Result].H := H; + if (Typ <> TEXTURE_TYPE_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; +begin + Background.Draw; + + Result := true; +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; + + 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 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; + +// implemented for the sake of usablility +// [curser down] picks the button left to the actual atm +// this behaviour doesn't make sense for two rows of buttons +procedure TMenu.InteractPrevRow; +var + Int: integer; +begin +// these two procedures just make sense for at least 5 buttons, because we +// usually start a second row when there are more than 4 buttons + Int := Interaction; + + Int := Int - ceil(Length(Interactions) / 2); + + //Set Interaction + if ((Int < 0) or (Int > Length(Interactions) - 1)) + then Int := Interaction //nonvalid button, keep current one + else Interaction := Int; //select row above +end; + +procedure TMenu.InteractNextRow; +var + Int: integer; +begin + Int := Interaction; + + Int := Int + ceil(Length(Interactions) / 2); + + //Set Interaction + if ((Int < 0) or (Int > Length(Interactions) - 1)) + then Int := Interaction //nonvalid button, keep current one + else Interaction := Int; //select row above +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 Break; + + 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 Break; + until IsSelectable(Int); + + //Set Interaction + Interaction := Int +end; + +procedure TMenu.InteractCustom(CustomSwitch: integer); +{ needed only for below +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; + +procedure TMenu.FadeTo(Screen: PMenu; aSound: TAudioPlaybackStream); +begin + FadeTo( Screen ); + AudioPlayback.PlaySound( aSound ); +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; const AddText: string); +begin + AddButtonText(AddX, AddY, 1, 1, 1, AddText); +end; + +procedure TMenu.AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; const 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; const 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; const 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.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), TEXTURE_TYPE_COLORIZED, + Skin.GetTextureFileName(ThemeSelectS.TexSBG), TEXTURE_TYPE_COLORIZED, + 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; + const Name: string; Typ: TTextureType; const SBGName: string; SBGTyp: TTextureType; + const Caption: string; var Data: integer): integer; +var + S: integer; + I: integer; +begin + S := Length(SelectsS); + SetLength(SelectsS, S + 1); + SelectsS[S] := TSelectSlide.Create; + + if (Typ = TEXTURE_TYPE_COLORIZED) then + SelectsS[S].Texture := Texture.GetTexture(Name, Typ, RGBFloatToInt(ColR, ColG, ColB)) + else + 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; + + if (SBGTyp = TEXTURE_TYPE_COLORIZED) then + SelectsS[S].TextureSBG := Texture.GetTexture(SBGName, SBGTyp, RGBFloatToInt(SBGColR, SBGColG, SBGColB)) + else + 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 := 30; + 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 := 30; + 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 := 30; + 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(const AddText: string); +begin + AddSelectSlideOption(High(SelectsS), AddText); +end; + +procedure TMenu.AddSelectSlideOption(SelectNo: cardinal; const 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; + +procedure TMenu.InteractInc; +var + Num: integer; + Value: integer; +begin + case Interactions[Interaction].Typ of + 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 + 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('MainBar'), TEXTURE_TYPE_COLORIZED); + AddStatic(X+2, Y+2, W-4, H-4, 1, 1, 1, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED); +end; + +procedure TMenu.onShow; +begin + // FIXME: this needs some work. First, there should be a variable like + // VideoBackground so we can check whether a video-background is enabled or not. + // Second, a video should be stopped if the screen is hidden, but the Video.Stop() + // method is not implemented by now. This is necessary for theme-switching too. + // At the moment videos cannot be turned off without restarting USDX. + + {// check if a background texture was found + if (BackImg.TexNum = 0) then + begin + // try to open an animated background + // Note: newer versions of ffmpeg are able to open images like jpeg + // so do not pass an image's filename to VideoPlayback.Open() + if fileexists( fFileName ) then + begin + if VideoPlayback.Open( fFileName ) then + begin + VideoBGTimer.SetTime(0); + VideoPlayback.Play; + end; + end; + end; } + if (Background = nil) then + AddBackground(DEFAULT_BACKGROUND); + + Background.OnShow; +end; + +procedure TMenu.onShowFinish; +begin + // nothing +end; + +(* + * Wrapper for WideUpperCase. Needed because some plattforms have problems with + * unicode support. + *) +function TMenu.WideCharUpperCase(wchar: WideChar) : WideString; +begin + // On Linux and MacOSX the cwstring unit is necessary for Unicode function-calls. + // Otherwise you will get an EIntOverflow exception (thrown by unimplementedwidestring()). + // The Unicode manager cwstring does not work with MacOSX at the moment because + // of missing references to iconv. So we have to use Ansi... for the moment. + + // cwstring crashes in FPC 2.2.2 so do not use the cwstring stuff + {.$IFNDEF DARWIN} + {$IFDEF NOIGNORE} + // The FPC implementation of WideUpperCase returns nil if wchar is #0 (e.g. if an arrow key is pressed) + if (wchar <> #0) then + Result := WideUpperCase(wchar) + else + Result := #0; + {$ELSE} + Result := AnsiUpperCase(wchar) + {$ENDIF} +end; + +(* + * Wrapper for WideUpperCase. Needed because some plattforms have problems with + * unicode support. + *) +function TMenu.WideStringUpperCase(wstring: WideString) : WideString; +begin + // cwstring crashes in FPC 2.2.2 so do not use the cwstring stuff + {.$IFNDEF DARWIN} + {$IFDEF NOIGNORE} + Result := WideUpperCase(wstring) + {$ELSE} + Result := AnsiUpperCase(wstring); + {$ENDIF} +end; + +procedure TMenu.onHide; +begin + // nothing + Background.OnFinish; +end; + +function TMenu.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +begin + // nothing + Result := true; +end; + +procedure TMenu.SetAnimationProgress(Progress: real); +begin + // nothing +end; + +end. + diff --git a/cmake/src/menu/UMenuBackground.pas b/cmake/src/menu/UMenuBackground.pas new file mode 100644 index 00000000..c85f0806 --- /dev/null +++ b/cmake/src/menu/UMenuBackground.pas @@ -0,0 +1,83 @@ +{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit UMenuBackground;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ SysUtils,
+ UThemes;
+
+//TMenuBackground - abstraction class for MenuBackgrounds
+//this is a class, not an interface because of the constructors
+//and destructors
+//--------
+
+type
+ EMenuBackgroundError = class(Exception);
+ TMenuBackground = class
+ constructor Create(const ThemedSettings: TThemeBackground); virtual;
+ procedure OnShow; virtual;
+ procedure Draw; virtual;
+ procedure OnFinish; virtual;
+ destructor Destroy; override;
+ end;
+ cMenuBackground = class of TMenuBackground;
+
+implementation
+
+constructor TMenuBackground.Create(const ThemedSettings: TThemeBackground);
+begin
+ inherited Create;
+end;
+
+destructor TMenuBackground.Destroy;
+begin
+ inherited;
+end;
+
+procedure TMenuBackground.OnShow;
+begin
+
+end;
+
+procedure TMenuBackground.OnFinish;
+begin
+
+end;
+
+procedure TMenuBackground.Draw;
+begin
+
+end;
+
+end.
diff --git a/cmake/src/menu/UMenuBackgroundColor.pas b/cmake/src/menu/UMenuBackgroundColor.pas new file mode 100644 index 00000000..a5c2a70a --- /dev/null +++ b/cmake/src/menu/UMenuBackgroundColor.pas @@ -0,0 +1,73 @@ +{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit UMenuBackgroundColor;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UThemes,
+ UMenuBackground;
+
+//TMenuBackgroundColor - Background Color
+//--------
+
+type
+ TMenuBackgroundColor = class (TMenuBackground)
+ private
+ Color: TRGB;
+ public
+ constructor Create(const ThemedSettings: TThemeBackground); override;
+ procedure Draw; override;
+ end;
+
+implementation
+uses
+ gl,
+ glext,
+ UGraphic;
+
+constructor TMenuBackgroundColor.Create(const ThemedSettings: TThemeBackground);
+begin
+ inherited;
+ Color := ThemedSettings.Color;
+end;
+
+procedure TMenuBackgroundColor.Draw;
+begin
+ if (ScreenAct = 1) then
+ begin //just clear once, even when using two screens
+ glClearColor(Color.R, Color.G, Color.B, 0);
+ glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+ end;
+end;
+
+end.
\ No newline at end of file diff --git a/cmake/src/menu/UMenuBackgroundFade.pas b/cmake/src/menu/UMenuBackgroundFade.pas new file mode 100644 index 00000000..b61a4542 --- /dev/null +++ b/cmake/src/menu/UMenuBackgroundFade.pas @@ -0,0 +1,176 @@ +{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit UMenuBackgroundFade;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UThemes,
+ UTexture,
+ UMenuBackground;
+
+//TMenuBackgroundFade - Background Fade In for Overlay screens
+//--------
+
+type
+ TMenuBackgroundFade = class (TMenuBackground)
+ private
+ Tex: TTexture;
+ Color: TRGB;
+ Alpha: real;
+
+ useTexture: boolean;
+
+ FadeTime: cardinal;
+ public
+ constructor Create(const ThemedSettings: TThemeBackground); override;
+ procedure OnShow; override;
+ procedure Draw; override;
+ destructor Destroy; override;
+ end;
+
+const
+ FADEINTIME = 1500; //Time the bg fades in
+
+implementation
+uses
+ sdl,
+ gl,
+ glext,
+ USkins,
+ UCommon,
+ UGraphic;
+
+constructor TMenuBackgroundFade.Create(const ThemedSettings: TThemeBackground);
+var
+ texFilename: string;
+begin
+ inherited;
+ FadeTime := 0;
+
+ Color := ThemedSettings.Color;
+ Alpha := ThemedSettings.Alpha;
+ if (Length(ThemedSettings.Tex) > 0) then
+ begin
+ texFilename := Skin.GetTextureFileName(ThemedSettings.Tex);
+ texFilename := AdaptFilePaths(texFilename);
+ Tex := Texture.GetTexture(texFilename, TEXTURE_TYPE_PLAIN);
+
+ UseTexture := (Tex.TexNum <> 0);
+ end
+ else
+ UseTexture := false;
+
+ if (not UseTexture) then
+ FreeandNil(Tex);
+end;
+
+destructor TMenuBackgroundFade.Destroy;
+begin
+ //Why isn't there any Tex.free method?
+ {if UseTexture then
+ FreeandNil(Tex); }
+ inherited;
+end;
+
+procedure TMenuBackgroundFade.OnShow;
+begin
+ FadeTime := SDL_GetTicks;
+end;
+
+procedure TMenuBackgroundFade.Draw;
+var
+ Progress: real;
+begin
+ if FadeTime = 0 then
+ Progress := Alpha
+ else
+ Progress := Alpha * (SDL_GetTicks - FadeTime) / FADEINTIME;
+
+ if Progress > Alpha then
+ begin
+ FadeTime := 0;
+ Progress := Alpha;
+ end;
+
+ if (UseTexture) then
+ begin //Draw Texture to Screen
+ if (ScreenAct = 1) then //Clear just once when in dual screen mode
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glColorRGB(Color, Progress);
+ glBindTexture(GL_TEXTURE_2D, Tex.TexNum);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(Tex.TexX1*Tex.TexW, Tex.TexY1*Tex.TexH);
+ glVertex2f(0, 0);
+
+ glTexCoord2f(Tex.TexX1*Tex.TexW, Tex.TexY2*Tex.TexH);
+ glVertex2f(0, 600);
+
+ glTexCoord2f(Tex.TexX2*Tex.TexW, Tex.TexY2*Tex.TexH);
+ glVertex2f(800, 600);
+
+ glTexCoord2f(Tex.TexX2*Tex.TexW, Tex.TexY1*Tex.TexH);
+ glVertex2f(800, 0);
+ glEnd;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+ end
+ else
+ begin //Clear Screen w/ progress Alpha + Color
+ if (ScreenAct = 1) then //Clear just once when in dual screen mode
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ glDisable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glColorRGB(Color, Progress);
+
+ glBegin(GL_QUADS);
+ glVertex2f(0, 0);
+ glVertex2f(0, 600);
+ glVertex2f(800, 600);
+ glVertex2f(800, 0);
+ glEnd;
+
+ glDisable(GL_BLEND);
+ end;
+end;
+
+end.
diff --git a/cmake/src/menu/UMenuBackgroundNone.pas b/cmake/src/menu/UMenuBackgroundNone.pas new file mode 100644 index 00000000..1fccc007 --- /dev/null +++ b/cmake/src/menu/UMenuBackgroundNone.pas @@ -0,0 +1,70 @@ +{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit UMenuBackgroundNone;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UThemes,
+ UMenuBackground;
+
+//TMenuBackgroundNone - Just no Background (e.g. for Overlays)
+//--------
+
+type
+ TMenuBackgroundNone = class (TMenuBackground)
+ private
+
+ public
+ constructor Create(const ThemedSettings: TThemeBackground); override;
+ procedure Draw; override;
+ end;
+
+implementation
+uses
+ gl,
+ glext,
+ UGraphic;
+
+constructor TMenuBackgroundNone.Create(const ThemedSettings: TThemeBackground);
+begin
+ inherited;
+end;
+
+procedure TMenuBackgroundNone.Draw;
+begin
+ //Do just nothing in here!
+ If (ScreenAct = 1) then //Clear just once when in dual screen mode
+ glClear(GL_DEPTH_BUFFER_BIT);
+end;
+
+end.
\ No newline at end of file diff --git a/cmake/src/menu/UMenuBackgroundTexture.pas b/cmake/src/menu/UMenuBackgroundTexture.pas new file mode 100644 index 00000000..a1b9e88a --- /dev/null +++ b/cmake/src/menu/UMenuBackgroundTexture.pas @@ -0,0 +1,125 @@ +{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit UMenuBackgroundTexture;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UThemes,
+ UTexture,
+ UMenuBackground;
+
+//TMenuBackgroundColor - Background Color
+//--------
+
+type
+ TMenuBackgroundTexture = class (TMenuBackground)
+ private
+ Tex: TTexture;
+ Color: TRGB;
+ public
+ constructor Create(const ThemedSettings: TThemeBackground); override;
+ procedure Draw; override;
+ destructor Destroy; override;
+ end;
+
+const
+ SUPPORTED_EXTS_BACKGROUNDTEXTURE: array[0..13] of string = ('.png', '.bmp', '.jpg', '.jpeg', '.gif', '.pnm', '.ppm', '.pgm', '.pbm', '.xpm', '.lbm', '.pcx', '.tga', '.tiff');
+
+implementation
+uses
+ USkins,
+ UCommon,
+ SysUtils,
+ gl,
+ glext,
+ UGraphic;
+
+constructor TMenuBackgroundTexture.Create(const ThemedSettings: TThemeBackground);
+var texFilename: string;
+begin
+ inherited;
+
+ if (Length(ThemedSettings.Tex) = 0) then
+ raise EMenuBackgroundError.Create('TMenuBackgroundTexture: No texture filename present');
+
+ Color := ThemedSettings.Color;
+
+ texFilename := Skin.GetTextureFileName(ThemedSettings.Tex);
+ texFilename := AdaptFilePaths(texFilename);
+ Tex := Texture.GetTexture(texFilename, TEXTURE_TYPE_PLAIN);
+
+ if (Tex.TexNum = 0) then
+ begin
+ freeandnil(Tex);
+ raise EMenuBackgroundError.Create('TMenuBackgroundTexture: Can''t load texture');
+ end;
+end;
+
+destructor TMenuBackgroundTexture.Destroy;
+begin
+ //freeandnil(Tex); <- this causes an Access Violation o0
+ inherited;
+end;
+
+procedure TMenuBackgroundTexture.Draw;
+begin
+ If (ScreenAct = 1) then //Clear just once when in dual screen mode
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ glColorRGB(Color);
+
+ glEnable(GL_TEXTURE_2D);
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+ glBindTexture(GL_TEXTURE_2D, Tex.TexNum);
+
+ glBegin(GL_QUADS);
+ glTexCoord2f(Tex.TexX1*Tex.TexW, Tex.TexY1*Tex.TexH);
+ glVertex2f(0, 0);
+
+ glTexCoord2f(Tex.TexX1*Tex.TexW, Tex.TexY2*Tex.TexH);
+ glVertex2f(0, 600);
+
+ glTexCoord2f(Tex.TexX2*Tex.TexW, Tex.TexY2*Tex.TexH);
+ glVertex2f(800, 600);
+
+ glTexCoord2f(Tex.TexX2*Tex.TexW, Tex.TexY1*Tex.TexH);
+ glVertex2f(800, 0);
+ glEnd;
+
+ glDisable(GL_BLEND);
+ glDisable(GL_TEXTURE_2D);
+end;
+
+end.
diff --git a/cmake/src/menu/UMenuBackgroundVideo.pas b/cmake/src/menu/UMenuBackgroundVideo.pas new file mode 100644 index 00000000..d1ce0f09 --- /dev/null +++ b/cmake/src/menu/UMenuBackgroundVideo.pas @@ -0,0 +1,204 @@ +{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit UMenuBackgroundVideo;
+
+interface
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+ UThemes,
+ UMenuBackground,
+ UVideo;
+
+//TMenuBackgroundColor - Background Color
+//--------
+
+type
+ //DefaultBGVideoPlayback = TVideoPlayback_FFmpeg;
+
+{type
+ TBGVideoPool = class;
+
+ PBGVideoPoolItem = ^TBGVideoPoolItem;
+ TBGVideoPoolItem = record
+ Parent: TBGVideoPool;
+ VideoPlayback = IVideoPlayback;
+ ReferenceCounter: cardinal; //Number of Creations
+ end;
+
+ TBGVideo = class
+ private
+ myItem: PBGVideoPoolItem;
+ public
+ constructor Create(Item: PBGVideoPoolItem); override;
+
+ function GetVideoPlayback: IVideoPlayback;
+ procedure Draw;
+
+ destructor Destroy;
+ end;
+
+ TBGVideoPool = class
+ private
+ Items: PBGVideoPoolItem;
+ public
+ constructor Create;
+
+ function GetBGVideo(filename: string): TBGVideo;
+ procedure RemoveItem(
+ procedure FreeAllItems;
+
+ destructor Destroy;
+ end;
+
+type }
+ TMenuBackgroundVideo = class (TMenuBackground)
+ private
+ fFilename: string;
+ public
+ constructor Create(const ThemedSettings: TThemeBackground); override;
+ procedure OnShow; override;
+ procedure Draw; override;
+ procedure OnFinish; override;
+ destructor Destroy; override;
+ end;
+
+{var
+ BGVideoPool: TBGVideoPool; }
+const
+ SUPPORTED_EXTS_BACKGROUNDVIDEO: array[0..6] of string = ('.avi', '.mov', '.divx', '.mpg', '.mp4', '.mpeg', '.m2v');
+
+implementation
+
+uses
+ gl,
+ glext,
+ UMusic,
+ SysUtils,
+ UTime,
+ USkins,
+ UCommon,
+ UGraphic;
+
+constructor TMenuBackgroundVideo.Create(const ThemedSettings: TThemeBackground);
+begin
+ inherited;
+ if (Length(ThemedSettings.Tex) = 0) then
+ raise EMenuBackgroundError.Create('TMenuBackgroundVideo: No video filename present');
+
+ fFileName := Skin.GetTextureFileName(ThemedSettings.Tex);
+ fFileName := AdaptFilePaths( fFileName );
+
+ if fileexists(fFilename) AND VideoPlayback.Open( fFileName ) then
+ begin
+ VideoBGTimer.SetTime(0);
+ VideoPlayback.Play;
+ end
+ else
+ raise EMenuBackgroundError.Create('TMenuBackgroundVideo: Can''t load background video: ' + fFilename);
+end;
+
+destructor TMenuBackgroundVideo.Destroy;
+begin
+
+end;
+
+procedure TMenuBackgroundVideo.OnShow;
+begin
+ if VideoPlayback.Open( fFileName ) then
+ begin
+ VideoBGTimer.SetTime(0);
+ VideoPlayback.Play;
+ end;
+end;
+
+procedure TMenuBackgroundVideo.OnFinish;
+begin
+
+end;
+
+procedure TMenuBackgroundVideo.Draw;
+begin
+ If (ScreenAct = 1) then //Clear just once when in dual screen mode
+ glClear(GL_DEPTH_BUFFER_BIT);
+
+ VideoPlayback.GetFrame(VideoBGTimer.GetTime());
+ // FIXME: why do we draw on screen 2? Seems to be wrong.
+ VideoPlayback.DrawGL(2);
+end;
+
+// Implementation of TBGVideo
+//--------
+{constructor TBGVideo.Create(Item: PBGVideoPoolItem);
+begin
+ myItem := PBGVideoPoolItem;
+ Inc(myItem.ReferenceCounter);
+end;
+
+destructor TBGVideo.Destroy;
+begin
+ Dec(myItem.ReferenceCounter);
+end;
+
+function TBGVideo.GetVideoPlayback: IVideoPlayback;
+begin
+
+end;
+
+procedure TBGVideo.Draw;
+begin
+
+end;
+
+// Implementation of TBGVideoPool
+//--------
+
+constructor TBGVideoPool.Create;
+begin
+
+end;
+
+destructor TBGVideoPool.Destroy;
+begin
+
+end;
+
+function TBGVideoPool.GetBGVideo(filename: string): TBGVideo;
+begin
+
+end;
+
+procedure TBGVideoPool.FreeAllItems;
+begin
+
+end; }
+
+end.
diff --git a/cmake/src/menu/UMenuButton.pas b/cmake/src/menu/UMenuButton.pas new file mode 100644 index 00000000..c6ff8ab7 --- /dev/null +++ b/cmake/src/menu/UMenuButton.pas @@ -0,0 +1,601 @@ +{* UltraStar Deluxe - Karaoke Game + * + * UltraStar Deluxe is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + *} + +unit UMenuButton; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses + TextGL, + UTexture, + gl, + UMenuText, + SDL; + +type + CButton = class of TButton; + + TButton = class + protected + SelectBool: boolean; + + FadeProgress: real; + FadeLastTick: cardinal; + + DeSelectW, + DeSelectH, + PosX, + PosY: real; + + constructor Create(); overload; + + public + Text: array of TText; + Texture: TTexture; // Button Screen position and size + Texture2: TTexture; // second texture only used for fading full resolution covers + + Colorized: boolean; + DeSelectTexture: TTexture; // texture for colorized hack + + FadeTex: TTexture; //Texture for beautiful fading + FadeTexPos: byte; //Pos of the FadeTexture (0: Top, 1: Left, 2: Bottom, 3: Right) + + DeselectType: integer; // not used yet + Visible: boolean; + + Reflection: boolean; + Reflectionspacing, + DeSelectReflectionspacing: real; + + Fade, + FadeText: boolean; + + Selectable: boolean; + + //Number of the Parent Collection, 0 if in no Collection + Parent: byte; + + SelectColR, + SelectColG, + SelectColB, + SelectInt, + SelectTInt: real; + //Fade Mod + SelectW: real; + SelectH: real; + + DeselectColR, + DeselectColG, + DeselectColB, + DeselectInt, + DeselectTInt: real; + + procedure SetY(Value: real); + procedure SetX(Value: real); + procedure SetW(Value: real); + procedure SetH(Value: real); + + procedure SetSelect(Value: boolean); virtual; + property X: real read PosX write SetX; + property Y: real read PosY write SetY; + property Z: real read Texture.z write Texture.z; + property W: real read DeSelectW write SetW; + property H: real read DeSelectH write SetH; + property Selected: boolean read SelectBool write SetSelect; + + procedure Draw; virtual; + + constructor Create(Textura: TTexture); overload; + constructor Create(Textura, DSTexture: TTexture); overload; + destructor Destroy; override; + end; + +implementation + +uses + SysUtils, + UDrawTexture; + +procedure TButton.SetX(Value: real); +{var + dx: real; + T: integer; // text} +begin + {dY := Value - Texture.y; + + Texture.X := Value; + + for T := 0 to High(Text) do + Text[T].X := Text[T].X + dY;} + + PosX := Value; + if (FadeTex.TexNum = 0) then + Texture.X := Value; + +end; + +procedure TButton.SetY(Value: real); +{var + dY: real; + T: integer; // text} +begin + {dY := Value - PosY; + + + for T := 0 to High(Text) do + Text[T].Y := Text[T].Y + dY;} + + PosY := Value; + if (FadeTex.TexNum = 0) then + Texture.y := Value; +end; + +procedure TButton.SetW(Value: real); +begin + if SelectW = DeSelectW then + SelectW := Value; + + DeSelectW := Value; + + if not Fade then + begin + if SelectBool then + Texture.W := SelectW + else + Texture.W := DeSelectW; + end; +end; + +procedure TButton.SetH(Value: real); +begin + if SelectH = DeSelectH then + SelectH := Value; + + DeSelectH := Value; + + if not Fade then + begin + if SelectBool then + Texture.H := SelectH + else + Texture.H := DeSelectH; + end; +end; + +procedure TButton.SetSelect(Value : boolean); +var + T: integer; +begin + SelectBool := Value; + + if (Value) then + begin + Texture.ColR := SelectColR; + Texture.ColG := SelectColG; + Texture.ColB := SelectColB; + Texture.Int := SelectInt; + + Texture2.ColR := SelectColR; + Texture2.ColG := SelectColG; + Texture2.ColB := SelectColB; + Texture2.Int := SelectInt; + + for T := 0 to High(Text) do + Text[T].Int := SelectTInt; + + //Fade Mod + if Fade then + begin + if (FadeProgress <= 0) then + FadeProgress := 0.125; + end + else + begin + Texture.W := SelectW; + Texture.H := SelectH; + end; + end + else + begin + Texture.ColR := DeselectColR; + Texture.ColG := DeselectColG; + Texture.ColB := DeselectColB; + Texture.Int := DeselectInt; + + Texture2.ColR := DeselectColR; + Texture2.ColG := DeselectColG; + Texture2.ColB := DeselectColB; + Texture2.Int := DeselectInt; + + for T := 0 to High(Text) do + Text[T].Int := DeselectTInt; + + //Fade Mod + if Fade then + begin + if (FadeProgress >= 1) then + FadeProgress := 0.875; + end + else + begin + Texture.W := DeSelectW; + Texture.H := DeSelectH; + end; + end; +end; + +constructor TButton.Create(); +begin + inherited Create; + // We initialize all to 0, nil or false + Visible := true; + SelectBool := false; + DeselectType := 0; + Selectable := true; + Reflection := false; + Colorized := false; + + SelectColR := 1; + SelectColG := 1; + SelectColB := 1; + SelectInt := 1; + SelectTInt := 1; + + DeselectColR := 1; + DeselectColG := 1; + DeselectColB := 1; + DeselectInt := 0.5; + DeselectTInt := 1; + + Fade := false; + FadeTex.TexNum := 0; + FadeProgress := 0; + FadeText := false; + SelectW := DeSelectW; + SelectH := DeSelectH; + + PosX := 0; + PosY := 0; + + Parent := 0; +end; + +// ***** Public methods ****** // + +procedure TButton.Draw; +var + T: integer; + Tick: cardinal; + Spacing: real; +begin + if Visible then + begin + //Fade Mod + T:=0; + if Fade then + begin + if (FadeProgress < 1) and (FadeProgress > 0) then + begin + Tick := SDL_GetTicks() div 16; + if (Tick <> FadeLastTick) then + begin + FadeLastTick := Tick; + + if SelectBool then + FadeProgress := FadeProgress + 0.125 + else + FadeProgress := FadeProgress - 0.125; + + if (FadeText) then + begin + for T := 0 to high(Text) do + begin + Text[T].MoveX := (SelectW - DeSelectW) * FadeProgress; + Text[T].MoveY := (SelectH - DeSelectH) * FadeProgress; + end; + end; + + end; + end; + + //Method without Fade Texture + if (FadeTex.TexNum = 0) then + begin + Texture.W := DeSelectW + (SelectW - DeSelectW) * FadeProgress; + Texture.H := DeSelectH + (SelectH - DeSelectH) * FadeProgress; + DeSelectTexture.W := Texture.W; + DeSelectTexture.H := Texture.H; + end + else //method with Fade Texture + begin + Texture.W := DeSelectW; + Texture.H := DeSelectH; + DeSelectTexture.W := Texture.W; + DeSelectTexture.H := Texture.H; + + FadeTex.ColR := Texture.ColR; + FadeTex.ColG := Texture.ColG; + FadeTex.ColB := Texture.ColB; + FadeTex.Int := Texture.Int; + + FadeTex.Z := Texture.Z; + + FadeTex.Alpha := Texture.Alpha; + FadeTex.TexX1 := 0; + FadeTex.TexX2 := 1; + FadeTex.TexY1 := 0; + FadeTex.TexY2 := 1; + + case FadeTexPos of + 0: //FadeTex on Top + begin + //Standard Texture + Texture.X := PosX; + Texture.Y := PosY + (SelectH - DeSelectH) * FadeProgress; + DeSelectTexture.X := Texture.X; + DeSelectTexture.Y := Texture.Y; + //Fade Tex + FadeTex.X := PosX; + FadeTex.Y := PosY; + FadeTex.W := Texture.W; + FadeTex.H := (SelectH - DeSelectH) * FadeProgress; + FadeTex.ScaleW := Texture.ScaleW; + //Some Hack that Fixes a little Space between both Textures + FadeTex.TexY2 := 0.9; + end; + 1: //FadeTex on Left + begin + //Standard Texture + Texture.X := PosX + (SelectW - DeSelectW) * FadeProgress; + Texture.Y := PosY; + DeSelectTexture.X := Texture.X; + DeSelectTexture.Y := Texture.Y; + //Fade Tex + FadeTex.X := PosX; + FadeTex.Y := PosY; + FadeTex.H := Texture.H; + FadeTex.W := (SelectW - DeSelectW) * FadeProgress; + FadeTex.ScaleH := Texture.ScaleH; + //Some Hack that Fixes a little Space between both Textures + FadeTex.TexX2 := 0.9; + end; + 2: //FadeTex on Bottom + begin + //Standard Texture + Texture.X := PosX; + Texture.Y := PosY; + DeSelectTexture.X := Texture.X; + DeSelectTexture.Y := Texture.Y; + //Fade Tex + FadeTex.X := PosX; + FadeTex.Y := PosY + (SelectH - DeSelectH) * FadeProgress;; + FadeTex.W := Texture.W; + FadeTex.H := (SelectH - DeSelectH) * FadeProgress; + FadeTex.ScaleW := Texture.ScaleW; + //Some Hack that Fixes a little Space between both Textures + FadeTex.TexY1 := 0.1; + end; + 3: //FadeTex on Right + begin + //Standard Texture + Texture.X := PosX; + Texture.Y := PosY; + DeSelectTexture.X := Texture.X; + DeSelectTexture.Y := Texture.Y; + //Fade Tex + FadeTex.X := PosX + (SelectW - DeSelectW) * FadeProgress; + FadeTex.Y := PosY; + FadeTex.H := Texture.H; + FadeTex.W := (SelectW - DeSelectW) * FadeProgress; + FadeTex.ScaleH := Texture.ScaleH; + //Some Hack that Fixes a little Space between both Textures + FadeTex.TexX1 := 0.1; + end; + end; + end; + end + else if (FadeText) then + begin + Text[T].MoveX := (SelectW - DeSelectW); + Text[T].MoveY := (SelectH - DeSelectH); + end; + + if SelectBool or (FadeProgress > 0) or not Colorized then + DrawTexture(Texture) + else + begin + DeSelectTexture.X := Texture.X; + DeSelectTexture.Y := Texture.Y; + DeSelectTexture.H := Texture.H; + DeSelectTexture.W := Texture.W; + DrawTexture(DeSelectTexture); + end; + + //Draw FadeTex + if (FadeTex.TexNum > 0) then + DrawTexture(FadeTex); + + if Texture2.Alpha > 0 then + begin + Texture2.ScaleW := Texture.ScaleW; + Texture2.ScaleH := Texture.ScaleH; + + Texture2.X := Texture.X; + Texture2.Y := Texture.Y; + Texture2.W := Texture.W; + Texture2.H := Texture.H; + + Texture2.ColR := Texture.ColR; + Texture2.ColG := Texture.ColG; + Texture2.ColB := Texture.ColB; + Texture2.Int := Texture.Int; + + Texture2.Z := Texture.Z; + + DrawTexture(Texture2); + end; + + //Reflection Mod + if (Reflection) then // Draw Reflections + begin + if (FadeProgress <> 0) and (FadeProgress <> 1) then + begin + Spacing := DeSelectReflectionspacing - (DeSelectReflectionspacing - Reflectionspacing) * FadeProgress; + end + else if SelectBool then + Spacing := Reflectionspacing + else + Spacing := DeSelectReflectionspacing; + + if SelectBool or not Colorized then + with Texture do + begin + //Bind Tex and GL Attributes + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + + glDepthRange(0, 10); + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, TexNum); + + //Draw + glBegin(GL_QUADS);//Top Left + glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3); + glTexCoord2f(TexX1*TexW, TexY2*TexH); + glVertex3f(x, y+h*scaleH+ Spacing, z); + + //Bottom Left + glColor4f(ColR * Int, ColG * Int, ColB * Int, 0); + glTexCoord2f(TexX1*TexW, TexY1+TexH*0.5); + glVertex3f(x, y+h*scaleH + h*scaleH/2 + Spacing, z); + + + //Bottom Right + glColor4f(ColR * Int, ColG * Int, ColB * Int, 0); + glTexCoord2f(TexX2*TexW, TexY1+TexH*0.5); + glVertex3f(x+w*scaleW, y+h*scaleH + h*scaleH/2 + Spacing, z); + + //Top Right + glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3); + glTexCoord2f(TexX2*TexW, TexY2*TexH); + glVertex3f(x+w*scaleW, y+h*scaleH + Spacing, z); + glEnd; + + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + end + else + with DeSelectTexture do + begin + //Bind Tex and GL Attributes + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + + glDepthRange(0, 10); + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, TexNum); + + //Draw + glBegin(GL_QUADS);//Top Left + glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3); + glTexCoord2f(TexX1*TexW, TexY2*TexH); + glVertex3f(x, y+h*scaleH+ Spacing, z); + + //Bottom Left + glColor4f(ColR * Int, ColG * Int, ColB * Int, 0); + glTexCoord2f(TexX1*TexW, TexY1+TexH*0.5); + glVertex3f(x, y+h*scaleH + h*scaleH/2 + Spacing, z); + + //Bottom Right + glColor4f(ColR * Int, ColG * Int, ColB * Int, 0); + glTexCoord2f(TexX2*TexW, TexY1+TexH*0.5); + glVertex3f(x+w*scaleW, y+h*scaleH + h*scaleH/2 + Spacing, z); + + //Top Right + glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3); + glTexCoord2f(TexX2*TexW, TexY2*TexH); + glVertex3f(x+w*scaleW, y+h*scaleH + Spacing, z); + glEnd; + + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + end; + end; + + for T := 0 to High(Text) do + begin + Text[T].Draw; + end; + end; +end; + + +destructor TButton.Destroy; +begin + inherited; +end; + +constructor TButton.Create(Textura: TTexture); +begin + Create(); + Texture := Textura; + DeSelectTexture := Textura; + Texture.ColR := 0; + Texture.ColG := 0.5; + Texture.ColB := 0; + Texture.Int := 1; + Colorized := false; +end; + +// Button has the texture-type "colorized" +// Two textures are generated, one with Col the other one with DCol +// Check UMenu.pas line 680 to see the call ( AddButton() ) +constructor TButton.Create(Textura, DSTexture: TTexture); +begin + Create(); + Texture := Textura; + DeSelectTexture := DSTexture; + Texture.ColR := 1; + Texture.ColG := 1; + Texture.ColB := 1; + Texture.Int := 1; + Colorized := true; +end; + +end. diff --git a/cmake/src/menu/UMenuButtonCollection.pas b/cmake/src/menu/UMenuButtonCollection.pas new file mode 100644 index 00000000..8b7a1c3f --- /dev/null +++ b/cmake/src/menu/UMenuButtonCollection.pas @@ -0,0 +1,101 @@ +{* UltraStar Deluxe - Karaoke Game + * + * UltraStar Deluxe is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + *} + +unit UMenuButtonCollection; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses + UMenuButton; + +type + //---------------- + //TButtonCollection + //No Extra Attributes or Functions ATM + //---------------- + AButton = array of TButton; + PAButton = ^AButton; + TButtonCollection = class(TButton) + //num of the First Button, that can be Selected + FirstChild: byte; + CountChilds: byte; + + ScreenButton: PAButton; + + procedure SetSelect(Value : boolean); override; + procedure Draw; override; + end; + +implementation + +procedure TButtonCollection.SetSelect(Value : boolean); +var + Index: integer; +begin + inherited; + + //Set Visible for Every Button that is a Child of this ButtonCollection + if (not Fade) then + for Index := 0 to High(ScreenButton^) do + if (ScreenButton^[Index].Parent = Parent) then + ScreenButton^[Index].Visible := Value; +end; + +procedure TButtonCollection.Draw; +var + I, J: integer; +begin + inherited; + //If fading is activated, Fade Child Buttons + if (Fade) then + begin + for I := 0 to High(ScreenButton^) do + if (ScreenButton^[I].Parent = Parent) then + begin + if (FadeProgress < 0.5) then + begin + ScreenButton^[I].Visible := SelectBool; + + for J := 0 to High(ScreenButton^[I].Text) do + ScreenButton^[I].Text[J].Visible := SelectBool; + end + else + begin + ScreenButton^[I].Texture.Alpha := (FadeProgress-0.666)*3; + + for J := 0 to High(ScreenButton^[I].Text) do + ScreenButton^[I].Text[J].Alpha := (FadeProgress-0.666)*3; + end; + end; + end; +end; + +end. diff --git a/cmake/src/menu/UMenuEqualizer.pas b/cmake/src/menu/UMenuEqualizer.pas new file mode 100644 index 00000000..8f57e44a --- /dev/null +++ b/cmake/src/menu/UMenuEqualizer.pas @@ -0,0 +1,320 @@ +{* UltraStar Deluxe - Karaoke Game + * + * UltraStar Deluxe is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + *} + +unit UMenuEqualizer; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses + UMusic, + UThemes; + +type + //---------------- + //Tms_Equalizer + //Class displaying an equalizer (Songscreen) + //---------------- + Tms_Equalizer = class(TObject) + private + FFTData: TFFTData; // moved here to avoid stack overflows + BandData: array of byte; + RefreshTime: cardinal; + + Source: IAudioPlayback; + + procedure Analyse; + public + X: integer; + Y: integer; + Z: real; + + W: integer; + H: integer; + Space: integer; + + Visible: boolean; + Alpha: real; + Color: TRGB; + + Direction: boolean; + BandLength: integer; + + Reflection: boolean; + Reflectionspacing: real; + + + constructor Create(Source: IAudioPlayback; mySkin: TThemeEqualizer); + + procedure Draw; + procedure SetBands(Value: byte); + function GetBands: byte; + property Bands: byte read GetBands write SetBands; + procedure SetSource(newSource: IAudioPlayback); + end; + +implementation +uses + math, + SDL, + gl, + glext; + +constructor Tms_Equalizer.Create(Source: IAudioPlayback; mySkin: TThemeEqualizer); +var + I: integer; +begin + if (Source <> nil) then + begin + X := mySkin.X; + Y := mySkin.Y; + W := mySkin.W; + H := mySkin.H; + Z := mySkin.Z; + + Space := mySkin.Space; + + Visible := mySkin.Visible; + Alpha := mySkin.Alpha; + Color.R := mySkin.ColR; + Color.G := mySkin.ColG; + Color.B := mySkin.ColB; + + Direction := mySkin.Direction; + Bands := mySkin.Bands; + BandLength := mySkin.Length; + + Reflection := mySkin.Reflection; + Reflectionspacing := mySkin.Reflectionspacing; + + Self.Source := Source; + + + //Check if Visible + if (Bands <= 0) or + (BandLength <= 0) or + (W <= 0) or + (H <= 0) or + (Alpha <= 0) then + Visible := false; + + //ClearArray + for I := low(BandData) to high(BandData) do + BandData[I] := 3; + end + else + Visible := false; +end; + +//-------- +// evaluate FFT-Data +//-------- +procedure Tms_Equalizer.Analyse; +var + I: integer; + ChansPerBand: byte; // channels per band + MaxChannel: integer; + Pos: real; + CurBand: integer; +begin + Source.GetFFTData(FFTData); + + Pos := 0; + // use only the first approx. 92 of 256 FFT-channels (approx. up to 8kHz + ChansPerBand := ceil(92 / Bands); // How much channels are used for one Band + MaxChannel := ChansPerBand * Bands - 1; + + // Change Lengths + for i := 0 to MaxChannel do + begin + // Gain higher freq. data so that the bars are visible + if i > 35 then + FFTData[i] := FFTData[i] * 8 + else if i > 11 then + FFTData[i] := FFTData[i] * 4.5 + else + FFTData[i] := FFTData[i] * 1.1; + + // clamp data + if (FFTData[i] > 1) then + FFTData[i] := 1; + + // Get max. pos + if (FFTData[i] * BandLength > Pos) then + Pos := FFTData[i] * BandLength; + + // Check if this is the last channel in the band + if ((i+1) mod ChansPerBand = 0) then + begin + CurBand := i div ChansPerBand; + + // Smooth delay if new equalizer is lower than the old one + if ((BandData[CurBand] > Pos) and (BandData[CurBand] > 1)) then + BandData[CurBand] := BandData[CurBand] - 1 + else + BandData[CurBand] := Round(Pos); + + Pos := 0; + end; + end; +end; + +//-------- +// Draw SpectrumAnalyser, Call Analyse +//-------- +procedure Tms_Equalizer.Draw; +var + CurTime: cardinal; + PosX, PosY: real; + I, J: integer; + Diff: real; + + function GetAlpha(Diff: single): single; + begin + if Direction then + Result := (Alpha * 0.6) * (0.5 - Diff/(BandLength * (H + Space))) + else + Result := (Alpha * 0.6) * (0.5 - Diff/(Bands * (H + Space))); + end; + +begin + if (Visible) and not (AudioPlayback.Finished) then + begin + //Call Analyse if necessary + CurTime := SDL_GetTicks(); + if (CurTime > RefreshTime) then + begin + Analyse; + + RefreshTime := CurTime + 44; + end; + + //Draw Equalizer Bands + // Setup OpenGL + glColorRGB(Color, Alpha); + glDisable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + + // Set position of the first equalizer bar + PosY := Y; + PosX := X; + + // Draw bars for each band + for I := 0 to High(BandData) do + begin + // Reset to lower or left position depending on the drawing-direction + if Direction then // Vertical bars + // FIXME: Is Y the upper or lower coordinate? + PosY := Y //+ (H + Space) * BandLength + else // Horizontal bars + PosX := X; + + // Draw the bar as a stack of blocks + for J := 1 to BandData[I] do + begin + // Draw block + glBegin(GL_QUADS); + glVertex3f(PosX, PosY, Z); + glVertex3f(PosX, PosY+H, Z); + glVertex3f(PosX+W, PosY+H, Z); + glVertex3f(PosX+W, PosY, Z); + glEnd; + + if (Reflection) and (J <= BandLength div 2) then + begin + Diff := (Y-PosY) + H; + + //Draw Reflection + if Direction then + begin + glBegin(GL_QUADS); + glColorRGB(Color, GetAlpha(Diff)); + glVertex3f(PosX, Diff + Y + ReflectionSpacing, Z); + + //bottom v + glColorRGB(Color, GetAlpha(Diff + H)); + glVertex3f(PosX, Diff + Y+H + ReflectionSpacing, Z); + glVertex3f(PosX+W, Diff + Y+H + ReflectionSpacing, Z); + + glColorRGB(Color, GetAlpha(Diff)); + glVertex3f(PosX+W, Diff + Y + ReflectionSpacing, Z); + glEnd; + end + else + begin + glBegin(GL_QUADS); + glColorRGB(Color, GetAlpha(Diff)); + glVertex3f(PosX, Diff + Y + (H + Space)*Bands + ReflectionSpacing, Z); + glVertex3f(PosX, Diff + Y+H + (H + Space)*Bands + ReflectionSpacing, Z); + glVertex3f(PosX+W, Diff + Y+H + (H + Space)*Bands + ReflectionSpacing, Z); + glVertex3f(PosX+W, Diff + Y + (H + Space)*Bands + ReflectionSpacing, Z); + glColorRGB(Color, GetAlpha(Diff + H)); + glEnd; + end; + + glColorRGB(Color, Alpha); + end; + + + // Calc position of the bar's next block + if Direction then // Vertical bars + PosY := PosY - H - Space + else // Horizontal bars + PosX := PosX + W + Space; + end; + + // Calc position of the next bar + if Direction then // Vertical bars + PosX := PosX + W + Space + else // Horizontal bars + PosY := PosY + H + Space; + end; + + + end; +end; + +procedure Tms_Equalizer.SetBands(Value: byte); +begin + SetLength(BandData, Value); +end; + +function Tms_Equalizer.GetBands: byte; +begin + Result := Length(BandData); +end; + +procedure Tms_Equalizer.SetSource(newSource: IAudioPlayback); +begin + if (newSource <> nil) then + Source := newSource; +end; + +end.
\ No newline at end of file diff --git a/cmake/src/menu/UMenuInteract.pas b/cmake/src/menu/UMenuInteract.pas new file mode 100644 index 00000000..beb6bcef --- /dev/null +++ b/cmake/src/menu/UMenuInteract.pas @@ -0,0 +1,45 @@ +{* UltraStar Deluxe - Karaoke Game + * + * UltraStar Deluxe is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + *} + +unit UMenuInteract; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +type + TInteract = record // for moving thru menu + Typ: integer; // 0 - button, 1 - select, 2 - Text, 3 - Select SLide, 5 - ButtonCollection Child + Num: integer; // number of this item in proper list like buttons, selects + end; + +implementation + +end. +
\ No newline at end of file diff --git a/cmake/src/menu/UMenuSelectSlide.pas b/cmake/src/menu/UMenuSelectSlide.pas new file mode 100644 index 00000000..a7133492 --- /dev/null +++ b/cmake/src/menu/UMenuSelectSlide.pas @@ -0,0 +1,388 @@ +{* UltraStar Deluxe - Karaoke Game + * + * UltraStar Deluxe is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + *} + +unit UMenuSelectSlide; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses + TextGL, + UTexture, + gl, + UMenuText; + +type + PSelectSlide = ^TSelectSlide; + TSelectSlide = class + private + SelectBool: boolean; + public + // objects + Text: TText; // Main text describing option + TextOpt: array of TText; // 3 texts in the position of possible options + TextOptT: array of string; // array of names for possible options + + Texture: TTexture; // Select Texture + TextureSBG: TTexture; // Background Selections Texture +// TextureS: array of TTexture; // Selections Texture (not used) + +// TextureArrowL: TTexture; // Texture for left arrow (not used yet) +// TextureArrowR: TTexture; // Texture for right arrow (not used yet) + + SelectOptInt: integer; + PData: ^integer; + + //For automatically Setting LineCount + Lines: byte; + + //Visibility + Visible: boolean; + + // for selection and deselection + // main static + ColR: real; + ColG: real; + ColB: real; + Int: real; + DColR: real; + DColG: real; + DColB: real; + DInt: real; + + // main text + TColR: real; + TColG: real; + TColB: real; + TInt: real; + TDColR: real; + TDColG: real; + TDColB: real; + TDInt: real; + + // selection background static + SBGColR: real; + SBGColG: real; + SBGColB: real; + SBGInt: real; + SBGDColR: real; + SBGDColG: real; + SBGDColB: real; + SBGDInt: real; + + // selection text + STColR: real; + STColG: real; + STColB: real; + STInt: real; + STDColR: real; + STDColG: real; + STDColB: real; + STDInt: real; + + // position and size + property X: real read Texture.x write Texture.x; + property Y: real read Texture.y write Texture.y; + property W: real read Texture.w write Texture.w; + property H: real read Texture.h write Texture.h; +// property X2: real read Texture2.x write Texture2.x; +// property Y2: real read Texture2.y write Texture2.y; +// property W2: real read Texture2.w write Texture2.w; +// property H2: real read Texture2.h write Texture2.h; + + property SBGW: real read TextureSBG.w write TextureSBG.w; + + // procedures + procedure SetSelect(Value: boolean); + property Selected: boolean read SelectBool write SetSelect; + procedure SetSelectOpt(Value: integer); + property SelectedOption: integer read SelectOptInt write SetSelectOpt; + procedure Draw; + constructor Create; + + //Automatically Generate Lines (Texts) + procedure genLines; + end; + +implementation +uses + UDrawTexture, + math, + ULog, + SysUtils; + +// ------------ Select +constructor TSelectSlide.Create; +begin + inherited Create; + Text := TText.Create; + SetLength(TextOpt, 1); + TextOpt[0] := TText.Create; + + //Set Standard Width for Selections Background + SBGW := 450; + + Visible := true; + {SetLength(TextOpt, 3); + TextOpt[0] := TText.Create; + TextOpt[1] := TText.Create; + TextOpt[2] := TText.Create;} +end; + +procedure TSelectSlide.SetSelect(Value: boolean); +{var + SO: integer; + I: integer;} +begin + SelectBool := Value; + if Value then + begin + Texture.ColR := ColR; + Texture.ColG := ColG; + Texture.ColB := ColB; + Texture.Int := Int; + + Text.ColR := TColR; + Text.ColG := TColG; + Text.ColB := TColB; + Text.Int := TInt; + + TextureSBG.ColR := SBGColR; + TextureSBG.ColG := SBGColG; + TextureSBG.ColB := SBGColB; + TextureSBG.Int := SBGInt; + +{ for I := 0 to High(TextOpt) do begin + TextOpt[I].ColR := STColR; + TextOpt[I].ColG := STColG; + TextOpt[I].ColB := STColB; + TextOpt[I].Int := STInt; + end;} + + end + else + begin + Texture.ColR := DColR; + Texture.ColG := DColG; + Texture.ColB := DColB; + Texture.Int := DInt; + + Text.ColR := TDColR; + Text.ColG := TDColG; + Text.ColB := TDColB; + Text.Int := TDInt; + + TextureSBG.ColR := SBGDColR; + TextureSBG.ColG := SBGDColG; + TextureSBG.ColB := SBGDColB; + TextureSBG.Int := SBGDInt; + +{ for I := 0 to High(TextOpt) do begin + TextOpt[I].ColR := STDColR; + TextOpt[I].ColG := STDColG; + TextOpt[I].ColB := STDColB; + TextOpt[I].Int := STDInt; + end;} + end; +end; + +procedure TSelectSlide.SetSelectOpt(Value: integer); +var + SO: integer; + HalfL: integer; + HalfR: integer; + +procedure DoSelection(Sel: cardinal); + var + I: integer; + begin + for I := low(TextOpt) to high(TextOpt) do + begin + TextOpt[I].ColR := STDColR; + TextOpt[I].ColG := STDColG; + TextOpt[I].ColB := STDColB; + TextOpt[I].Int := STDInt; + end; + if (integer(Sel) <= high(TextOpt)) then + begin + TextOpt[Sel].ColR := STColR; + TextOpt[Sel].ColG := STColG; + TextOpt[Sel].ColB := STColB; + TextOpt[Sel].Int := STInt; + end; + end; +begin + SelectOptInt := Value; + PData^ := Value; +// SetSelect(true); // reset all colors + + if (Length(TextOpt)>0) AND (Length(TextOptT)>0) then + begin + + if (Value <= 0) then + begin //First Option Selected + Value := 0; + + for SO := low (TextOpt) to high(TextOpt) do + begin + TextOpt[SO].Text := TextOptT[SO]; + end; + + DoSelection(0); + end + else if (Value >= high(TextOptT)) then + begin //Last Option Selected + Value := high(TextOptT); + + for SO := high(TextOpt) downto low (TextOpt) do + begin + TextOpt[SO].Text := TextOptT[high(TextOptT)-(Lines-SO-1)]; + end; + DoSelection(Lines-1); + end + else + begin + HalfL := Ceil((Lines-1)/2); + HalfR := Lines-1-HalfL; + + if (Value <= HalfL) then + begin //Selected Option is near to the left side + {HalfL := Value; + HalfR := Lines-1-HalfL;} + //Change Texts + for SO := low (TextOpt) to high(TextOpt) do + begin + TextOpt[SO].Text := TextOptT[SO]; + end; + + DoSelection(Value); + end + else if (Value > High(TextOptT)-HalfR) then + begin //Selected is too near to the right border + HalfR := high(TextOptT) - Value; + HalfL := Lines-1-HalfR; + //Change Texts + for SO := high(TextOpt) downto low (TextOpt) do + begin + TextOpt[SO].Text := TextOptT[high(TextOptT)-(Lines-SO-1)]; + end; + + DoSelection (HalfL); + end + else + begin + //Change Texts + for SO := low (TextOpt) to high(TextOpt) do + begin + TextOpt[SO].Text := TextOptT[Value - HalfL + SO]; + end; + + DoSelection(HalfL); + end; + + end; + + end; + +end; + +procedure TSelectSlide.Draw; +var + SO: integer; +begin + if Visible then + begin + DrawTexture(Texture); + DrawTexture(TextureSBG); + + Text.Draw; + + for SO := low(TextOpt) to high(TextOpt) do + TextOpt[SO].Draw; + end; +end; + +procedure TSelectSlide.GenLines; +var + maxlength: real; + I: integer; +begin + SetFontStyle(0{Text.Style}); + SetFontSize(Text.Size); + maxlength := 0; + + for I := low(TextOptT) to high (TextOptT) do + begin + if (glTextWidth(TextOptT[I]) > maxlength) then + maxlength := glTextWidth(TextOptT[I]); + end; + + Lines := floor((TextureSBG.W-40) / (maxlength+7)); + if (Lines > Length(TextOptT)) then + Lines := Length(TextOptT); + + if (Lines <= 0) then + Lines := 1; + + //Free old Space used by Texts + for I := low(TextOpt) to high(TextOpt) do + TextOpt[I].Free; + + setLength (TextOpt, Lines); + + for I := low(TextOpt) to high(TextOpt) do + begin + TextOpt[I] := TText.Create; + TextOpt[I].Size := Text.Size; + //TextOpt[I].Align := 1; + TextOpt[I].Align := 0; + TextOpt[I].Visible := true; + + TextOpt[I].ColR := STDColR; + TextOpt[I].ColG := STDColG; + TextOpt[I].ColB := STDColB; + TextOpt[I].Int := STDInt; + + //Generate Positions + //TextOpt[I].X := TextureSBG.X + 20 + (TextureSBG.W / Lines) * (I + 0.5); + if (I <> High(TextOpt)) OR (High(TextOpt) = 0) OR (Length(TextOptT) = Lines) then + TextOpt[I].X := TextureSBG.X + 20 + (TextureSBG.W / Lines) * I + else + TextOpt[I].X := TextureSBG.X + TextureSBG.W - maxlength; + + TextOpt[I].Y := TextureSBG.Y + (TextureSBG.H - Text.Size) / 2; + + //Better Look with 2 Options + if (Lines=2) AND (Length(TextOptT)= 2) then + TextOpt[I].X := TextureSBG.X + 20 + (TextureSBG.W -40 - glTextWidth(TextOptT[1])) * I; + end; +end; + +end. diff --git a/cmake/src/menu/UMenuStatic.pas b/cmake/src/menu/UMenuStatic.pas new file mode 100644 index 00000000..72f4eb36 --- /dev/null +++ b/cmake/src/menu/UMenuStatic.pas @@ -0,0 +1,117 @@ +{* UltraStar Deluxe - Karaoke Game + * + * UltraStar Deluxe is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + *} + +unit UMenuStatic; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses + UTexture, + gl; + +type + TStatic = class + public + Texture: TTexture; // Button Screen position and size + Visible: boolean; + + //Reflection Mod + Reflection: boolean; + Reflectionspacing: real; + + procedure Draw; + constructor Create(Textura: TTexture); overload; + end; + +implementation +uses + UDrawTexture; + +procedure TStatic.Draw; +begin + if Visible then + begin + DrawTexture(Texture); + + //Reflection Mod + if (Reflection) then // Draw Reflections + begin + with Texture do + begin + //Bind Tex and GL Attributes + glEnable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + + glDepthRange(0, 10); + glDepthFunc(GL_LEQUAL); + glEnable(GL_DEPTH_TEST); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBindTexture(GL_TEXTURE_2D, TexNum); + + //Draw + glBegin(GL_QUADS);//Top Left + glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3); + glTexCoord2f(TexX1*TexW, TexY2*TexH); + glVertex3f(x, y+h*scaleH+ Reflectionspacing, z); + + //Bottom Left + glColor4f(ColR * Int, ColG * Int, ColB * Int, 0); + glTexCoord2f(TexX1*TexW, 0.5*TexH+TexY1); + glVertex3f(x, y+h*scaleH + h*scaleH/2 + Reflectionspacing, z); + + + //Bottom Right + glColor4f(ColR * Int, ColG * Int, ColB * Int, 0); + glTexCoord2f(TexX2*TexW, 0.5*TexH+TexY1); + glVertex3f(x+w*scaleW, y+h*scaleH + h*scaleH/2 + Reflectionspacing, z); + + //Top Right + glColor4f(ColR * Int, ColG * Int, ColB * Int, Alpha-0.3); + glTexCoord2f(TexX2*TexW, TexY2*TexH); + glVertex3f(x+w*scaleW, y+h*scaleH + Reflectionspacing, z); + glEnd; + + glDisable(GL_TEXTURE_2D); + glDisable(GL_DEPTH_TEST); + glDisable(GL_BLEND); + end; + end; + end; +end; + +constructor TStatic.Create(Textura: TTexture); +begin + inherited Create; + Texture := Textura; +end; + +end. diff --git a/cmake/src/menu/UMenuText.pas b/cmake/src/menu/UMenuText.pas new file mode 100644 index 00000000..6cf53200 --- /dev/null +++ b/cmake/src/menu/UMenuText.pas @@ -0,0 +1,377 @@ +{* UltraStar Deluxe - Karaoke Game + * + * UltraStar Deluxe is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + *} + +unit UMenuText; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses + TextGL, + UTexture, + gl, + math, + SysUtils, + SDL; + +type + TText = class + private + SelectBool: boolean; + TextString: string; + TextTiles: array of string; + + STicks: Cardinal; + SelectBlink: boolean; + public + X: real; + Y: real; + Z: real; + MoveX: real; //Some Modifier for X - Position that don't affect the real Y + MoveY: real; //Some Modifier for Y - Position that don't affect the real Y + W: real; //text wider than W is broken +// H: real; + Size: real; + ColR: real; + ColG: real; + ColB: real; + Alpha: real; + Int: real; + Style: integer; + Visible: boolean; + Align: integer; // 0 = left, 1 = center, 2 = right + + //Reflection + Reflection: boolean; + ReflectionSpacing: real; + + procedure SetSelect(Value: boolean); + property Selected: boolean read SelectBool write SetSelect; + + procedure SetText(Value: string); + property Text: string read TextString write SetText; + + procedure DeleteLastL; //Procedure to Delete Last Letter + + procedure Draw; + constructor Create; overload; + constructor Create(X, Y: real; Text: string); overload; + constructor Create(ParX, ParY, ParW: real; ParStyle: integer; ParSize, ParColR, ParColG, ParColB: real; ParAlign: integer; ParText: string; ParReflection: boolean; ParReflectionSpacing: real; ParZ: real); overload; + end; + +implementation + +uses UGraphic, + StrUtils; + +procedure TText.SetSelect(Value: boolean); +begin + SelectBool := Value; + + //Set Cursor Visible + SelectBlink := True; + STicks := SDL_GetTicks() div 550; +end; + +procedure TText.SetText(Value: string); +var + NextPos: cardinal; // NextPos of a Space etc. + LastPos: cardinal; // LastPos " + LastBreak: cardinal; // Last Break + isBreak: boolean; // True if the Break is not Caused because the Text is out of the area + FirstWord: word; // Is First Word after Break? + Len: word; // Length of the Tiles Array + + function GetNextPos: boolean; + var + T1, {T2,} T3: cardinal; + begin + LastPos := NextPos; + + //Next Space (If Width is given) + if (W > 0) then + T1 := PosEx(' ', Value, LastPos + 1) + else + T1 := Length(Value); + + {//Next - + T2 := PosEx('-', Value, LastPos + 1);} + + //Next Break + T3 := PosEx('\n', Value, LastPos + 1); + + if T1 = 0 then + T1 := Length(Value); + {if T2 = 0 then + T2 := Length(Value); } + if T3 = 0 then + T3 := Length(Value); + + //Get Nearest Pos + NextPos := min(T1, T3{min(T2, T3)}); + + if (LastPos = cardinal(Length(Value))) then + NextPos := 0; + + isBreak := (NextPos = T3) and (NextPos <> cardinal(Length(Value))); + Result := (NextPos <> 0); + end; + + procedure AddBreak(const From, bTo: cardinal); + begin + if (isBreak) or (bTo - From >= 1) then + begin + Inc(Len); + SetLength (TextTiles, Len); + TextTiles[Len-1] := Trim(Copy(Value, From, bTo - From)); + + if isBreak then + LastBreak := bTo + 2 + else + LastBreak := bTo + 1; + FirstWord := 0; + end; + end; + +begin + //Set TExtstring + TextString := Value; + + //Set Cursor Visible + SelectBlink := True; + STicks := SDL_GetTicks() div 550; + + //Exit if there is no Need to Create Tiles + if (W <= 0) and (Pos('\n', Value) = 0) then + begin + SetLength (TextTiles, 1); + TextTiles[0] := Value; + Exit; + end; + + //Create Tiles + //Reset Text Array + SetLength (TextTiles, 0); + Len := 0; + + //Reset Counter Vars + LastPos := 1; + NextPos := 1; + LastBreak := 1; + FirstWord := 1; + + if (W > 0) then + begin + //Set Font Properties + SetFontStyle(Style); + SetFontSize(Size); + end; + + //go Through Text + while (GetNextPos) do + begin + //Break in Text + if isBreak then + begin + //Look for Break before the Break + if (glTextWidth(Copy(Value, LastBreak, NextPos - LastBreak + 1)) > W) AND (NextPos-LastPos > 1) then + begin + isBreak := False; + //Not the First word after Break, so we don't have to break within a word + if (FirstWord > 1) then + begin + //Add Break before actual Position, because there the Text fits the Area + AddBreak(LastBreak, LastPos); + end + else //First Word after Break Break within the Word + begin + //ToDo + //AddBreak(LastBreak, LastBreak + 155); + end; + end; + + isBreak := True; + //Add Break from Text + AddBreak(LastBreak, NextPos); + end + //Text comes out of the Text Area -> CreateBreak + else if (glTextWidth(Copy(Value, LastBreak, NextPos - LastBreak + 1)) > W) then + begin + //Not the First word after Break, so we don't have to break within a word + if (FirstWord > 1) then + begin + //Add Break before actual Position, because there the Text fits the Area + AddBreak(LastBreak, LastPos); + end + else //First Word after Break -> Break within the Word + begin + //ToDo + //AddBreak(LastBreak, LastBreak + 155); + end; + end; + //end; + Inc(FirstWord) + end; + //Add Ending + AddBreak(LastBreak, Length(Value)+1); +end; + +procedure TText.DeleteLastL; +var + S: string; + L: integer; +begin + S := TextString; + L := Length(S); + if (L > 0) then + SetLength(S, L-1); + + SetText(S); +end; + +procedure TText.Draw; +var + X2, Y2: real; + Text2: string; + I: cardinal; +begin + if Visible then + begin + SetFontStyle(Style); + SetFontSize(Size); + SetFontItalic(False); + + glColor4f(ColR*Int, ColG*Int, ColB*Int, Alpha); + + //Reflection + if Reflection = true then + SetFontReflection(true, ReflectionSpacing) + else + SetFontReflection(false,0); + + //if selected set blink... + if SelectBool then + begin + I := SDL_GetTicks() div 550; + if I <> STicks then + begin //Change Visability + STicks := I; + SelectBlink := Not SelectBlink; + end; + end; + + {if (False) then //no width set draw as one long string + begin + if not (SelectBool AND SelectBlink) then + Text2 := Text + else + Text2 := Text + '|'; + + case Align of + 0: X2 := X; + 1: X2 := X - glTextWidth(Text2)/2; + 2: X2 := X - glTextWidth(Text2); + end; + + SetFontPos(X2, Y); + glPrint(Text2); + SetFontStyle(0); // reset to default + end + else + begin} + //now use allways: + //draw text as many strings + Y2 := Y + MoveY; + for I := 0 to high(TextTiles) do + begin + if (not (SelectBool and SelectBlink)) or (I <> cardinal(high(TextTiles))) then + Text2 := TextTiles[I] + else + Text2 := TextTiles[I] + '|'; + + case Align of + 0: X2 := X + MoveX; + 1: X2 := X + MoveX - glTextWidth(Text2)/2; + 2: X2 := X + MoveX - glTextWidth(Text2); + end; + + SetFontPos(X2, Y2); + + SetFontZ(Z); + + glPrint(Text2); + + {if Size >= 10 then + Y2 := Y2 + Size * 0.93 + else} + if (Style = 1) then + Y2 := Y2 + Size * 0.93 + else + Y2 := Y2 + Size * 0.72; + end; + SetFontStyle(0); // reset to default + + //end; + end; +end; + +constructor TText.Create; +begin + Create(0, 0, ''); +end; + +constructor TText.Create(X, Y: real; Text: string); +begin + Create(X, Y, 0, 0, 30, 0, 0, 0, 0, Text, false, 0, 0); +end; + +constructor TText.Create(ParX, ParY, ParW: real; ParStyle: integer; ParSize, ParColR, ParColG, ParColB: real; ParAlign: integer; ParText: string; ParReflection: boolean; ParReflectionSpacing: real; ParZ:real); +begin + inherited Create; + Alpha := 1; + X := ParX; + Y := ParY; + W := ParW; + Z := ParZ; + Style := ParStyle; + Size := ParSize; + Text := ParText; + ColR := ParColR; + ColG := ParColG; + ColB := ParColB; + Int := 1; + Align := ParAlign; + SelectBool := false; + Visible := true; + Reflection:= ParReflection; + ReflectionSpacing:= ParReflectionSpacing; +end; + +end. |