From 688182ae4f56aabaf12233f32763274286c5d634 Mon Sep 17 00:00:00 2001 From: whiteshark0 Date: Sun, 21 Sep 2008 11:34:25 +0000 Subject: missing files commited Equalizer now loads reflection settings from theme old equalizer methods removed git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/trunk@1388 b956fd51-792f-4845-bead-9b4dfca2ff2c --- src/base/UThemes.pas | 91 +++++++------- src/menu/UMenuEqualizer.pas | 285 ++++++++++++++++++++++++++++++++++++++++++++ src/screens/UScreenSong.pas | 120 +------------------ 3 files changed, 337 insertions(+), 159 deletions(-) create mode 100644 src/menu/UMenuEqualizer.pas diff --git a/src/base/UThemes.pas b/src/base/UThemes.pas index 2319107a..6097e3ee 100644 --- a/src/base/UThemes.pas +++ b/src/base/UThemes.pas @@ -145,6 +145,23 @@ type SkipX: integer; end; + TThemeEqualizer = record + Visible: Boolean; + Direction: Boolean; + Alpha: real; + X: Integer; + Y: Integer; + Z: Real; + W: Integer; + H: Integer; + Space: Integer; + Bands: Integer; + Length: Integer; + ColR, ColG, ColB: Real; + Reflection: boolean; + Reflectionspacing: Real; + end; + PThemeBasic = ^TThemeBasic; TThemeBasic = class Background: TThemeBackground; @@ -208,20 +225,7 @@ type end; //Equalizer Mod - Equalizer: record - Visible: Boolean; - Direction: Boolean; - Alpha: real; - X: Integer; - Y: Integer; - Z: Real; - W: Integer; - H: Integer; - Space: Integer; - Bands: Integer; - Length: Integer; - ColR, ColG, ColB: Real; - end; + Equalizer: TThemeEqualizer; //Party and Non Party specific Statics and Texts @@ -708,6 +712,7 @@ type procedure ThemeLoadButtonCollection(var Collection: TThemeButtonCollection; Name: string); procedure ThemeLoadButtonCollections(var Collections: AThemeButtonCollection; Name: string); procedure ThemeLoadSelectSlide(var ThemeSelectS: TThemeSelectSlide; Name: string); + procedure ThemeLoadEqualizer(var ThemeEqualizer: TThemeEqualizer; Name: string); procedure ThemeSave(FileName: string); procedure ThemeSaveBasic(Theme: TThemeBasic; Name: string); @@ -939,32 +944,7 @@ begin Song.Cover.Reflections := (ThemeIni.ReadInteger('SongCover', 'Reflections', 0) = 1); //Load Cover Pos and Size from Theme Mod End - //Load Equalizer Pos and Size from Theme Mod - Song.Equalizer.Visible := (ThemeIni.ReadInteger('SongEqualizer', 'Visible', 0) = 1); - Song.Equalizer.Direction := (ThemeIni.ReadInteger('SongEqualizer', 'Direction', 0) = 1); - Song.Equalizer.Alpha := ThemeIni.ReadInteger('SongEqualizer', 'Alpha', 1); - Song.Equalizer.Space := ThemeIni.ReadInteger('SongEqualizer', 'Space', 1); - Song.Equalizer.X := ThemeIni.ReadInteger('SongEqualizer', 'X', 0); - Song.Equalizer.Y := ThemeIni.ReadInteger('SongEqualizer', 'Y', 0); - Song.Equalizer.Z := ThemeIni.ReadInteger('SongEqualizer', 'Z', 1); - Song.Equalizer.W := ThemeIni.ReadInteger('SongEqualizer', 'PieceW', 8); - Song.Equalizer.H := ThemeIni.ReadInteger('SongEqualizer', 'PieceH', 8); - Song.Equalizer.Bands := ThemeIni.ReadInteger('SongEqualizer', 'Bands', 5); - Song.Equalizer.Length := ThemeIni.ReadInteger('SongEqualizer', 'Length', 12); - - //Color - I := ColorExists(ThemeIni.ReadString('SongEqualizer', 'Color', 'Black')); - if I >= 0 then begin - Song.Equalizer.ColR := Color[I].RGB.R; - Song.Equalizer.ColG := Color[I].RGB.G; - Song.Equalizer.ColB := Color[I].RGB.B; - end - else begin - Song.Equalizer.ColR := 0; - Song.Equalizer.ColG := 0; - Song.Equalizer.ColB := 0; - end; - //Load Equalizer Pos and Size from Theme Mod End + ThemeLoadEqualizer(Song.Equalizer, 'SongEqualizer'); //Party and Non Party specific Statics and Texts ThemeLoadStatics (Song.StaticParty, 'SongStaticParty'); @@ -1717,6 +1697,37 @@ begin ThemeSelectS.STDInt := ThemeIni.ReadFloat(Name, 'STDInt', 1); end; +procedure TTheme.ThemeLoadEqualizer(var ThemeEqualizer: TThemeEqualizer; Name: string); +var I: Integer; +begin + ThemeEqualizer.Visible := (ThemeIni.ReadInteger(Name, 'Visible', 0) = 1); + ThemeEqualizer.Direction := (ThemeIni.ReadInteger(Name, 'Direction', 0) = 1); + ThemeEqualizer.Alpha := ThemeIni.ReadInteger(Name, 'Alpha', 1); + ThemeEqualizer.Space := ThemeIni.ReadInteger(Name, 'Space', 1); + ThemeEqualizer.X := ThemeIni.ReadInteger(Name, 'X', 0); + ThemeEqualizer.Y := ThemeIni.ReadInteger(Name, 'Y', 0); + ThemeEqualizer.Z := ThemeIni.ReadInteger(Name, 'Z', 1); + ThemeEqualizer.W := ThemeIni.ReadInteger(Name, 'PieceW', 8); + ThemeEqualizer.H := ThemeIni.ReadInteger(Name, 'PieceH', 8); + ThemeEqualizer.Bands := ThemeIni.ReadInteger(Name, 'Bands', 5); + ThemeEqualizer.Length := ThemeIni.ReadInteger(Name, 'Length', 12); + ThemeEqualizer.Reflection := (ThemeIni.ReadInteger(Name, 'Reflection', 0) = 1); + ThemeEqualizer.ReflectionSpacing := ThemeIni.ReadFloat(Name, 'ReflectionSpacing', 15); + + //Color + I := ColorExists(ThemeIni.ReadString(Name, 'Color', 'Black')); + if I >= 0 then begin + ThemeEqualizer.ColR := Color[I].RGB.R; + ThemeEqualizer.ColG := Color[I].RGB.G; + ThemeEqualizer.ColB := Color[I].RGB.B; + end + else begin + ThemeEqualizer.ColR := 0; + ThemeEqualizer.ColG := 0; + ThemeEqualizer.ColB := 0; + end; +end; + procedure TTheme.LoadColors; var SL: TStringList; diff --git a/src/menu/UMenuEqualizer.pas b/src/menu/UMenuEqualizer.pas new file mode 100644 index 00000000..8cff606d --- /dev/null +++ b/src/menu/UMenuEqualizer.pas @@ -0,0 +1,285 @@ +unit UMenuEqualizer; + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$I switches.inc} + +uses UMusic, UThemes; + +type + //---------------- + //Tms_Equalizer + //Class displaying an equalizer (Songscreen) + //---------------- + Tms_Equalizer = class(TObject) + private + FFTData: TFFTData; // moved here to avoid stack overflows + BandData: array of Byte; + RefreshTime: Cardinal; + + Source: IAudioPlayback; + + Procedure Analyse; + public + X: Integer; + Y: Integer; + Z: Real; + + W: Integer; + H: Integer; + Space: Integer; + + Visible: Boolean; + Alpha: real; + Color: TRGB; + + Direction: Boolean; + + BandLength: Integer; + + Reflection: boolean; + Reflectionspacing: Real; + + + constructor Create(Source: IAudioPlayback; mySkin: TThemeEqualizer); + + procedure Draw; + + Procedure SetBands(Value: Byte); + Function GetBands: Byte; + Property Bands: Byte read GetBands write SetBands; + procedure SetSource(newSource: IAudioPlayback); + end; + +implementation +uses math, SDL, gl, glext; + + +constructor Tms_Equalizer.Create(Source: IAudioPlayback; mySkin: TThemeEqualizer); +var I: Integer; +begin + If (Source <> nil) then + begin + X := mySkin.X; + Y := mySkin.Y; + W := mySkin.W; + H := mySkin.H; + Z := mySkin.Z; + + Space := mySkin.Space; + + Visible := mySkin.Visible; + Alpha := mySkin.Alpha; + Color.R := mySkin.ColR; + Color.G := mySkin.ColG; + Color.B := mySkin.ColB; + + Direction := mySkin.Direction; + Bands := mySkin.Bands; + BandLength := mySkin.Length; + + Reflection := mySkin.Reflection; + Reflectionspacing := mySkin.Reflectionspacing; + + Self.Source := Source; + + + //Check if Visible + If (Bands <= 0) OR + (BandLength <= 0) OR + (W <= 0) OR + (H <= 0) OR + (Alpha <= 0) then + Visible := False; + + //ClearArray + For I := low(BandData) to high(BandData) do + BandData[I] := 3; + end + else + Visible := False; +end; + +//-------- +// evaluate FFT-Data +//-------- +Procedure Tms_Equalizer.Analyse; + var + I: Integer; + ChansPerBand: byte; // channels per band + MaxChannel: Integer; + Pos: Real; + CurBand: Integer; +begin + Source.GetFFTData(FFTData); + + Pos := 0; + // use only the first approx. 92 of 256 FFT-channels (approx. up to 8kHz + ChansPerBand := ceil(92 / Bands); // How much channels are used for one Band + MaxChannel := ChansPerBand * Bands - 1; + + // Change Lengths + for i := 0 to MaxChannel do + begin + // Gain higher freq. data so that the bars are visible + if i > 35 then + FFTData[i] := FFTData[i] * 8 + else if i > 11 then + FFTData[i] := FFTData[i] * 4.5 + else + FFTData[i] := FFTData[i] * 1.1; + + // clamp data + if (FFTData[i] > 1) then + FFTData[i] := 1; + + // Get max. pos + if (FFTData[i] * BandLength > Pos) then + Pos := FFTData[i] * BandLength; + + // Check if this is the last channel in the band + if ((i+1) mod ChansPerBand = 0) then + begin + CurBand := i div ChansPerBand; + + // Smooth delay if new equalizer is lower than the old one + if ((BandData[CurBand] > Pos) and (BandData[CurBand] > 1)) then + BandData[CurBand] := BandData[CurBand] - 1 + else + BandData[CurBand] := Round(Pos); + + Pos := 0; + end; + end; +end; + +//-------- +// Draw SpectrumAnalyser, Call Analyse +//-------- +procedure Tms_Equalizer.Draw; + var + CurTime: Cardinal; + PosX, PosY: Real; + I, J: Integer; + Diff: Real; + + Function GetAlpha(H: Single): Single; + begin + Result := (Alpha * 0.3) *(1 - H/(Bands * (W + Space))); + end; +begin + If (Visible) AND not (AudioPlayback.Finished) then + begin + //Call Analyse if necessary + CurTime := SDL_GetTicks(); + If (CurTime > RefreshTime) then + begin + Analyse; + + RefreshTime := CurTime + 44; + end; + + //Draw Equalizer Bands + // Setup OpenGL + glColorRGB(Color, Alpha); + glDisable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + + // Set position of the first equalizer bar + PosY := Y; + PosX := X; + + // Draw bars for each band + for I := 0 to High(BandData) do + begin + // Reset to lower or left position depending on the drawing-direction + if Direction then // Vertical bars + // FIXME: Is Y the upper or lower coordinate? + PosY := Y //+ (H + Space) * BandLength + else // Horizontal bars + PosX := X; + + // Draw the bar as a stack of blocks + for J := 1 to BandData[I] do + begin + // Draw block + glBegin(GL_QUADS); + glVertex3f(PosX, PosY, Z); + glVertex3f(PosX, PosY+H, Z); + glVertex3f(PosX+W, PosY+H, Z); + glVertex3f(PosX+W, PosY, Z); + glEnd; + + If (Reflection) AND (J < BandLength div 2) then + begin + Diff := (Y-PosY) + H; + + //Draw Reflection + If Direction then + begin + glBegin(GL_QUADS); + glColorRGB(Color, GetAlpha(Diff)); + glVertex3f(PosX, Diff + Y + ReflectionSpacing, Z); + glVertex3f(PosX, Diff + Y+H + ReflectionSpacing, Z); + glVertex3f(PosX+W, Diff + Y+H + ReflectionSpacing, Z); + glVertex3f(PosX+W, Diff + Y + ReflectionSpacing, Z); + glColorRGB(Color, GetAlpha(Diff + H)); + glEnd; + end + else + begin + glBegin(GL_QUADS); + glColorRGB(Color, GetAlpha(Diff)); + glVertex3f(PosX, Diff + Y + (H + Space)*Bands + ReflectionSpacing, Z); + glVertex3f(PosX, Diff + Y+H + (H + Space)*Bands + ReflectionSpacing, Z); + glVertex3f(PosX+W, Diff + Y+H + (H + Space)*Bands + ReflectionSpacing, Z); + glVertex3f(PosX+W, Diff + Y + (H + Space)*Bands + ReflectionSpacing, Z); + glColorRGB(Color, GetAlpha(Diff + H)); + glEnd; + end; + + glColorRGB(Color, Alpha); + end; + + + // Calc position of the bar's next block + if Direction then // Vertical bars + PosY := PosY - H - Space + else // Horizontal bars + PosX := PosX + W + Space; + end; + + // Calc position of the next bar + if Direction then // Vertical bars + PosX := PosX + W + Space + else // Horizontal bars + PosY := PosY + H + Space; + end; + + + end; +end; + +Procedure Tms_Equalizer.SetBands(Value: Byte); +begin + SetLength(BandData, Value); +end; + +Function Tms_Equalizer.GetBands: Byte; +begin + Result := Length(BandData); +end; + +Procedure Tms_Equalizer.SetSource(newSource: IAudioPlayback); +begin + If (newSource <> nil) then + Source := newSource; +end; + + + +end. \ No newline at end of file diff --git a/src/screens/UScreenSong.pas b/src/screens/UScreenSong.pas index 1b5e4c41..f632afe0 100644 --- a/src/screens/UScreenSong.pas +++ b/src/screens/UScreenSong.pas @@ -110,7 +110,6 @@ type procedure ShowCatTLCustom(Caption: String);// Show Custom Text in Top left procedure HideCatTL;// Show Cat in Tob left procedure Refresh; //Refresh Song Sorting - procedure DrawEqualizer; procedure ChangeMusic; //Party Mode procedure SelectRandomSong; @@ -776,13 +775,8 @@ begin // Randomize Patch Randomize; - {//Equalizer - SetLength(EqualizerBands, Theme.Song.Equalizer.Bands); - //ClearArray - For I := low(EqualizerBands) to high(EqualizerBands) do - EqualizerBands[I] := 3; } - Equalizer := Tms_Equalizer.Create(AudioPlayback); + Equalizer := Tms_Equalizer.Create(AudioPlayback, Theme.Song.Equalizer); if (Length(CatSongs.Song) > 0) then Interaction := 0; @@ -1495,8 +1489,6 @@ begin for I := 0 to Length(Text) - 1 do Text[I].Draw; - - //Draw Equalizer Equalizer.Draw; DrawExtensions; @@ -1656,116 +1648,6 @@ begin FixSelected2; end; -procedure TScreenSong.DrawEqualizer; -{var - I, J: Integer; - ChansPerBand: byte; // channels per band - MaxChannel: Integer; - CurBand: Integer; // current band - CurTime: Cardinal; - PosX, PosY: Integer; - Pos: Real; } -begin - { // Nothing to do if no music is played or an equalizer bar consists of no block - if (AudioPlayback.Finished or (Theme.Song.Equalizer.Length <= 0)) then - Exit; - - CurTime := SDL_GetTicks(); - - // Evaluate FFT-data every 44 ms - if (CurTime >= EqualizerTime) then - begin - EqualizerTime := CurTime + 44; - AudioPlayback.GetFFTData(EqualizerData); - - Pos := 0; - // use only the first approx. 92 of 256 FFT-channels (approx. up to 8kHz - ChansPerBand := ceil(92 / Theme.Song.Equalizer.Bands); // How much channels are used for one Band - MaxChannel := ChansPerBand * Theme.Song.Equalizer.Bands - 1; - - // Change Lengths - for i := 0 to MaxChannel do - begin - // Gain higher freq. data so that the bars are visible - if i > 35 then - EqualizerData[i] := EqualizerData[i] * 8 - else if i > 11 then - EqualizerData[i] := EqualizerData[i] * 4.5 - else - EqualizerData[i] := EqualizerData[i] * 1.1; - - // clamp data - if (EqualizerData[i] > 1) then - EqualizerData[i] := 1; - - // Get max. pos - if (EqualizerData[i] * Theme.Song.Equalizer.Length > Pos) then - Pos := EqualizerData[i] * Theme.Song.Equalizer.Length; - - // Check if this is the last channel in the band - if ((i+1) mod ChansPerBand = 0) then - begin - CurBand := i div ChansPerBand; - - // Smooth delay if new equalizer is lower than the old one - if ((EqualizerBands[CurBand] > Pos) and (EqualizerBands[CurBand] > 1)) then - EqualizerBands[CurBand] := EqualizerBands[CurBand] - 1 - else - EqualizerBands[CurBand] := Round(Pos); - - Pos := 0; - end; - end; - - end; - - // Draw equalizer bands - - // Setup OpenGL - glColor4f(Theme.Song.Equalizer.ColR, Theme.Song.Equalizer.ColG, Theme.Song.Equalizer.ColB, Theme.Song.Equalizer.Alpha); - glDisable(GL_TEXTURE_2D); - glEnable(GL_BLEND); - - // Set position of the first equalizer bar - PosY := Theme.Song.Equalizer.Y; - PosX := Theme.Song.Equalizer.X; - - // Draw bars for each band - for I := 0 to High(EqualizerBands) do - begin - // Reset to lower or left position depending on the drawing-direction - if Theme.Song.Equalizer.Direction then // Vertical bars - // FIXME: Is Theme.Song.Equalizer.Y the upper or lower coordinate? - PosY := Theme.Song.Equalizer.Y //+ (Theme.Song.Equalizer.H + Theme.Song.Equalizer.Space) * Theme.Song.Equalizer.Length - else // Horizontal bars - PosX := Theme.Song.Equalizer.X; - - // Draw the bar as a stack of blocks - for J := 1 to EqualizerBands[I] do - begin - // Draw block - glBegin(GL_QUADS); - glVertex3f(PosX, PosY, Theme.Song.Equalizer.Z); - glVertex3f(PosX, PosY+Theme.Song.Equalizer.H, Theme.Song.Equalizer.Z); - glVertex3f(PosX+Theme.Song.Equalizer.W, PosY+Theme.Song.Equalizer.H, Theme.Song.Equalizer.Z); - glVertex3f(PosX+Theme.Song.Equalizer.W, PosY, Theme.Song.Equalizer.Z); - glEnd; - - // Calc position of the bar's next block - if Theme.Song.Equalizer.Direction then // Vertical bars - PosY := PosY - Theme.Song.Equalizer.H - Theme.Song.Equalizer.Space - else // Horizontal bars - PosX := PosX + Theme.Song.Equalizer.W + Theme.Song.Equalizer.Space; - end; - - // Calc position of the next bar - if Theme.Song.Equalizer.Direction then // Vertical bars - PosX := PosX + Theme.Song.Equalizer.W + Theme.Song.Equalizer.Space - else // Horizontal bars - PosY := PosY + Theme.Song.Equalizer.H + Theme.Song.Equalizer.Space; - end; } -end; - procedure TScreenSong.SelectRandomSong; var I, I2: Integer; -- cgit v1.2.3