From 322b798413826681915eca1960f081cbc4dd302c Mon Sep 17 00:00:00 2001
From: whiteshark0 <whiteshark0@b956fd51-792f-4845-bead-9b4dfca2ff2c>
Date: Mon, 13 Oct 2008 14:14:32 +0000
Subject: Abstraction of the menus background 5 different bg types:
 none(fallback), colored, texture, video, and fade(for overlays) Some
 sideeffect is 5 mb less memory usage, don't know for which reasons :P

git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1446 b956fd51-792f-4845-bead-9b4dfca2ff2c
---
 src/base/UGraphic.pas                |  64 +++++------
 src/base/UThemes.pas                 |  42 ++++++-
 src/menu/UDisplay.pas                |   6 +-
 src/menu/UMenu.pas                   | 206 ++++++++++++++++++++++++++---------
 src/menu/UMenuBackground.pas         |  85 +++++++++++++++
 src/menu/UMenuBackgroundColor.pas    |  69 ++++++++++++
 src/menu/UMenuBackgroundFade.pas     | 172 +++++++++++++++++++++++++++++
 src/menu/UMenuBackgroundNone.pas     |  68 ++++++++++++
 src/menu/UMenuBackgroundTexture.pas  | 122 +++++++++++++++++++++
 src/menu/UMenuBackgroundVideo.pas    | 204 ++++++++++++++++++++++++++++++++++
 src/screens/UScreenLoading.pas       |   6 -
 src/screens/UScreenOptionsThemes.pas |   2 +-
 src/screens/UScreenPopup.pas         |  27 ++---
 src/screens/UScreenSong.pas          |  13 ++-
 src/ultrastardx.dpr                  |  18 +++
 15 files changed, 987 insertions(+), 117 deletions(-)
 create mode 100644 src/menu/UMenuBackground.pas
 create mode 100644 src/menu/UMenuBackgroundColor.pas
 create mode 100644 src/menu/UMenuBackgroundFade.pas
 create mode 100644 src/menu/UMenuBackgroundNone.pas
 create mode 100644 src/menu/UMenuBackgroundTexture.pas
 create mode 100644 src/menu/UMenuBackgroundVideo.pas

(limited to 'src')

diff --git a/src/base/UGraphic.pas b/src/base/UGraphic.pas
index a624d14f..eea7db0b 100644
--- a/src/base/UGraphic.pas
+++ b/src/base/UGraphic.pas
@@ -767,39 +767,39 @@ begin
 end;
 
 procedure UnLoadScreens;
+var I: Integer;
 begin
-  freeandnil( ScreenMain );
-  freeandnil( ScreenName );
-  freeandnil( ScreenLevel);
-  freeandnil( ScreenSong );
-  freeandnil( ScreenSongMenu );
-  freeandnil( ScreenSing );
-  freeandnil( ScreenScore);
-  freeandnil( ScreenTop5 );
-  freeandnil( ScreenOptions );
-  freeandnil( ScreenOptionsGame );
-  freeandnil( ScreenOptionsGraphics );
-  freeandnil( ScreenOptionsSound );
-  freeandnil( ScreenOptionsLyrics );
-//  freeandnil( ScreenOptionsThemes );
-  freeandnil( ScreenOptionsRecord );
-  freeandnil( ScreenOptionsAdvanced );
-  freeandnil( ScreenEditSub );
-  freeandnil( ScreenEdit );
-  freeandnil( ScreenEditConvert );
-  freeandnil( ScreenOpen );
-  freeandnil( ScreenSingModi );
-  freeandnil( ScreenSongMenu );
-  freeandnil( ScreenSongJumpto);
-  freeandnil( ScreenPopupCheck );
-  freeandnil( ScreenPopupError );
-  freeandnil( ScreenPartyNewRound );
-  freeandnil( ScreenPartyScore    );
-  freeandnil( ScreenPartyWin     );
-  freeandnil( ScreenPartyOptions  );
-  freeandnil( ScreenPartyPlayer   );
-  freeandnil( ScreenStatMain     );
-  freeandnil( ScreenStatDetail    );
+  ScreenMain.Destroy;
+  ScreenName.Destroy;
+  ScreenLevel.Destroy;
+  ScreenSong.Destroy;
+  ScreenSing.Destroy;
+  ScreenScore.Destroy;
+  ScreenTop5.Destroy;
+  ScreenOptions.Destroy;
+  ScreenOptionsGame.Destroy;
+  ScreenOptionsGraphics.Destroy;
+  ScreenOptionsSound.Destroy;
+  ScreenOptionsLyrics.Destroy;
+//  ScreenOptionsThemes.Destroy;
+  ScreenOptionsRecord.Destroy;
+  ScreenOptionsAdvanced.Destroy;
+  ScreenEditSub.Destroy;
+  ScreenEdit.Destroy;
+  ScreenEditConvert.Destroy;
+  ScreenOpen.Destroy;
+  ScreenSingModi.Destroy;
+  ScreenSongMenu.Destroy;
+  ScreenSongJumpto.Destroy;
+  ScreenPopupCheck.Destroy;
+  ScreenPopupError.Destroy;
+  ScreenPartyNewRound.Destroy;
+  ScreenPartyScore.Destroy;
+  ScreenPartyWin.Destroy;
+  ScreenPartyOptions.Destroy;
+  ScreenPartyPlayer.Destroy;
+  ScreenStatMain.Destroy;
+  ScreenStatDetail.Destroy;
 end;
 
 end.
diff --git a/src/base/UThemes.pas b/src/base/UThemes.pas
index 3ee2798e..e5232c17 100644
--- a/src/base/UThemes.pas
+++ b/src/base/UThemes.pas
@@ -51,10 +51,29 @@ type
     R, G, B, A: Double;
   end;
 
-  TThemeBackground = record
-    Tex:  string;
+TThemeBackground = record
+    BGType: Byte;
+    Color:  TRGB;
+    Tex:    string;
+    Alpha:  Real;
   end;
 
+const
+  BGT_Names: Array [0..4] of String = ('none', 'color', 'texture', 'video', 'fade');
+  BGT_None    = 0;
+  BGT_Color   = 1;
+  BGT_Texture = 2;
+  BGT_Video   = 3;
+  BGT_Fade    = 4;
+  BGT_Auto    = 255;
+  //Defaul Background for Screens w/o Theme e.g. editor
+  DEFAULTBACKGROUND: TThemeBackground = (BGType: BGT_Color;
+                                         Color:  (R:1; G:1; B:1);
+                                         Tex:    '';
+                                         Alpha:  1.0);
+
+
+type
   TThemeStatic = record
     X:      integer;
     Y:      integer;
@@ -1468,8 +1487,25 @@ begin
 end;
 
 procedure TTheme.ThemeLoadBackground(var ThemeBackground: TThemeBackground; Name: string);
+var
+  BGType: String;
+  I: Integer;
 begin
-  ThemeBackground.Tex := ThemeIni.ReadString(Name + 'Background', 'Tex', '');
+  BGType  := lowercase(ThemeIni.ReadString(Name + 'Background', 'Type', 'auto'));
+
+  ThemeBackground.BGType := BGT_Auto;
+  For I := 0 to high(BGT_Names) do
+    If (BGT_Names[I] = BGType) then
+    begin
+      ThemeBackground.BGType := I;
+      Break;
+    end;
+
+  ThemeBackground.Tex     := ThemeIni.ReadString(Name + 'Background', 'Tex', '');
+  ThemeBackground.Color.R := ThemeIni.ReadFloat(Name + 'Background', 'ColR', 1);
+  ThemeBackground.Color.G := ThemeIni.ReadFloat(Name + 'Background', 'ColG', 1);
+  ThemeBackground.Color.B := ThemeIni.ReadFloat(Name + 'Background', 'ColB', 1);
+  ThemeBackground.Alpha   := ThemeIni.ReadFloat(Name + 'Background', 'Alpha', 1);
 end;
 
 procedure TTheme.ThemeLoadText(var ThemeText: TThemeText; Name: string);
diff --git a/src/menu/UDisplay.pas b/src/menu/UDisplay.pas
index cd8241ae..ebd25e50 100644
--- a/src/menu/UDisplay.pas
+++ b/src/menu/UDisplay.pas
@@ -141,8 +141,10 @@ var
 begin
   Result := True;
 
-  glClearColor(1, 1, 1 , 0);
-  glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+  //We don't need this here anymore,
+  //Because the background care about cleaning the buffers
+  //glClearColor(1, 1, 1 , 0);
+  //glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
 
   for S := 1 to Screens do
   begin
diff --git a/src/menu/UMenu.pas b/src/menu/UMenu.pas
index dd182d5f..9068e4cb 100644
--- a/src/menu/UMenu.pas
+++ b/src/menu/UMenu.pas
@@ -42,6 +42,7 @@ uses
   UMenuButton,
   UMenuSelectSlide,
   UMenuInteract,
+  UMenuBackground,
   UThemes,
   UMenuButtonCollection,
   Math,
@@ -53,18 +54,16 @@ type
   PMenu = ^TMenu;
   TMenu = class
     protected
-      ButtonPos:      Integer;
+      Background:     TMenuBackground;
 
       Interactions:   array of TInteract;
       SelInteraction: integer;
+
+      ButtonPos:      Integer;
       Button:         array of TButton;
+      
       SelectsS:       array of TSelectSlide;
       ButtonCollection: array of TButtonCollection;
-      BackImg:        TTexture;
-      BackW:          integer;
-      BackH:          integer;
-
-      fFileName : string;
     public
       Text:       array of TText;
       Static:     array of TStatic;
@@ -94,7 +93,7 @@ type
       procedure AddButtonCollection(const ThemeCollection: TThemeButtonCollection; Const Num: Byte);
 
       // background
-      procedure AddBackground(Name: string);
+      procedure AddBackground(ThemedSettings: TThemeBackground);
 
       // static
       function AddStatic(ThemeStatic: TThemeStatic): integer; overload;
@@ -191,10 +190,21 @@ uses UCommon,
      UDisplay,
      UCovers,
      UTime,
-     USkins;
+     USkins,
+     //Background types
+     UMenuBackgroundNone,
+     UMenuBackgroundColor,
+     UMenuBackgroundTexture,
+     UMenuBackgroundVideo,
+     UMenuBackgroundFade;
 
 destructor TMenu.Destroy;
 begin
+  If (Background <> nil) then
+  begin
+    Background.Destroy;
+  end;
+  //Log.LogError('Unloaded Succesful: ' + ClassName);
   inherited;
 end;
 
@@ -207,10 +217,10 @@ begin
   SetLength(Static, 0);
   SetLength(Button, 0);
 
-  BackImg.TexNum := 0;
-
   //Set ButtonPos to Autoset Length
   ButtonPos := -1;
+
+  Background := nil;
 end;
 {
 constructor TMenu.Create(Back: String);
@@ -314,7 +324,7 @@ begin
   PrepareButtonCollections(ThemeBasic.ButtonCollection);
 
   //Add Background
-  AddBackground(ThemeBasic.Background.Tex);
+  AddBackground(ThemeBasic.Background);
 
   //Add Statics and Texts
   for I := 0 to High(ThemeBasic.Static) do
@@ -324,34 +334,141 @@ begin
     AddText(ThemeBasic.Text[I]);
 end;
 
-procedure TMenu.AddBackground(Name: string);
-//var
-//  lFileName : string;
+procedure TMenu.AddBackground(ThemedSettings: TThemeBackground);
+  var
+    FileExt: String;
+
+  Function IsInArray(const Piece: String; const A: Array of String): Boolean;
+  var I: Integer;
+  begin
+    Result := False;
+    
+    For I := 0 to High(A) do
+      If (A[I] = Piece) then
+      begin
+        Result := True;
+        Exit;
+      end;
+  end;
+
+  Function TryBGCreate(Typ: cMenuBackground): Boolean;
+  begin
+    Result := True;
+
+    try
+      Background := Typ.Create(ThemedSettings);
+    except
+      on E: EMenuBackgroundError do
+      begin //Background failes to create
+        Freeandnil(Background);
+        Result := False;
+      end;
+    end;
+  end;
 begin
-  if Name <> '' then
+  If (Background <> nil) then
   begin
-    fFileName := Skin.GetTextureFileName(Name);
-    fFileName := AdaptFilePaths( fFileName );
+    Background.Destroy;
+    Background := nil;
+  end;
 
-    if fileexists( fFileName ) then
-    begin
-      BackImg   := Texture.GetTexture( fFileName , TEXTURE_TYPE_PLAIN);
+  Case ThemedSettings.BGType of
+    BGT_Auto: begin //Automaticly choose one out of BGT_Texture, BGT_Video or BGT_Color
 
-      if ( BackImg.TexNum = 0 )  then
+      If (Length(ThemedSettings.Tex) > 0) then
       begin
-        if VideoPlayback.Open( fFileName ) then
+
+        //At first some intelligent try to decide which BG to load
+        FileExt := lowercase(ExtractFileExt(Skin.GetTextureFileName(ThemedSettings.Tex)));
+
+        If IsInArray(FileExt, SUPPORTED_EXTS_BACKGROUNDTEXTURE) then
+          TryBGCreate(TMenuBackgroundTexture)
+        Else If IsInArray(FileExt, SUPPORTED_EXTS_BACKGROUNDVIDEO) then
+          TryBGCreate(TMenuBackgroundVideo);
+
+
+        //If the intelligent method don't succeed
+        //do it by trial and error
+        If (Background = nil) then
+        begin
+          //Try Textured Bg
+          if not TryBGCreate(TMenuBackgroundTexture) then
+            TryBgCreate(TMenuBackgroundVideo); //Try Video BG
+
+          //Color is fallback if Background = nil
+        end;
+      end;
+    end;
+
+    BGT_Color: begin
+      try
+        Background := TMenuBackgroundColor.Create(ThemedSettings);
+      except
+        on E: EMenuBackgroundError do
+        begin
+          Log.LogError(E.Message);
+          freeandnil(Background);
+        end;
+      end;
+    end;
+
+    BGT_Texture: begin
+      try
+        Background := TMenuBackgroundTexture.Create(ThemedSettings);
+      except
+        on E: EMenuBackgroundError do
+        begin
+          Log.LogError(E.Message);
+          freeandnil(Background);
+        end;
+      end;
+    end;
+
+    BGT_Video: begin
+      try
+        Background := TMenuBackgroundVideo.Create(ThemedSettings);
+      except
+        on E: EMenuBackgroundError do
+        begin
+          Log.LogError(E.Message);
+          freeandnil(Background);
+        end;
+      end;
+    end;
+
+    BGT_None: begin
+      try
+        Background := TMenuBackgroundNone.Create(ThemedSettings);
+      except
+        on E: EMenuBackgroundError do
         begin
-          VideoBGTimer.SetTime(0);
-          VideoPlayback.Play;
+          Log.LogError(E.Message);
+          freeandnil(Background);
         end;
       end;
+    end;
 
-      BackImg.W := 800;
-      BackImg.H := 600;
-      BackW     := 1;
-      BackH     := 1;
+    BGT_Fade: begin
+      try
+        Background := TMenuBackgroundFade.Create(ThemedSettings);
+      except
+        on E: EMenuBackgroundError do
+        begin
+          Log.LogError(E.Message);
+          freeandnil(Background);
+        end;
+      end;
     end;
   end;
+
+  //Fallback to None Background or Colored Background
+  If (Background = nil) then
+  begin
+    If (ThemedSettings.BGType = BGT_Color) then
+      Background := TMenuBackgroundNone.Create(ThemedSettings)
+    Else
+      Background := TMenuBackgroundColor.Create(ThemedSettings)
+  end;
 end;
 
 //----------------------
@@ -752,29 +869,7 @@ end;
 // Method to draw our TMenu and all his child buttons
 function TMenu.DrawBG: boolean;
 begin
-  BackImg.ColR := 1;
-  BackImg.ColG := 1;
-  BackImg.ColB := 1;
-  BackImg.TexX1 := 0;
-  BackImg.TexY1 := 0;
-  BackImg.TexX2 := 1;
-  BackImg.TexY2 := 1;
-
-  if (BackImg.TexNum > 0) then
-  begin
-    BackImg.X := 0;
-    BackImg.Y := 0;
-    BackImg.Z := 0; // todo: eddie: to the opengl experts: please check this! On the mac z is not initialized???
-    BackImg.W := 800;
-    BackImg.H := 600;
-    DrawTexture(BackImg);
-  end
-  else if (VideoPlayback <> nil) then
-  begin
-    VideoPlayback.GetFrame(VideoBGTimer.GetTime());
-    // FIXME: why do we draw on screen 2? Seems to be wrong.
-    VideoPlayback.DrawGL(2);
-  end;
+  Background.Draw;
 
   Result := true;
 end;
@@ -1391,7 +1486,7 @@ begin
   // method is not implemented by now. This is necessary for theme-switching too.
   // At the moment videos cannot be turned off without restarting USDX. 
 
-  // check if a background texture was found
+  {// check if a background texture was found
   if (BackImg.TexNum = 0)  then
   begin
     // try to open an animated background
@@ -1405,7 +1500,11 @@ begin
         VideoPlayback.Play;
       end;
     end;
-  end;
+  end; }
+  If (Background = nil) then
+    AddBackground(DEFAULTBACKGROUND);
+
+  Background.OnShow;
 end;
 
 procedure TMenu.onShowFinish;
@@ -1451,6 +1550,7 @@ end;
 procedure TMenu.onHide;
 begin
   // nothing
+  Background.OnFinish;
 end;
 
 function TMenu.ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean;
diff --git a/src/menu/UMenuBackground.pas b/src/menu/UMenuBackground.pas
new file mode 100644
index 00000000..762faf34
--- /dev/null
+++ b/src/menu/UMenuBackground.pas
@@ -0,0 +1,85 @@
+{* 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; virtual;
+  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/src/menu/UMenuBackgroundColor.pas b/src/menu/UMenuBackgroundColor.pas
new file mode 100644
index 00000000..26385b44
--- /dev/null
+++ b/src/menu/UMenuBackgroundColor.pas
@@ -0,0 +1,69 @@
+{* 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;
+
+Constructor TMenuBackgroundColor.Create(const ThemedSettings: TThemeBackground);
+begin
+  inherited;
+  Color := ThemedSettings.Color;
+end;
+
+Procedure   TMenuBackgroundColor.Draw;
+begin
+   glClearColor(Color.R, Color.G, Color.B, 0);
+   glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
+end;
+
+end.
\ No newline at end of file
diff --git a/src/menu/UMenuBackgroundFade.pas b/src/menu/UMenuBackgroundFade.pas
new file mode 100644
index 00000000..3bdd631e
--- /dev/null
+++ b/src/menu/UMenuBackgroundFade.pas
@@ -0,0 +1,172 @@
+{* 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;
+
+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
+    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
+    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/src/menu/UMenuBackgroundNone.pas b/src/menu/UMenuBackgroundNone.pas
new file mode 100644
index 00000000..d4188395
--- /dev/null
+++ b/src/menu/UMenuBackgroundNone.pas
@@ -0,0 +1,68 @@
+{* 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;
+
+Constructor TMenuBackgroundNone.Create(const ThemedSettings: TThemeBackground);
+begin
+  inherited;
+end;
+
+Procedure   TMenuBackgroundNone.Draw;
+begin
+  //Do just nothing in here!
+  glClear(GL_DEPTH_BUFFER_BIT);
+end;
+
+end.
\ No newline at end of file
diff --git a/src/menu/UMenuBackgroundTexture.pas b/src/menu/UMenuBackgroundTexture.pas
new file mode 100644
index 00000000..55d1d0b6
--- /dev/null
+++ b/src/menu/UMenuBackgroundTexture.pas
@@ -0,0 +1,122 @@
+{* 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;
+
+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
+  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/src/menu/UMenuBackgroundVideo.pas b/src/menu/UMenuBackgroundVideo.pas
new file mode 100644
index 00000000..a6d02828
--- /dev/null
+++ b/src/menu/UMenuBackgroundVideo.pas
@@ -0,0 +1,204 @@
+{* UltraStar Deluxe - Karaoke Game
+ *
+ * UltraStar Deluxe is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *}
+
+unit UMenuBackgroundVideo;
+
+interface
+
+{$IFDEF FPC}
+  {$MODE Delphi}
+{$ENDIF}
+
+{$I switches.inc}
+
+uses
+  UThemes,
+  UMenuBackground,
+  UVideo;
+
+//TMenuBackgroundColor - Background Color
+//--------
+
+type
+  //DefaultBGVideoPlayback = TVideoPlayback_FFmpeg;
+
+{type 
+  TBGVideoPool = class;
+
+  PBGVideoPoolItem = ^TBGVideoPoolItem;
+  TBGVideoPoolItem = record
+    Parent: TBGVideoPool;
+    VideoPlayback = IVideoPlayback;
+    ReferenceCounter: Cardinal; //Number of Creations
+  end;
+
+  TBGVideo = class
+    private
+      myItem: PBGVideoPoolItem;
+    public
+      Constructor Create(Item: PBGVideoPoolItem); override;
+
+      Function    GetVideoPlayback: IVideoPlayback;
+      Procedure   Draw;
+
+      Destructor  Destroy;
+  end;
+
+  TBGVideoPool = class
+    private
+      Items: PBGVideoPoolItem;
+    public
+      Constructor Create;
+
+      Function    GetBGVideo(filename: String): TBGVideo;
+      Procedure   RemoveItem(
+      Procedure   FreeAllItems;
+
+      Destructor  Destroy;
+  end;
+        
+type }
+  TMenuBackgroundVideo = class (TMenuBackground)
+    private
+      fFilename: String;
+    public
+      Constructor Create(const ThemedSettings: TThemeBackground); override;
+      Procedure   OnShow; override;
+      Procedure   Draw; override;
+      Procedure   OnFinish; override;
+      Destructor  Destroy; override;
+  end;
+
+{var
+  BGVideoPool: TBGVideoPool;  }
+const
+  SUPPORTED_EXTS_BACKGROUNDVIDEO: Array[0..6] of String = ('.avi', '.mov', '.divx', '.mpg', '.mp4', '.mpeg', '.m2v');
+
+implementation
+
+uses
+  gl,
+  glext,
+  UMusic,
+  SysUtils,
+  UTime,
+  USkins,
+  UCommon;
+
+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
+  glClear(GL_DEPTH_BUFFER_BIT);
+
+  VideoPlayback.GetFrame(VideoBGTimer.GetTime());
+    // FIXME: why do we draw on screen 2? Seems to be wrong.
+  VideoPlayback.DrawGL(2);
+end;
+
+// Implementation of TBGVideo
+//--------
+{Constructor TBGVideo.Create(Item: PBGVideoPoolItem);
+begin
+  myItem := PBGVideoPoolItem;
+  Inc(myItem.ReferenceCounter);
+end;
+
+Destructor  TBGVideo.Destroy;
+begin
+  Dec(myItem.ReferenceCounter);
+end;
+
+Function    TBGVideo.GetVideoPlayback: IVideoPlayback;
+begin
+
+end;
+
+Procedure   TBGVideo.Draw;
+begin
+
+end;
+
+// Implementation of TBGVideoPool
+//--------
+
+Constructor TBGVideoPool.Create;
+begin
+
+end;
+
+Destructor  TBGVideoPool.Destroy;
+begin
+
+end;
+
+Function    TBGVideoPool.GetBGVideo(filename: String): TBGVideo;
+begin
+
+end;
+
+Procedure   TBGVideoPool.FreeAllItems;
+begin
+
+end;  }
+
+end.
diff --git a/src/screens/UScreenLoading.pas b/src/screens/UScreenLoading.pas
index 55737b15..f4a3508a 100644
--- a/src/screens/UScreenLoading.pas
+++ b/src/screens/UScreenLoading.pas
@@ -47,7 +47,6 @@ type
       constructor Create; override;
       procedure   onShow; override;
       function    ParseInput(PressedKey: Cardinal; CharCode: WideChar; PressedDown: Boolean): Boolean; override;
-      function    GetBGTexNum: GLUInt;
   end;
 
 implementation
@@ -74,9 +73,4 @@ begin
   inherited;
 end;
 
-function TScreenLoading.GetBGTexNum: GLUInt;
-begin
-  Result := Self.BackImg.TexNum;
-end;
-
 end.
diff --git a/src/screens/UScreenOptionsThemes.pas b/src/screens/UScreenOptionsThemes.pas
index e9fde523..82d7d782 100644
--- a/src/screens/UScreenOptionsThemes.pas
+++ b/src/screens/UScreenOptionsThemes.pas
@@ -194,7 +194,7 @@ begin
   Display.Draw;
   SwapBuffers;
 
-  freeandnil( self );
+  Self.Destroy;
 end;
 
 end.
diff --git a/src/screens/UScreenPopup.pas b/src/screens/UScreenPopup.pas
index 92ef7e28..4ef93549 100644
--- a/src/screens/UScreenPopup.pas
+++ b/src/screens/UScreenPopup.pas
@@ -136,7 +136,9 @@ var
 begin
   inherited Create;
 
-  AddBackground(Theme.CheckPopup.Background.Tex);
+  AddText(Theme.CheckPopup.TextCheck);
+  
+  LoadFromTheme(Theme.CheckPopup);
 
   AddButton(Theme.CheckPopup.Button1);
   if (Length(Button[0].Text) = 0) then
@@ -146,14 +148,6 @@ begin
   if (Length(Button[1].Text) = 0) then
     AddButtonText(14, 20, 'Button 2');
 
-  AddText(Theme.CheckPopup.TextCheck);
-
-  for I := 0 to High(Theme.CheckPopup.Static) do
-    AddStatic(Theme.CheckPopup.Static[I]);
-
-  for I := 0 to High(Theme.CheckPopup.Text) do
-    AddText(Theme.CheckPopup.Text[I]);
-
   Interaction := 0;
 end;
 
@@ -179,6 +173,8 @@ begin
 
   Button[0].Text[0].Text := Language.Translate('SONG_MENU_YES');
   Button[1].Text[0].Text := Language.Translate('SONG_MENU_NO');
+
+  Background.OnShow
 end;
 
 // error popup
@@ -223,20 +219,14 @@ var
 begin
   inherited Create;
 
-  AddBackground(Theme.CheckPopup.Background.Tex);
+  AddText(Theme.ErrorPopup.TextError);
+
+  LoadFromTheme(Theme.ErrorPopup);
 
   AddButton(Theme.ErrorPopup.Button1);
   if (Length(Button[0].Text) = 0) then
     AddButtonText(14, 20, 'Button 1');
 
-  AddText(Theme.ErrorPopup.TextError);
-
-  for I := 0 to High(Theme.ErrorPopup.Static) do
-    AddStatic(Theme.ErrorPopup.Static[I]);
-
-  for I := 0 to High(Theme.ErrorPopup.Text) do
-    AddText(Theme.ErrorPopup.Text[I]);
-
   Interaction := 0;
 end;
 
@@ -259,6 +249,7 @@ procedure TScreenPopupError.ShowPopup(msg: String);
 begin
   Interaction := 0; //Reset Interaction
   Visible := True;  //Set Visible
+  Background.OnShow;
 
 {  //dirty hack... Text[0] is invisible for some strange reason
   for i:=1 to high(Text) do
diff --git a/src/screens/UScreenSong.pas b/src/screens/UScreenSong.pas
index c340be2b..95ccae83 100644
--- a/src/screens/UScreenSong.pas
+++ b/src/screens/UScreenSong.pas
@@ -340,17 +340,25 @@ begin
               if (not CatSongs.Song[Interaction].Main) then // clicked on Song
               begin 
                 if CatSongs.CatNumShow = -3 then
-                  ScreenSongMenu.MenuShow(SM_Playlist)
+                begin
+                  ScreenSongMenu.onShow;
+                  ScreenSongMenu.MenuShow(SM_Playlist);
+                end
                 else
+                begin
+                  ScreenSongMenu.onShow;
                   ScreenSongMenu.MenuShow(SM_Main);
+                end;
               end
               else
               begin
+                ScreenSongMenu.onShow;
                 ScreenSongMenu.MenuShow(SM_Playlist_Load);
               end;
             end //Party Mode -> Show Party Menu
             else
             begin
+              ScreenSongMenu.onShow;
               ScreenSongMenu.MenuShow(SM_Party_Main);
             end;
           end;
@@ -361,7 +369,8 @@ begin
         begin
           if (Songs.SongList.Count > 0) and (Mode = smNormal) then
           begin
-              ScreenSongMenu.MenuShow(SM_Playlist_Load);
+            ScreenSongMenu.onShow;
+            ScreenSongMenu.MenuShow(SM_Playlist_Load);
           end;
           Exit;
         end;
diff --git a/src/ultrastardx.dpr b/src/ultrastardx.dpr
index c35cb620..df546274 100644
--- a/src/ultrastardx.dpr
+++ b/src/ultrastardx.dpr
@@ -151,6 +151,13 @@ uses
   UDrawTexture           in 'menu\UDrawTexture.pas',
   UMenuButtonCollection  in 'menu\UMenuButtonCollection.pas',
 
+  UMenuBackground        in 'menu\UMenuBackground.pas',
+  UMenuBackgroundNone    in 'menu\UMenuBackgroundNone.pas',
+  UMenuBackgroundColor   in 'menu\UMenuBackgroundColor.pas',
+  UMenuBackgroundTexture in 'menu\UMenuBackgroundTexture.pas',
+  UMenuBackgroundVideo   in 'menu\UMenuBackgroundVideo.pas',
+  UMenuBackgroundFade    in 'menu\UMenuBackgroundFade.pas',
+
   //------------------------------
   //Includes - base
   //------------------------------
@@ -189,6 +196,17 @@ uses
   USingScores       in 'base\USingScores.pas',
   USingNotes        in 'base\USingNotes.pas',
 
+  //------------------------------
+  //Includes - Plugin Support
+  //------------------------------
+  {UPluginDefines    in 'pluginsupport\UPluginDefines.pas',
+  UPartyDefines     in 'pluginsupport\UPartyDefines.pas',
+
+  UPartyMode        in 'pluginsupport\UPartyMode.pas',
+  UPartyManager     in 'pluginsupport\UPartyManager.pas',
+  UPartyModePlugin  in 'pluginsupport\UPartyModePlugin.pas',
+  UPluginLoader     in 'pluginsupport\UPluginLoader.pas',    }
+
   UModules          in 'base\UModules.pas',          //List of Modules to Load
   UHooks            in 'base\UHooks.pas',            //Hook Managing
   UServices         in 'base\UServices.pas',         //Service Managing
-- 
cgit v1.2.3