From 678cc132f942ff4d84a803550eedf96acc543bca Mon Sep 17 00:00:00 2001 From: tobigun Date: Sun, 23 May 2010 09:07:15 +0000 Subject: update to trunk rev. 2391 git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/experimental@2401 b956fd51-792f-4845-bead-9b4dfca2ff2c --- cmake/src/menu/UDisplay.pas | 389 ++++++++++++++++------- cmake/src/menu/UMenu.pas | 508 ++++++++++++++++-------------- cmake/src/menu/UMenuBackground.pas | 166 +++++----- cmake/src/menu/UMenuBackgroundColor.pas | 144 ++++----- cmake/src/menu/UMenuBackgroundFade.pas | 352 ++++++++++----------- cmake/src/menu/UMenuBackgroundNone.pas | 138 ++++---- cmake/src/menu/UMenuBackgroundTexture.pas | 251 +++++++-------- cmake/src/menu/UMenuBackgroundVideo.pas | 415 ++++++++++++------------ cmake/src/menu/UMenuButton.pas | 48 ++- cmake/src/menu/UMenuInteract.pas | 9 + cmake/src/menu/UMenuSelectSlide.pas | 217 ++++++++++--- cmake/src/menu/UMenuText.pas | 57 ++-- 12 files changed, 1537 insertions(+), 1157 deletions(-) (limited to 'cmake/src/menu') diff --git a/cmake/src/menu/UDisplay.pas b/cmake/src/menu/UDisplay.pas index f2eb2ced..e3ec272a 100644 --- a/cmake/src/menu/UDisplay.pas +++ b/cmake/src/menu/UDisplay.pas @@ -35,24 +35,32 @@ interface uses UCommon, + Math, SDL, - UMenu, gl, glu, - SysUtils; + SysUtils, + UMenu, + UPath, + UMusic, + UHookableEvent; type TDisplay = class private + ePreDraw: THookableEvent; + eDraw: THookableEvent; + //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 + FadeTime: cardinal; // time when fading starts, 0 means that the fade texture must be initialized + DoneOnShow: boolean; // true if passed onShow after fading - FadeTex: array[1..2] of GLuint; + FadeTex: array[0..1] of GLuint; + TexW, TexH: Cardinal; FPSCounter: cardinal; LastFPS: cardinal; @@ -72,6 +80,9 @@ type Cursor_Fade: boolean; procedure DrawDebugInformation; + + { called by MoveCursor and OnMouseButton to update last move and start fade in } + procedure UpdateCursorFade; public NextScreen: PMenu; CurrentScreen: PMenu; @@ -86,17 +97,29 @@ type constructor Create; destructor Destroy; override; + procedure InitFadeTextures(); + procedure SaveScreenShot; function Draw: boolean; + { calls ParseInput of cur or next Screen if assigned } + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown : boolean): boolean; + { sets SDL_ShowCursor depending on options set in Ini } procedure SetCursor; { called when cursor moves, positioning of software cursor } - procedure MoveCursor(X, Y: double; Pressed: boolean); + procedure MoveCursor(X, Y: double); + + { called when left or right mousebutton is pressed or released } + procedure OnMouseButton(Pressed: boolean); + { fades to specific screen (playing specified sound) } + function FadeTo(Screen: PMenu; const aSound: TAudioPlaybackStream = nil): PMenu; + + { abort fading to the current screen, may be used in OnShow, or during fade process } + procedure AbortScreenChange; - { draws software cursor } procedure DrawCursor; end; @@ -105,6 +128,9 @@ var Display: TDisplay; const + { constants for screen transition + time in milliseconds } + Transition_Fade_Time = 400; { constants for software cursor effects time in milliseconds } Cursor_FadeIn_Time = 500; // seconds the fade in effect lasts @@ -123,14 +149,17 @@ uses UMain, UTexture, UTime, - UPath; + ULanguage, + UPathUtils; constructor TDisplay.Create; -var - i: integer; begin inherited Create; + // create events for plugins + ePreDraw := THookableEvent.Create('Display.PreDraw'); + eDraw := THookableEvent.Create('Display.Draw'); + //popup hack CheckOK := false; NextScreen := nil; @@ -138,18 +167,13 @@ begin BlackScreen := false; // fade mod - FadeState := 0; + FadeTime := 0; FadeEnabled := (Ini.ScreenFade = 1); FadeFailed := false; + DoneOnShow := 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; + glGenTextures(2, PGLuint(@FadeTex)); + InitFadeTextures(); //Set LastError for OSD to No Error OSD_LastError := 'No Errors'; @@ -166,16 +190,35 @@ end; destructor TDisplay.Destroy; begin - glDeleteTextures(2, @FadeTex); + glDeleteTextures(2, @FadeTex); inherited Destroy; end; +procedure TDisplay.InitFadeTextures(); +var + i: integer; +begin + TexW := Round(Power(2, Ceil(Log2(ScreenW div Screens)))); + TexH := Round(Power(2, Ceil(Log2(ScreenH)))); + + for i := 0 to 1 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); + glTexImage2D(GL_TEXTURE_2D, 0, 3, TexW, TexH, 0, GL_RGB, GL_UNSIGNED_BYTE, nil); + end; +end; + function TDisplay.Draw: boolean; var S: integer; FadeStateSquare: real; + FadeW, FadeH: real; + FadeCopyW, FadeCopyH: integer; currentTime: cardinal; glError: glEnum; + begin Result := true; @@ -214,20 +257,25 @@ begin if (not assigned(NextScreen)) and (not BlackScreen) then begin + ePreDraw.CallHookChain(false); CurrentScreen.Draw; //popup mod if (ScreenPopupError <> nil) and ScreenPopupError.Visible then ScreenPopupError.Draw + else if (ScreenPopupInfo <> nil) and ScreenPopupInfo.Visible then + ScreenPopupInfo.Draw else if (ScreenPopupCheck <> nil) and ScreenPopupCheck.Visible then ScreenPopupCheck.Draw; // fade mod - FadeState := 0; + FadeTime := 0; if ((Ini.ScreenFade = 1) and (not FadeFailed)) then FadeEnabled := true else if (Ini.ScreenFade = 0) then FadeEnabled := false; + + eDraw.CallHookChain(false); end else begin @@ -240,95 +288,129 @@ begin if (FadeEnabled and not FadeFailed) then begin //Create Fading texture if we're just starting - if FadeState = 0 then + if FadeTime = 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 + ePreDraw.CallHookChain(false); CurrentScreen.Draw; + eDraw.CallHookChain(false); // clear OpenGL errors, otherwise fading might be disabled due to some // older errors in previous OpenGL calls. glGetError(); + FadeCopyW := ScreenW div Screens; + FadeCopyH := ScreenH; + + // it is possible that our fade textures are too small after a window + // resize. In that case resize the fade texture to fit the requirements. + if (TexW < FadeCopyW) or (TexH < FadeCopyH) then + InitFadeTextures(); + // copy screen to texture - glBindTexture(GL_TEXTURE_2D, FadeTex[S]); - glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, 512, 512, 0); + glBindTexture(GL_TEXTURE_2D, FadeTex[S-1]); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, (S-1) * ScreenW div Screens, 0, + FadeCopyW, FadeCopyH); + glError := glGetError(); if (glError <> GL_NO_ERROR) then begin FadeFailed := true; - Log.LogWarn('Fading disabled: ' + gluErrorString(glError), 'TDisplay.Draw'); + Log.LogError('Fading disabled: ' + gluErrorString(glError), 'TDisplay.Draw'); end; - // restore viewport - glPopAttrib(); - // blackscreen-hack - if not BlackScreen then - NextScreen.onShow; + if not BlackScreen and (S = 1) and not DoneOnShow then + begin + NextScreen.OnShow; + DoneOnShow := true; + end; - // update fade state - LastFadeTime := SDL_GetTicks(); - if (S = 2) or (Screens = 1) then - FadeState := FadeState + 1; + + // set fade time once on second screen (or first if screens = 1) + if (Screens = 1) or (S = 2) then + FadeTime := SDL_GetTicks; end; // end texture creation in first fading step - //do some time-based fading + {//do some time-based fading currentTime := SDL_GetTicks(); if (currentTime > LastFadeTime+30) and (S = 1) then begin - FadeState := FadeState + 4; + FadeState := FadeState + 5; LastFadeTime := currentTime; - end; + end; } // blackscreen-hack if not BlackScreen then - NextScreen.Draw // draw next screen + begin + ePreDraw.CallHookChain(false); + NextScreen.Draw; // draw next screen + eDraw.CallHookChain(false); + end else if ScreenAct = 1 then begin - glClearColor(0, 0, 0 , 0); + glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); end; // and draw old screen over it... slowly fading out + if (FadeTime = 0) then + FadeStateSquare := 0 // for first screen if screens = 2 + else + FadeStateSquare := sqr((SDL_GetTicks - FadeTime) / Transition_Fade_Time); - 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); + if (FadeStateSquare < 1) then + begin + FadeW := (ScreenW div Screens)/TexW; + FadeH := ScreenH/TexH; + + glBindTexture(GL_TEXTURE_2D, FadeTex[S-1]); + // TODO: check if glTexEnvi() gives any speed improvement + //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + 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/2)*FadeW, (0+FadeStateSquare/2)*FadeH); + glVertex2f(0, RenderH); + + glTexCoord2f((0+FadeStateSquare/2)*FadeW, (1-FadeStateSquare/2)*FadeH); + glVertex2f(0, 0); + + glTexCoord2f((1-FadeStateSquare/2)*FadeW, (1-FadeStateSquare/2)*FadeH); + glVertex2f(RenderW, 0); + + glTexCoord2f((1-FadeStateSquare/2)*FadeW, (0+FadeStateSquare/2)*FadeH); + glVertex2f(RenderW, RenderH); + glEnd; + glDisable(GL_BLEND); + glDisable(GL_TEXTURE_2D); + + // reset to default + //glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + end; end -// blackscreen hack + + // blackscreen hack else if not BlackScreen then begin NextScreen.OnShow; end; - if ((FadeState > 40) or (not FadeEnabled) or FadeFailed) and (S = 1) then + if ((FadeTime + Transition_Fade_Time < SDL_GetTicks) or (not FadeEnabled) or FadeFailed) and ((Screens = 1) or (S = 2)) then begin // fade out complete... - FadeState := 0; + FadeTime := 0; + DoneOnShow := false; CurrentScreen.onHide; CurrentScreen.ShowFinish := false; CurrentScreen := NextScreen; NextScreen := nil; if not BlackScreen then begin - CurrentScreen.onShowFinish; + CurrentScreen.OnShowFinish; CurrentScreen.ShowFinish := true; end else @@ -341,11 +423,11 @@ begin // 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 + DrawDebugInformation; - if not BlackScreen then - DrawCursor; + if not BlackScreen then + DrawCursor; + end; // for end; { sets SDL_ShowCursor depending on options set in Ini } @@ -392,35 +474,51 @@ begin end; end; -{ called when cursor moves, positioning of software cursor } -procedure TDisplay.MoveCursor(X, Y: double; Pressed: boolean); +{ called by MoveCursor and OnMouseButton to update last move and start fade in } +procedure TDisplay.UpdateCursorFade; var Ticks: cardinal; begin - if (Ini.Mouse = 2) and - ((X <> Cursor_X) or (Y <> Cursor_Y) or (Pressed <> Cursor_Pressed)) then + Ticks := SDL_GetTicks; + + { fade in on movement (or button press) if not first movement } + if (not Cursor_Visible) and (Cursor_LastMove <> 0) then + begin + if Cursor_Fade then // we use a trick here to consider progress of fade out + Cursor_LastMove := Ticks - round(Cursor_FadeIn_Time * (1 - (Ticks - Cursor_LastMove)/Cursor_FadeOut_Time)) + else + Cursor_LastMove := Ticks; + + Cursor_Visible := true; + Cursor_Fade := true; + end + else if not Cursor_Fade then + begin + Cursor_LastMove := Ticks; + end; +end; + +{ called when cursor moves, positioning of software cursor } +procedure TDisplay.MoveCursor(X, Y: double); +begin + if (Ini.Mouse = 2) and + ((X <> Cursor_X) or (Y <> Cursor_Y)) then begin Cursor_X := X; Cursor_Y := Y; - Cursor_Pressed := Pressed; - Ticks := SDL_GetTicks; + UpdateCursorFade; + end; +end; - { fade in on movement (or button press) if not first movement } - if (not Cursor_Visible) and (Cursor_LastMove <> 0) then - begin - if Cursor_Fade then // we use a trick here to consider progress of fade out - Cursor_LastMove := Ticks - round(Cursor_FadeIn_Time * (1 - (Ticks - Cursor_LastMove)/Cursor_FadeOut_Time)) - else - Cursor_LastMove := Ticks; +{ called when left or right mousebutton is pressed or released } +procedure TDisplay.OnMouseButton(Pressed: boolean); +begin + if (Ini.Mouse = 2) then + begin + Cursor_Pressed := Pressed; - Cursor_Visible := true; - Cursor_Fade := true; - end - else if not Cursor_Fade then - begin - Cursor_LastMove := Ticks; - end; + UpdateCursorFade; end; end; @@ -429,8 +527,9 @@ procedure TDisplay.DrawCursor; var Alpha: single; Ticks: cardinal; + DrawX: double; begin - if (Ini.Mouse = 2) then + if (Ini.Mouse = 2) and ((Screens = 1) or ((ScreenAct - 1) = (Round(Cursor_X+16) div RenderW))) then begin // draw software cursor Ticks := SDL_GetTicks; @@ -471,6 +570,9 @@ begin if (Alpha > 0) and (not Cursor_HiddenByScreen) then begin + DrawX := Cursor_X; + if (ScreenAct = 2) then + DrawX := DrawX - RenderW; glColor4f(1, 1, 1, Alpha); glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); @@ -483,16 +585,16 @@ begin glBegin(GL_QUADS); glTexCoord2f(0, 0); - glVertex2f(Cursor_X, Cursor_Y); + glVertex2f(DrawX, Cursor_Y); glTexCoord2f(0, 1); - glVertex2f(Cursor_X, Cursor_Y + 32); + glVertex2f(DrawX, Cursor_Y + 32); glTexCoord2f(1, 1); - glVertex2f(Cursor_X + 32, Cursor_Y + 32); + glVertex2f(DrawX + 32, Cursor_Y + 32); glTexCoord2f(1, 0); - glVertex2f(Cursor_X + 32, Cursor_Y); + glVertex2f(DrawX + 32, Cursor_Y); glEnd; glDisable(GL_BLEND); @@ -501,52 +603,101 @@ begin end; end; +function TDisplay.ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown : boolean): boolean; +begin + if (assigned(NextScreen)) then + Result := NextScreen^.ParseInput(PressedKey, CharCode, PressedDown) + else if (assigned(CurrentScreen)) then + Result := CurrentScreen^.ParseInput(PressedKey, CharCode, PressedDown) + else + Result := True; +end; + +{ abort fading to the next screen, may be used in OnShow, or during fade process } +procedure TDisplay.AbortScreenChange; + var + Temp: PMenu; +begin + // this is some kind of "hack" it is based on the + // code that is used to change the screens in TDisplay.Draw + // we should rewrite this whole behaviour, as it is not well + // structured and not well extendable. Also we should offer + // a possibility to change screens to plugins + // change this code when restructuring is done + if (assigned(NextScreen)) then + begin + // we have to swap the screens + Temp := CurrentScreen; + CurrentScreen := NextScreen; + NextScreen := Temp; + + // and call the OnShow procedure of the previous screen + // because it was already called by default fade procedure + NextScreen.OnShow; + + end; +end; + +{ fades to specific screen (playing specified sound) + returns old screen } +function TDisplay.FadeTo(Screen: PMenu; const aSound: TAudioPlaybackStream = nil): PMenu; +begin + Result := CurrentScreen; + if (Result <> nil) then + begin + if (aSound <> nil) then + Result.FadeTo(Screen, aSound) + else + Result.FadeTo(Screen); + end; +end; + procedure TDisplay.SaveScreenShot; var Num: integer; - FileName: string; + FileName: IPath; + Prefix: UTF8String; 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 if Screenshot-path does not exist or read-only + if (ScreenshotsPath.IsUnset) 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 + // fill prefix to 4 digits with leading '0', e.g. '0001' + Prefix := Format('screenshot%.4d', [Num]); + FileName := ScreenshotsPath.Append(Prefix + '.png'); + if not FileName.Exists() then + break; end; -// we must take the row-alignment (4byte by default) into account + // we must take the row-alignment (4byte by default) into account glGetIntegerv(GL_PACK_ALIGNMENT, @Align); -// calc aligned row-size + // 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); + // 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 := WriteJPGImage(FileName, Surface, 95); + // Success := WriteBMPImage(FileName, Surface); Success := WritePNGImage(FileName, Surface); if Success then - ScreenPopupError.ShowPopup('Screenshot saved: ' + ExtractFileName(FileName)) + ScreenPopupInfo.ShowPopup(Format(Language.Translate('SCREENSHOT_SAVED'), [FileName.GetName.ToUTF8()])) else - ScreenPopupError.ShowPopup('Screenshot failed'); + ScreenPopupError.ShowPopup(Language.Translate('SCREENSHOT_FAILED')); SDL_FreeSurface(Surface); FreeMem(ScreenData); @@ -559,7 +710,7 @@ procedure TDisplay.DrawDebugInformation; var Ticks: cardinal; begin -// Some White Background for information + // Some White Background for information glEnable(GL_BLEND); glDisable(GL_TEXTURE_2D); glColor4f(1, 1, 1, 0.5); @@ -571,13 +722,13 @@ begin glEnd; glDisable(GL_BLEND); -// set font specs - SetFontStyle(0); + // set font specs + SetFontStyle(ftNormal); SetFontSize(21); SetFontItalic(false); glColor4f(0, 0, 0, 1); -// calculate fps + // calculate fps Ticks := SDL_GetTicks(); if (Ticks >= NextFPSSwap) then begin @@ -588,17 +739,17 @@ begin Inc(FPSCounter); -// draw text + // draw text -// fps + // fps SetFontPos(695, 0); glPrint ('FPS: ' + InttoStr(LastFPS)); -// rspeed + // rspeed SetFontPos(695, 13); glPrint ('RSpeed: ' + InttoStr(Round(1000 * TimeMid))); -// lasterror + // lasterror SetFontPos(695, 26); glColor4f(1, 0, 0, 1); glPrint (OSD_LastError); diff --git a/cmake/src/menu/UMenu.pas b/cmake/src/menu/UMenu.pas index a3f47b3d..b011eddf 100644 --- a/cmake/src/menu/UMenu.pas +++ b/cmake/src/menu/UMenu.pas @@ -38,6 +38,7 @@ uses Math, gl, SDL, + UPath, UMenuBackground, UMenuButton, UMenuButtonCollection, @@ -67,7 +68,7 @@ type ButtonCollection: array of TButtonCollection; public Text: array of TText; - Static: array of TStatic; + Statics: array of TStatic; mX: integer; // mouse X mY: integer; // mouse Y @@ -81,8 +82,6 @@ type //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); virtual; property Interaction: integer read SelInteraction write SetInteraction; @@ -98,62 +97,62 @@ type // 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; + function AddStatic(X, Y, W, H: real; const TexName: IPath): integer; overload; + function AddStatic(X, Y, W, H: real; const TexName: IPath; Typ: TTextureType): integer; overload; + function AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; const TexName: IPath; Typ: TTextureType): integer; overload; + function AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; const TexName: IPath; Typ: TTextureType): integer; overload; + function AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; const TexName: IPath; Typ: TTextureType; Color: integer): integer; overload; + function AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; const TexName: IPath; Typ: TTextureType; Color: integer): integer; overload; + function AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; TexX1, TexY1, TexX2, TexY2: real; const TexName: IPath; 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; + function AddText(X, Y: real; const Text_: UTF8String): integer; overload; + function AddText(X, Y: real; Style: integer; Size, ColR, ColG, ColB: real; const Text: UTF8String): integer; overload; + function AddText(X, Y, W: real; Style: integer; Size, ColR, ColG, ColB: real; Align: integer; const Text_: UTF8String; 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; + function AddButton(X, Y, W, H: real; const TexName: IPath): integer; overload; + function AddButton(X, Y, W, H: real; const TexName: IPath; Typ: TTextureType; Reflection: boolean): integer; overload; + function AddButton(X, Y, W, H, ColR, ColG, ColB, Int, DColR, DColG, DColB, DInt: real; const TexName: IPath; 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; + procedure AddButtonText(AddX, AddY: real; const AddText: UTF8String); overload; + procedure AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; const AddText: UTF8String); overload; + procedure AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: UTF8String); overload; + procedure AddButtonText(CustomButton: TButton; AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: UTF8String); overload; // select slide - function AddSelectSlide(ThemeSelectS: TThemeSelectSlide; var Data: integer; Values: array of string): integer; overload; + function AddSelectSlide(ThemeSelectS: TThemeSelectSlide; var Data: integer; const Values: array of UTF8String): 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); + const TexName: IPath; Typ: TTextureType; const SBGName: IPath; SBGTyp: TTextureType; + const Caption: UTF8String; var Data: integer): integer; overload; + procedure AddSelectSlideOption(const AddText: UTF8String); overload; + procedure AddSelectSlideOption(SelectNo: cardinal; const AddText: UTF8String); overload; + procedure UpdateSelectSlideOptions(ThemeSelectSlide: TThemeSelectSlide; SelectNum: integer; const Values: array of UTF8String; 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); + procedure CheckFadeTo(Screen: PMenu; Msg: UTF8String); function DrawBG: boolean; virtual; function DrawFG: boolean; virtual; function Draw: boolean; virtual; - function ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown : boolean): boolean; virtual; + function ParseInput(PressedKey: cardinal; CharCode: UCS4Char; PressedDown : boolean): boolean; virtual; function ParseMouse(MouseButton: integer; BtnDown: boolean; X, Y: integer): boolean; virtual; - function InRegion(X1, Y1, W, H, X, Y: real): boolean; + function InRegion(X, Y: real; A: TMouseOverRect): boolean; function InteractAt(X, Y: real): integer; function CollectionAt(X, Y: real): integer; - procedure onShow; virtual; - procedure onShowFinish; virtual; - procedure onHide; virtual; + procedure OnShow; virtual; + procedure OnShowFinish; virtual; + procedure OnHide; virtual; procedure SetAnimationProgress(Progress: real); virtual; @@ -169,6 +168,8 @@ type procedure AddBox(X, Y, W, H: real); end; +function RGBFloatToInt(R, G, B: double): cardinal; + const MENU_MDOWN = 8; MENU_MUP = 0; @@ -205,11 +206,22 @@ uses UMenuBackgroundFade; destructor TMenu.Destroy; +var + I: integer; begin - if (Background <> nil) then - begin - Background.Destroy; - end; + for I := 0 to High(Button) do + Button[I].Free; + for I := 0 to High(ButtonCollection) do + ButtonCollection[I].Free; + for I := 0 to High(SelectsS) do + SelectsS[I].Free; + for I := 0 to High(Text) do + Text[I].Free; + for I := 0 to High(Statics) do + Statics[I].Free; + + Background.Free; + //Log.LogError('Unloaded Succesful: ' + ClassName); inherited; end; @@ -220,7 +232,7 @@ begin Fade := 0;//fWhite; - SetLength(Static, 0); + SetLength(Statics, 0); SetLength(Button, 0); //Set ButtonPos to Autoset Length @@ -337,8 +349,8 @@ begin 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.Statics) do + AddStatic(ThemeBasic.Statics[I]); for I := 0 to High(ThemeBasic.Text) do AddText(ThemeBasic.Text[I]); @@ -378,11 +390,7 @@ procedure TMenu.AddBackground(ThemedSettings: TThemeBackground); end; begin - if (Background <> nil) then - begin - Background.Destroy; - Background := nil; - end; + FreeAndNil(Background); case ThemedSettings.BGType of bgtAuto: begin //Automaticly choose one out of BGT_Texture, BGT_Video or BGT_Color @@ -391,7 +399,7 @@ begin begin //At first some intelligent try to decide which BG to load - FileExt := lowercase(ExtractFileExt(Skin.GetTextureFileName(ThemedSettings.Tex))); + FileExt := LowerCase(Skin.GetTextureFileName(ThemedSettings.Tex).GetExtension.ToUTF8); if IsInArray(FileExt, SUPPORTED_EXTS_BACKGROUNDTEXTURE) then TryBGCreate(TMenuBackgroundTexture) @@ -599,69 +607,69 @@ begin ThemeStatic.Typ, $FFFFFF, ThemeStatic.Reflection, ThemeStatic.Reflectionspacing); end; -function TMenu.AddStatic(X, Y, W, H: real; const Name: string): integer; +function TMenu.AddStatic(X, Y, W, H: real; const TexName: IPath): integer; begin - Result := AddStatic(X, Y, W, H, Name, TEXTURE_TYPE_PLAIN); + Result := AddStatic(X, Y, W, H, TexName, TEXTURE_TYPE_PLAIN); end; function TMenu.AddStatic(X, Y, W, H: real; - ColR, ColG, ColB: real; - const Name: string; + ColR, ColG, ColB: real; + const TexName: IPath; Typ: TTextureType): integer; begin - Result := AddStatic(X, Y, W, H, ColR, ColG, ColB, Name, Typ, $FFFFFF); + Result := AddStatic(X, Y, W, H, ColR, ColG, ColB, TexName, Typ, $FFFFFF); end; function TMenu.AddStatic(X, Y, W, H, Z: real; - ColR, ColG, ColB: real; - const Name: string; + ColR, ColG, ColB: real; + const TexName: IPath; Typ: TTextureType): integer; begin - Result := AddStatic(X, Y, W, H, Z, ColR, ColG, ColB, Name, Typ, $FFFFFF); + Result := AddStatic(X, Y, W, H, Z, ColR, ColG, ColB, TexName, Typ, $FFFFFF); end; function TMenu.AddStatic(X, Y, W, H: real; - const Name: string; + const TexName: IPath; 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 + StatNum := Length(Statics); + SetLength(Statics, StatNum + 1); + Statics[StatNum] := TStatic.Create(Texture.GetTexture(TexName, 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; + Statics[StatNum].Texture.X := X; + Statics[StatNum].Texture.Y := Y; + Statics[StatNum].Texture.W := W; + Statics[StatNum].Texture.H := H; + Statics[StatNum].Visible := true; Result := StatNum; end; function TMenu.AddStatic(X, Y, W, H: real; ColR, ColG, ColB: real; - const Name: string; + const TexName: IPath; Typ: TTextureType; Color: integer): integer; begin - Result := AddStatic(X, Y, W, H, 0, ColR, ColG, ColB, Name, Typ, Color); + Result := AddStatic(X, Y, W, H, 0, ColR, ColG, ColB, TexName, Typ, Color); end; function TMenu.AddStatic(X, Y, W, H, Z: real; ColR, ColG, ColB: real; - const Name: string; + const TexName: IPath; 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); + Result := AddStatic(X, Y, W, H, Z, ColR, ColG, ColB, 0, 0, 1, 1, TexName, 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; + const TexName: IPath; Typ: TTextureType; Color: integer; Reflection: boolean; @@ -670,52 +678,52 @@ var StatNum: integer; begin // adds static - StatNum := Length(Static); - SetLength(Static, StatNum + 1); + StatNum := Length(Statics); + SetLength(Statics, 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))); + Statics[StatNum] := TStatic.Create(Texture.GetTexture(TexName, Typ, RGBFloatToInt(ColR, ColG, ColB))); end else begin - Static[StatNum] := TStatic.Create(Texture.GetTexture(Name, Typ, Color)); // new skin + Statics[StatNum] := TStatic.Create(Texture.GetTexture(TexName, Typ, Color)); // new skin end; // configures static - Static[StatNum].Texture.X := X; - Static[StatNum].Texture.Y := Y; + Statics[StatNum].Texture.X := X; + Statics[StatNum].Texture.Y := Y; //Set height and width via sprite size if omitted if(H = 0) then - Static[StatNum].Texture.H := Static[StatNum].Texture.H + Statics[StatNum].Texture.H := Statics[StatNum].Texture.H else - Static[StatNum].Texture.H := H; + Statics[StatNum].Texture.H := H; if(W = 0) then - Static[StatNum].Texture.W := Static[StatNum].Texture.W + Statics[StatNum].Texture.W := Statics[StatNum].Texture.W else - Static[StatNum].Texture.W := W; + Statics[StatNum].Texture.W := W; - Static[StatNum].Texture.Z := Z; + Statics[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; + Statics[StatNum].Texture.ColR := ColR; + Statics[StatNum].Texture.ColG := ColG; + Statics[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; + Statics[StatNum].Texture.TexX1 := TexX1; + Statics[StatNum].Texture.TexY1 := TexY1; + Statics[StatNum].Texture.TexX2 := TexX2; + Statics[StatNum].Texture.TexY2 := TexY2; + Statics[StatNum].Texture.Alpha := 1; + Statics[StatNum].Visible := true; //ReflectionMod - Static[StatNum].Reflection := Reflection; - Static[StatNum].ReflectionSpacing := ReflectionSpacing; + Statics[StatNum].Reflection := Reflection; + Statics[StatNum].ReflectionSpacing := ReflectionSpacing; Result := StatNum; end; @@ -726,7 +734,7 @@ begin 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; +function TMenu.AddText(X, Y: real; const Text_: UTF8String): integer; var TextNum: integer; begin @@ -739,20 +747,20 @@ end; function TMenu.AddText(X, Y: real; Style: integer; - Size, ColR, ColG, ColB: real - ; const Text: string): integer; + Size, ColR, ColG, ColB: real; + const Text: UTF8String): 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; + Size, ColR, ColG, ColB: real; + Align: integer; + const Text_: UTF8String; + Reflection_: boolean; + ReflectionSpacing_: real; + Z : real): integer; var TextNum: integer; begin @@ -839,22 +847,20 @@ begin 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; +function TMenu.AddButton(X, Y, W, H: real; const TexName: IPath): integer; begin - Result := AddButton(X, Y, W, H, Name, TEXTURE_TYPE_PLAIN, false); + Result := AddButton(X, Y, W, H, TexName, TEXTURE_TYPE_PLAIN, false); end; -function TMenu.AddButton(X, Y, W, H: real; const Name: string; Typ: TTextureType; Reflection: boolean): integer; +function TMenu.AddButton(X, Y, W, H: real; const TexName: IPath; 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); + Result := AddButton(X, Y, W, H, 1, 1, 1, 1, 1, 1, 1, 0.5, TexName, 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; + const TexName: IPath; Typ: TTextureType; Reflection: boolean; ReflectionSpacing, DeSelectReflectionSpacing: real): integer; @@ -876,12 +882,12 @@ begin 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))); + Button[Result] := TButton.Create(Texture.GetTexture(TexName, Typ, RGBFloatToInt(ColR, ColG, ColB)), + Texture.GetTexture(TexName, Typ, RGBFloatToInt(DColR, DColG, DColB))); end else begin - Button[Result] := TButton.Create(Texture.GetTexture(Name, Typ)); + Button[Result] := TButton.Create(Texture.GetTexture(TexName, Typ)); end; // configures button @@ -935,11 +941,11 @@ 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; + for J := 0 to High(Statics) do + Statics[J].Draw; // ... and slightly implemented menutext unit - for J := 0 to Length(Text) - 1 do + for J := 0 to High(Text) do Text[J].Draw; // Draw all ButtonCollections @@ -947,10 +953,10 @@ begin ButtonCollection[J].Draw; // Second, we draw all of our buttons - for J := 0 to Length(Button) - 1 do + for J := 0 to High(Button) do Button[J].Draw; - for J := 0 to Length(SelectsS) - 1 do + for J := 0 to High(SelectsS) do SelectsS[J].Draw; // Third, we draw all our widgets @@ -1178,21 +1184,41 @@ begin AudioPlayback.PlaySound( aSound ); end; +procedure OnSaveEncodingError(Value: boolean; Data: Pointer); +begin + Display.CheckOK := Value; + if (Value) then + begin + //Hack to Finish Singscreen correct on Exit with Q Shortcut + if (Display.NextScreenWithCheck = nil) then + begin + if (Display.CurrentScreen = @ScreenSing) then + ScreenSing.Finish + {else if (Display.CurrentScreen = @ScreenSingModi) then + ScreenSingModi.Finish;} + end; + end + else + begin + Display.NextScreenWithCheck := nil; + end; +end; + //popup hack -procedure TMenu.CheckFadeTo(Screen: PMenu; msg: string); +procedure TMenu.CheckFadeTo(Screen: PMenu; Msg: UTF8String); begin Display.Fade := 0; Display.NextScreenWithCheck := Screen; Display.CheckOK := false; - ScreenPopupCheck.ShowPopup(msg); + ScreenPopupCheck.ShowPopup(msg, OnSaveEncodingError, nil, false); end; -procedure TMenu.AddButtonText(AddX, AddY: real; const AddText: string); +procedure TMenu.AddButtonText(AddX, AddY: real; const AddText: UTF8String); begin AddButtonText(AddX, AddY, 1, 1, 1, AddText); end; -procedure TMenu.AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; const AddText: string); +procedure TMenu.AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; const AddText: UTF8String); var Il: integer; begin @@ -1208,7 +1234,7 @@ begin end; end; -procedure TMenu.AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: string); +procedure TMenu.AddButtonText(AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: UTF8String); var Il: integer; begin @@ -1227,7 +1253,7 @@ begin end; end; -procedure TMenu.AddButtonText(CustomButton: TButton; AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: string); +procedure TMenu.AddButtonText(CustomButton: TButton; AddX, AddY: real; ColR, ColG, ColB: real; Font: integer; Size: integer; Align: integer; const AddText: UTF8String); var Il: integer; begin @@ -1246,7 +1272,7 @@ begin end; end; -function TMenu.AddSelectSlide(ThemeSelectS: TThemeSelectSlide; var Data: integer; Values: array of string): integer; +function TMenu.AddSelectSlide(ThemeSelectS: TThemeSelectSlide; var Data: integer; const Values: array of UTF8String): integer; var SO: integer; begin @@ -1259,8 +1285,8 @@ begin 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, + Skin.GetTextureFileName(ThemeSelectS.Tex), ThemeSelectS.Typ, + Skin.GetTextureFileName(ThemeSelectS.TexSBG), ThemeSelectS.TypSBG, ThemeSelectS.Text, Data); for SO := 0 to High(Values) do AddSelectSlideOption(Values[SO]); @@ -1269,6 +1295,8 @@ begin SelectsS[High(SelectsS)].Texture.Z := ThemeSelectS.Z; SelectsS[High(SelectsS)].TextureSBG.Z := ThemeSelectS.Z; + SelectsS[High(SelectsS)].Tex_SelectS_ArrowL.Z := ThemeSelectS.Z; + SelectsS[High(SelectsS)].Tex_SelectS_ArrowR.Z := ThemeSelectS.Z; SelectsS[High(SelectsS)].showArrows := ThemeSelectS.showArrows; SelectsS[High(SelectsS)].oneItemOnly := ThemeSelectS.oneItemOnly; @@ -1283,8 +1311,8 @@ function TMenu.AddSelectSlide(X, Y, W, H, SkipX, SBGW, ColR, ColG, ColB, Int, DC 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; + const TexName: IPath; Typ: TTextureType; const SBGName: IPath; SBGTyp: TTextureType; + const Caption: UTF8String; var Data: integer): integer; var S: integer; I: integer; @@ -1294,37 +1322,67 @@ begin SelectsS[S] := TSelectSlide.Create; if (Typ = TEXTURE_TYPE_COLORIZED) then - SelectsS[S].Texture := Texture.GetTexture(Name, Typ, RGBFloatToInt(ColR, ColG, ColB)) + begin + SelectsS[S].Colorized := true; + SelectsS[S].Texture := Texture.GetTexture(TexName, Typ, RGBFloatToInt(ColR, ColG, ColB)); + SelectsS[S].DeselectTexture := Texture.GetTexture(TexName, Typ, RGBFloatToInt(DColR, DColG, DColB)); + end else - SelectsS[S].Texture := Texture.GetTexture(Name, Typ); + begin + SelectsS[S].Colorized := false; + SelectsS[S].Texture := Texture.GetTexture(TexName, Typ); + + SelectsS[S].ColR := ColR; + SelectsS[S].ColG := ColG; + SelectsS[S].ColB := ColB; + + SelectsS[S].DColR := DColR; + SelectsS[S].DColG := DColG; + SelectsS[S].DColB := DColB; + end; + + SelectsS[S].Int := Int; + SelectsS[S].DInt := DInt; + SelectsS[S].X := X; SelectsS[S].Y := Y; SelectsS[S].W := W; - SelectsS[S].H := H; - - SelectsS[S].ColR := ColR; - SelectsS[S].ColG := ColG; - SelectsS[S].ColB := ColB; - SelectsS[S].Int := Int; - SelectsS[S].DColR := DColR; - SelectsS[S].DColG := DColG; - SelectsS[S].DColB := DColB; - SelectsS[S].DInt := DInt; + SelectsS[S].H := H; if (SBGTyp = TEXTURE_TYPE_COLORIZED) then - SelectsS[S].TextureSBG := Texture.GetTexture(SBGName, SBGTyp, RGBFloatToInt(SBGColR, SBGColG, SBGColB)) + begin + SelectsS[S].ColorizedSBG := true; + SelectsS[S].TextureSBG := Texture.GetTexture(SBGName, SBGTyp, RGBFloatToInt(SBGColR, SBGColG, SBGColB)); + SelectsS[S].DeselectTextureSBG := Texture.GetTexture(SBGName, SBGTyp, RGBFloatToInt(SBGDColR, SBGDColG, SBGDColB)); + end else + begin + SelectsS[S].ColorizedSBG := false; SelectsS[S].TextureSBG := Texture.GetTexture(SBGName, SBGTyp); + SelectsS[S].SBGColR := SBGColR; + SelectsS[S].SBGColG := SBGColG; + SelectsS[S].SBGColB := SBGColB; + + SelectsS[S].SBGDColR := SBGDColR; + SelectsS[S].SBGDColG := SBGDColG; + SelectsS[S].SBGDColB := SBGDColB; + end; + + + SelectsS[S].SBGInt := SBGInt; + SelectsS[S].SBGDInt := SBGDInt; + SelectsS[High(SelectsS)].Tex_SelectS_ArrowL := Tex_SelectS_ArrowL; SelectsS[High(SelectsS)].Tex_SelectS_ArrowL.X := X + W + SkipX; - SelectsS[High(SelectsS)].Tex_SelectS_ArrowL.Y := Y; + SelectsS[High(SelectsS)].Tex_SelectS_ArrowL.Y := Y + (H - Tex_SelectS_ArrowL.H) / 2; SelectsS[High(SelectsS)].Tex_SelectS_ArrowL.W := Tex_SelectS_ArrowL.W; SelectsS[High(SelectsS)].Tex_SelectS_ArrowL.H := Tex_SelectS_ArrowL.H; + SelectsS[High(SelectsS)].Tex_SelectS_ArrowR := Tex_SelectS_ArrowR; SelectsS[High(SelectsS)].Tex_SelectS_ArrowR.X := X + W + SkipX + SBGW - Tex_SelectS_ArrowR.W; - SelectsS[High(SelectsS)].Tex_SelectS_ArrowR.Y := Y; + SelectsS[High(SelectsS)].Tex_SelectS_ArrowR.Y := Y + (H - Tex_SelectS_ArrowR.H) / 2; SelectsS[High(SelectsS)].Tex_SelectS_ArrowR.W := Tex_SelectS_ArrowR.W; SelectsS[High(SelectsS)].Tex_SelectS_ArrowR.H := Tex_SelectS_ArrowR.H; @@ -1332,14 +1390,6 @@ begin SelectsS[S].TextureSBG.Y := Y; 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; @@ -1414,12 +1464,12 @@ begin Result := S; end; -procedure TMenu.AddSelectSlideOption(const AddText: string); +procedure TMenu.AddSelectSlideOption(const AddText: UTF8String); begin AddSelectSlideOption(High(SelectsS), AddText); end; -procedure TMenu.AddSelectSlideOption(SelectNo: cardinal; const AddText: string); +procedure TMenu.AddSelectSlideOption(SelectNo: cardinal; const AddText: UTF8String); var SO: integer; begin @@ -1435,7 +1485,8 @@ begin } end; -procedure TMenu.UpdateSelectSlideOptions(ThemeSelectSlide: TThemeSelectSlide; SelectNum: integer; Values: array of string; var Data: integer); +procedure TMenu.UpdateSelectSlideOptions(ThemeSelectSlide: TThemeSelectSlide; + SelectNum: integer; const Values: array of UTF8String; var Data: integer); var SO: integer; begin @@ -1560,7 +1611,7 @@ begin AddStatic(X+2, Y+2, W-4, H-4, 1, 1, 1, Skin.GetTextureFileName('MainBar'), TEXTURE_TYPE_COLORIZED); end; -procedure TMenu.onShow; +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. @@ -1589,57 +1640,18 @@ begin Background.OnShow; end; -procedure TMenu.onShowFinish; +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; +procedure TMenu.OnHide; begin // nothing Background.OnFinish; end; -function TMenu.ParseInput(PressedKey: cardinal; CharCode: WideChar; PressedDown: boolean): boolean; +function TMenu.ParseInput(PressedKey: Cardinal; CharCode: UCS4Char; PressedDown: boolean): boolean; begin // nothing Result := true; @@ -1648,6 +1660,7 @@ end; function TMenu.ParseMouse(MouseButton: integer; BtnDown: boolean; X, Y: integer): boolean; var nBut: integer; + Action: TMouseClickAction; begin //default mouse parsing: clicking generates return keypress, // mousewheel selects in select slide @@ -1657,55 +1670,80 @@ begin if RightMbESC and (MouseButton = SDL_BUTTON_RIGHT) and BtnDown then begin //if RightMbESC is set, send ESC keypress - Result:=ParseInput(SDLK_ESCAPE, #0, true); + Result:=ParseInput(SDLK_ESCAPE, 0, true); end; - nBut := InteractAt(X, Y); - if nBut >= 0 then + // transfer mousecords to the 800x600 raster we use to draw + X := Round((X / (ScreenW / Screens)) * RenderW); + if (X > RenderW) then + X := X - RenderW; + Y := Round((Y / ScreenH) * RenderH); + + // allways go to next screen if we don't have any interactions + if Length(Interactions) = 0 then begin - //select on mouse-over - if nBut <> Interaction then - SetInteraction(nBut); - if (MouseButton = SDL_BUTTON_LEFT) and BtnDown then - begin - //click button - Result:=ParseInput(SDLK_RETURN, #0, true); - end; - if (Interactions[nBut].Typ = iSelectS) then - begin - //forward/backward in select slide with mousewheel - if (MouseButton = SDL_BUTTON_WHEELDOWN) and BtnDown then - begin - ParseInput(SDLK_RIGHT, #0, true); - end; - if (MouseButton = SDL_BUTTON_WHEELUP) and BtnDown then - begin - ParseInput(SDLK_LEFT, #0, true); - end; - end; + if (BtnDown) and (MouseButton = SDL_BUTTON_LEFT) then + Result := ParseInput(SDLK_RETURN, 0, true); end else begin - nBut := CollectionAt(X, Y); + nBut := InteractAt(X, Y); if nBut >= 0 then begin - // if over button collection, select first child but don't allow click - nBut := ButtonCollection[nBut].FirstChild - 1; + //select on mouse-over if nBut <> Interaction then SetInteraction(nBut); + + Action := maNone; + + if (BtnDown) then + begin + if (MouseButton = SDL_BUTTON_LEFT) then + begin + //click button or SelectS + if (Interactions[nBut].Typ = iSelectS) then + Action := SelectsS[Interactions[nBut].Num].OnClick(X, Y) + else + Action := maReturn; + end + else if (MouseButton = SDL_BUTTON_WHEELDOWN) then + begin //forward on select slide with mousewheel + if (Interactions[nBut].Typ = iSelectS) then + Action := maRight; + end + else if (MouseButton = SDL_BUTTON_WHEELUP) then + begin //backward on select slide with mousewheel + if (Interactions[nBut].Typ = iSelectS) then + Action := maLeft; + end; + end; + + // do the action we have to do ;) + case Action of + maReturn: Result := ParseInput(SDLK_RETURN, 0, true); + maLeft: Result := ParseInput(SDLK_LEFT, 0, true); + maRight: Result := ParseInput(SDLK_RIGHT, 0, true); + end; + end + else + begin + nBut := CollectionAt(X, Y); + if (nBut >= 0) and (not ButtonCollection[nBut].Selected) then + begin + // if over button collection, that is not already selected + // -> select first child but don't allow click + nBut := ButtonCollection[nBut].FirstChild - 1; + if nBut <> Interaction then + SetInteraction(nBut); + end; end; end; end; -function TMenu.InRegion(X1, Y1, W, H, X, Y: real): boolean; +function TMenu.InRegion(X, Y: real; A: TMouseOverRect): boolean; begin - Result := false; - X1 := X1 * Screen.w / 800; - W := W * Screen.w / 800; - Y1 := Y1 * Screen.h / 600; - H := H * Screen.h / 600; - if (X >= X1) and (X <= X1 + W) and (Y >= Y1) and (Y <= Y1 + H) then - Result := true; + // check whether A contains X and Y + Result := (X >= A.X) and (X <= A.X + A.W) and (Y >= A.Y) and (Y <= A.Y + A.H); end; //takes x,y coordinates and returns the interaction number @@ -1718,20 +1756,22 @@ begin for i := Low(Interactions) to High(Interactions) do begin case Interactions[i].Typ of - iButton: if InRegion(Button[Interactions[i].Num].X, Button[Interactions[i].Num].Y, Button[Interactions[i].Num].W, Button[Interactions[i].Num].H, X, Y) and + iButton: + if InRegion(X, Y, Button[Interactions[i].Num].GetMouseOverArea) and Button[Interactions[i].Num].Visible then - begin + begin Result:=i; exit; end; - iBCollectionChild: if InRegion(Button[Interactions[i].Num].X, Button[Interactions[i].Num].Y, Button[Interactions[i].Num].W, Button[Interactions[i].Num].H, X, Y) then + iBCollectionChild: + if InRegion(X, Y, Button[Interactions[i].Num].GetMouseOverArea) then begin Result:=i; exit; end; - iSelectS: if InRegion(SelectSs[Interactions[i].Num].X, SelectSs[Interactions[i].Num].Y, SelectSs[Interactions[i].Num].W, SelectSs[Interactions[i].Num].H, X, Y) or - InRegion(SelectSs[Interactions[i].Num].TextureSBG.X, SelectSs[Interactions[i].Num].TextureSBG.Y, SelectSs[Interactions[i].Num].TextureSBG.W, SelectSs[Interactions[i].Num].TextureSBG.H, X, Y) then - begin + iSelectS: + if InRegion(X, Y, SelectSs[Interactions[i].Num].GetMouseOverArea) then + begin Result:=i; exit; end; @@ -1747,7 +1787,7 @@ begin Result := -1; for i:= Low(ButtonCollection) to High(ButtonCollection) do begin - if InRegion(ButtonCollection[i].X, ButtonCollection[i].Y, ButtonCollection[i].W, ButtonCollection[i].H, X, Y) and + if InRegion(X, Y, ButtonCollection[i].GetMouseOverArea) and ButtonCollection[i].Visible then begin Result:=i; diff --git a/cmake/src/menu/UMenuBackground.pas b/cmake/src/menu/UMenuBackground.pas index c85f0806..0e2e63a6 100644 --- a/cmake/src/menu/UMenuBackground.pas +++ b/cmake/src/menu/UMenuBackground.pas @@ -1,83 +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. +{* 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 index a5c2a70a..45b58c1e 100644 --- a/cmake/src/menu/UMenuBackgroundColor.pas +++ b/cmake/src/menu/UMenuBackgroundColor.pas @@ -1,73 +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; - +{* 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 index b61a4542..6d877baa 100644 --- a/cmake/src/menu/UMenuBackgroundFade.pas +++ b/cmake/src/menu/UMenuBackgroundFade.pas @@ -1,176 +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. +{* 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, + UPath; + +//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: IPath; +begin + inherited; + FadeTime := 0; + + Color := ThemedSettings.Color; + Alpha := ThemedSettings.Alpha; + if (Length(ThemedSettings.Tex) > 0) then + begin + texFilename := Skin.GetTextureFileName(ThemedSettings.Tex); + 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 index 1fccc007..c64f3023 100644 --- a/cmake/src/menu/UMenuBackgroundNone.pas +++ b/cmake/src/menu/UMenuBackgroundNone.pas @@ -1,70 +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; - +{* 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 index a1b9e88a..f71637ff 100644 --- a/cmake/src/menu/UMenuBackgroundTexture.pas +++ b/cmake/src/menu/UMenuBackgroundTexture.pas @@ -1,125 +1,126 @@ -{* 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. +{* 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, + UPath; + +//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: IPath; +begin + inherited; + + if (Length(ThemedSettings.Tex) = 0) then + raise EMenuBackgroundError.Create('TMenuBackgroundTexture: No texture filename present'); + + Color := ThemedSettings.Color; + + texFilename := Skin.GetTextureFileName(ThemedSettings.Tex); + 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 index d1ce0f09..bfaee702 100644 --- a/cmake/src/menu/UMenuBackgroundVideo.pas +++ b/cmake/src/menu/UMenuBackgroundVideo.pas @@ -1,204 +1,211 @@ -{* 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. +{* 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, + UMusic, + UVideo, + UPath; + +//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: IPath): TBGVideo; + procedure RemoveItem( + procedure FreeAllItems; + + destructor Destroy; + end; + +type } + TMenuBackgroundVideo = class (TMenuBackground) + private + fFilename: IPath; + fBgVideo: IVideo; + 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, + 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); + if (not fFilename.IsFile) then + raise EMenuBackgroundError.Create('TMenuBackgroundVideo: Can''t load background video: ' + fFilename.ToNative); +end; + +destructor TMenuBackgroundVideo.Destroy; +begin +end; + +procedure TMenuBackgroundVideo.OnShow; +begin + fBgVideo := VideoPlayback.Open(fFileName); + if (fBgVideo <> nil) then + begin + VideoBGTimer.SetTime(0); + VideoBGTimer.Start(); + fBgVideo.Loop := true; + fBgVideo.Play; + end; +end; + +procedure TMenuBackgroundVideo.OnFinish; +begin + // unload video + fBgVideo := nil; +end; + +procedure TMenuBackgroundVideo.Draw; +begin + // clear just once when in dual screen mode + if (ScreenAct = 1) then + begin + glClear(GL_DEPTH_BUFFER_BIT); + // video failure -> draw blank background + if (fBgVideo = nil) then + glClear(GL_COLOR_BUFFER_BIT); + end; + + if (fBgVideo <> nil) then + begin + fBgVideo.GetFrame(VideoBGTimer.GetTime()); + // FIXME: why do we draw on screen 2? Seems to be wrong. + fBgVideo.DrawGL(2); + end; +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: IPath): TBGVideo; +begin + +end; + +procedure TBGVideoPool.FreeAllItems; +begin + +end; } + +end. diff --git a/cmake/src/menu/UMenuButton.pas b/cmake/src/menu/UMenuButton.pas index 923f0b14..868a86f3 100644 --- a/cmake/src/menu/UMenuButton.pas +++ b/cmake/src/menu/UMenuButton.pas @@ -38,7 +38,8 @@ uses UTexture, gl, UMenuText, - SDL; + SDL, + UMenuInteract; type CButton = class of TButton; @@ -116,6 +117,8 @@ type constructor Create(Textura: TTexture); overload; constructor Create(Textura, DSTexture: TTexture); overload; destructor Destroy; override; + + function GetMouseOverArea: TMouseOverRect; end; implementation @@ -529,6 +532,49 @@ begin end; end; +function TButton.GetMouseOverArea: TMouseOverRect; +begin + if (FadeTex.TexNum = 0) then + begin + Result.X := Texture.X; + Result.Y := Texture.Y; + Result.W := Texture.W; + Result.H := Texture.H; + end + else + begin + case FadeTexPos of + 0: begin // fade tex on top + Result.X := Texture.X; + Result.Y := FadeTex.Y; + Result.W := Texture.W; + Result.H := FadeTex.H + Texture.H; + end; + + 1: begin // fade tex on left side + Result.X := FadeTex.X; + Result.Y := Texture.Y; + Result.W := FadeTex.W + Texture.W; + Result.H := Texture.H; + end; + + 2: begin // fade tex on bottom + Result.X := Texture.X; + Result.Y := Texture.Y; + Result.W := Texture.W; + Result.H := FadeTex.H + Texture.H; + end; + + 3: begin // fade tex on right side + Result.X := Texture.X; + Result.Y := Texture.Y; + Result.W := FadeTex.W + Texture.W; + Result.H := Texture.H; + end; + end; + end; +end; + destructor TButton.Destroy; begin diff --git a/cmake/src/menu/UMenuInteract.pas b/cmake/src/menu/UMenuInteract.pas index beb6bcef..7cb92025 100644 --- a/cmake/src/menu/UMenuInteract.pas +++ b/cmake/src/menu/UMenuInteract.pas @@ -39,6 +39,15 @@ type Num: integer; // number of this item in proper list like buttons, selects end; + { to handle the area where the mouse is over a control } + TMouseOverRect = record + X, Y: Real; + W, H: Real; + end; + + { to handle the on click action } + TMouseClickAction = (maNone, maReturn, maLeft, maRight); + implementation end. diff --git a/cmake/src/menu/UMenuSelectSlide.pas b/cmake/src/menu/UMenuSelectSlide.pas index f9f6bbae..09ce3b9f 100644 --- a/cmake/src/menu/UMenuSelectSlide.pas +++ b/cmake/src/menu/UMenuSelectSlide.pas @@ -37,22 +37,29 @@ uses gl, TextGL, UMenuText, - UTexture; + UTexture, + UMenuInteract; type PSelectSlide = ^TSelectSlide; TSelectSlide = class private SelectBool: boolean; + + function AdjustOptionTextToFit(OptText: UTF8String): UTF8String; 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 + TextOptT: array of UTF8String; // array of names for possible options Texture: TTexture; // Select Texture TextureSBG: TTexture; // Background Selections Texture -// TextureS: array of TTexture; // Selections Texture (not used) + + Colorized: boolean; + DeSelectTexture: TTexture; // texture for colorized hack + ColorizedSBG: boolean; + DeSelectTextureSBG: TTexture; // texture for colorized hack Select BG Tex_SelectS_ArrowL: TTexture; // Texture for left arrow Tex_SelectS_ArrowR: TTexture; // Texture for right arrow @@ -135,8 +142,17 @@ type //Automatically Generate Lines (Texts) procedure genLines; + + function GetMouseOverArea: TMouseOverRect; + function OnClick(X, Y: Real): TMouseClickAction; end; +const + ArrowAlphaOptionsLeft = 1; + ArrowAlphaNoOptionsLeft = 0; + MinItemSpacing = 5; + MinSideSpacing = 24; + implementation uses @@ -153,6 +169,26 @@ begin SetLength(TextOpt, 1); TextOpt[0] := TText.Create; Visible := true; + + Colorized := false; + ColorizedSBG := false; + ColR := 1; + ColG := 1; + ColB := 1; + Int := 1; + DColR := 1; + DColG := 1; + DColB := 1; + DInt := 1; + + SBGColR := 1; + SBGColG := 1; + SBGColB := 1; + SBGInt := 1; + SBGDColR := 1; + SBGDColG := 1; + SBGDColB := 1; + SBGDInt := 1; end; procedure TSelectSlide.SetSelect(Value: boolean); @@ -180,20 +216,30 @@ begin end else begin - Texture.ColR := DColR; - Texture.ColG := DColG; - Texture.ColB := DColB; - Texture.Int := DInt; + if Colorized then + DeSelectTexture.Int := DInt + else + begin + Texture.ColR := DColR; + Texture.ColG := DColG; + Texture.ColB := DColB; + Texture.Int := DInt; + end; Text.ColR := TDColR; Text.ColG := TDColG; Text.ColB := TDColB; Text.Int := TDInt; - TextureSBG.ColR := SBGDColR; - TextureSBG.ColG := SBGDColG; - TextureSBG.ColB := SBGDColB; - TextureSBG.Int := SBGDInt; + if (ColorizedSBG) then + DeselectTextureSBG.Int := SBGDInt + else + begin + TextureSBG.ColR := SBGDColR; + TextureSBG.ColG := SBGDColG; + TextureSBG.ColB := SBGDColB; + TextureSBG.Int := SBGDInt; + end; end; end; @@ -236,12 +282,15 @@ begin begin Value := 0; - Tex_SelectS_ArrowL.alpha := 0; - Tex_SelectS_ArrowR.alpha := 1; + Tex_SelectS_ArrowL.alpha := ArrowAlphaNoOptionsLeft; + if (Length(TextOptT) > 1) then + Tex_SelectS_ArrowR.alpha := ArrowAlphaOptionsLeft + else + Tex_SelectS_ArrowR.alpha := ArrowAlphaNoOptionsLeft; for SO := Low(TextOpt) to High(TextOpt) do begin - TextOpt[SO].Text := TextOptT[SO]; + TextOpt[SO].Text := AdjustOptionTextToFit(TextOptT[SO]); end; DoSelection(0); @@ -252,12 +301,12 @@ begin begin Value := High(TextOptT); - Tex_SelectS_ArrowL.alpha := 1; - Tex_SelectS_ArrowR.alpha := 0; + Tex_SelectS_ArrowL.alpha := ArrowAlphaOptionsLeft; + Tex_SelectS_ArrowR.alpha := ArrowAlphaNoOptionsLeft; for SO := High(TextOpt) downto Low(TextOpt) do begin - TextOpt[SO].Text := TextOptT[High(TextOptT) - (Lines - SO - 1)]; + TextOpt[SO].Text := AdjustOptionTextToFit(TextOptT[High(TextOptT) - (Lines - SO - 1)]); end; DoSelection(Lines - 1); end @@ -265,8 +314,8 @@ begin //in between first and last else begin - Tex_SelectS_ArrowL.alpha := 1; - Tex_SelectS_ArrowR.alpha := 1; + Tex_SelectS_ArrowL.alpha := ArrowAlphaOptionsLeft; + Tex_SelectS_ArrowR.alpha := ArrowAlphaOptionsLeft; HalfL := Ceil((Lines - 1) / 2); HalfR := Lines - 1 - HalfL; @@ -277,7 +326,7 @@ begin //Change texts for SO := Low(TextOpt) to High(TextOpt) do begin - TextOpt[SO].Text := TextOptT[SO]; + TextOpt[SO].Text := AdjustOptionTextToFit(TextOptT[SO]); end; DoSelection(Value); @@ -291,10 +340,10 @@ begin //Change texts for SO := High(TextOpt) downto Low(TextOpt) do begin - TextOpt[SO].Text := TextOptT[High(TextOptT) - (Lines - SO - 1)]; + TextOpt[SO].Text := AdjustOptionTextToFit(TextOptT[High(TextOptT) - (Lines - SO - 1)]); end; - DoSelection (HalfL); + DoSelection (HalfL); end else @@ -302,7 +351,7 @@ begin //Change Texts for SO := Low(TextOpt) to High(TextOpt) do begin - TextOpt[SO].Text := TextOptT[Value - HalfL + SO]; + TextOpt[SO].Text := AdjustOptionTextToFit(TextOptT[Value - HalfL + SO]); end; DoSelection(HalfL); @@ -311,14 +360,71 @@ begin end; end; +{ cuts the text if it is too long to fit on the selectbg } +function TSelectSlide.AdjustOptionTextToFit(OptText: UTF8String): UTF8String; + var + MaxLen: real; + Len: integer; +begin + Result := OptText; + + if (TextureSBG.W > 0) then + begin + MaxLen := TextureSBG.W - MinSideSpacing * 2; + + SetFontStyle(ftNormal); + SetFontSize(Text.Size); + + // we will remove min. 2 letters by default and replace them w/ points + // if the whole text don't fit + Len := Length(OptText) - 1; + + while (glTextWidth(Result) > MaxLen) and (Len > 0) do + begin + { ensure that we only cut at full letters } + { this code may be a problem if there is a text that + consists of many multi byte characters and only few + one byte characters } + repeat + Dec(Len); + until (byte(OptText[Len]) and 128) = 0; + + Result := copy(OptText, 1, Len) + '..'; + end; + end; +end; + procedure TSelectSlide.Draw; var SO: integer; begin if Visible then begin - DrawTexture(Texture); - DrawTexture(TextureSBG); + if SelectBool or not Colorized then + begin + DrawTexture(Texture); + end + else + begin + DeselectTexture.X := Texture.X; + DeselectTexture.Y := Texture.Y; + DeselectTexture.W := Texture.W; + DeselectTexture.H := Texture.H; + DrawTexture(DeselectTexture); + end; + + if SelectBool or not ColorizedSBG then + begin + DrawTexture(TextureSBG); + end + else + begin + DeselectTextureSBG.X := TextureSBG.X; + DeselectTextureSBG.Y := TextureSBG.Y; + DeselectTextureSBG.W := TextureSBG.W; + DeselectTextureSBG.H := TextureSBG.H; + DrawTexture(DeselectTextureSBG); + end; if showArrows then begin @@ -338,7 +444,7 @@ var maxlength: real; I: integer; begin - SetFontStyle(0{Text.Style}); + SetFontStyle(ftNormal{Text.Style}); SetFontSize(Text.Size); maxlength := 0; @@ -352,7 +458,7 @@ begin if (oneItemOnly = false) then begin //show all items - Lines := floor((TextureSBG.W-40) / (maxlength+7)); + Lines := floor((TextureSBG.W - MinSideSpacing * 2) / (maxlength + MinItemSpacing)); if (Lines > Length(TextOptT)) then Lines := Length(TextOptT); @@ -369,40 +475,67 @@ begin for I := Low(TextOpt) to High(TextOpt) do TextOpt[I].Free; - setLength (TextOpt, Lines); + 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].Style := 0; 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; - + // generate positions TextOpt[I].Y := TextureSBG.Y + (TextureSBG.H - Text.Size) / 2; - //Better Look with 2 Options - if (Lines = 2) and (Length(TextOptT) = 2) then + // better look with 2 options and a single option + if (Lines = 2) then + begin TextOpt[I].X := TextureSBG.X + 20 + (TextureSBG.W -40 - glTextWidth(TextOptT[1])) * I; - - if (Lines = 1) then + TextOpt[I].Align := 0; + end + else if (Lines = 1) then begin - TextOpt[I].Align := 1; //center text TextOpt[I].X := TextureSBG.X + (TextureSBG.W / 2); + TextOpt[I].Align := 1; //center text + end + else + begin + TextOpt[I].X := TextureSBG.X + TextureSBG.W / 2 + (TextureSBG.W - MinSideSpacing*2) * (I / Lines - 0.5); + TextOpt[I].Align := 0; end; end; end; +function TSelectSlide.GetMouseOverArea: TMouseOverRect; +begin + Result.X := Texture.X; + Result.Y := Texture.Y; + Result.W := (TextureSBG.X + TextureSBG.W) - Result.X; + Result.H := Max(Texture.H, TextureSBG.H); +end; + +function TSelectSlide.OnClick(X, Y: Real): TMouseClickAction; + var + AreaW: Real; +begin + // default: press return on click + Result := maReturn; + + // use left sides to inc or dec selection by click + AreaW := TextureSbg.W / 20; + + if (Y >= TextureSBG.Y) and (Y <= TextureSBG.Y + TextureSBG.H) then + begin + if (X >= TextureSBG.X) and (X <= TextureSBG.X + AreaW) then + Result := maLeft // hit left area + else if (X >= TextureSBG.X + TextureSBG.W - AreaW) and (X <= TextureSBG.X + TextureSBG.W) then + Result := maRight; // hit right area + end; +end; + end. diff --git a/cmake/src/menu/UMenuText.pas b/cmake/src/menu/UMenuText.pas index b5507327..ab180b77 100644 --- a/cmake/src/menu/UMenuText.pas +++ b/cmake/src/menu/UMenuText.pas @@ -45,8 +45,8 @@ type TText = class private SelectBool: boolean; - TextString: string; - TextTiles: array of string; + TextString: UTF8String; + TextTiles: array of UTF8String; STicks: cardinal; SelectBlink: boolean; @@ -75,22 +75,23 @@ type procedure SetSelect(Value: boolean); property Selected: boolean read SelectBool write SetSelect; - procedure SetText(Value: string); - property Text: string read TextString write SetText; + procedure SetText(Value: UTF8String); + property Text: UTF8String read TextString write SetText; - procedure DeleteLastL; // procedure to delete last letter + procedure DeleteLastLetter; //< Deletes the rightmost 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; + constructor Create(X, Y: real; const Text: UTF8String); overload; + constructor Create(ParX, ParY, ParW: real; ParStyle: integer; ParSize, ParColR, ParColG, ParColB: real; ParAlign: integer; const ParText: UTF8String; ParReflection: boolean; ParReflectionSpacing: real; ParZ: real); overload; end; implementation uses - StrUtils, - UGraphic; + UGraphic, + UUnicodeUtils, + StrUtils; procedure TText.SetSelect(Value: boolean); begin @@ -101,7 +102,7 @@ begin STicks := SDL_GetTicks() div 550; end; -procedure TText.SetText(Value: string); +procedure TText.SetText(Value: UTF8String); var NextPos: cardinal; // next pos of a space etc. LastPos: cardinal; // last pos " @@ -244,23 +245,15 @@ begin AddBreak(LastBreak, Length(Value)+1); end; -procedure TText.DeleteLastL; -var - S: string; - L: integer; +procedure TText.DeleteLastLetter; begin - S := TextString; - L := Length(S); - if (L > 0) then - SetLength(S, L-1); - - SetText(S); + SetText(UTF8Copy(TextString, 1, LengthUTF8(TextString)-1)); end; procedure TText.Draw; var X2, Y2: real; - Text2: string; + Text2: UTF8String; I: integer; Ticks: cardinal; begin @@ -304,7 +297,7 @@ begin SetFontPos(X2, Y); glPrint(Text2); - SetFontStyle(0); // reset to default + SetFontStyle(ftNormal); // reset to default end else begin} @@ -333,12 +326,12 @@ begin {if Size >= 10 then Y2 := Y2 + Size * 0.93 else} - if (Style = 1) then + if (Style = ftBold) then Y2 := Y2 + Size * 0.93 else Y2 := Y2 + Size * 0.72; end; - SetFontStyle(0); // reset to default + SetFontStyle(ftNormal); // reset to default //end; end; @@ -349,19 +342,19 @@ begin Create(0, 0, ''); end; -constructor TText.Create(X, Y: real; Text: string); +constructor TText.Create(X, Y: real; const Text: UTF8String); begin - Create(X, Y, 0, 0, 30, 0, 0, 0, 0, Text, false, 0, 0); + Create(X, Y, 0, ftNormal, 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); + ParSize, ParColR, ParColG, ParColB: real; + ParAlign: integer; + const ParText: UTF8String; + ParReflection: boolean; + ParReflectionSpacing: real; + ParZ: real); begin inherited Create; Alpha := 1; -- cgit v1.2.3