From 5c8e54621afcc5d822bec4045401b0f6489c6702 Mon Sep 17 00:00:00 2001 From: utak3r Date: Tue, 10 Apr 2007 23:17:24 +0000 Subject: [PATCH] Getting a random gradient from a given file --- 2.10/Source/Global.pas | 1 + 2.10/Source/Options.dfm | 60 ++++++++++++++- 2.10/Source/Options.pas | 16 ++++ 2.10/Source/Regstry.pas | 10 +++ 2.10/Source/RndFlame.pas | 161 ++++++++++++++++++++++++++++++++++++++- 5 files changed, 243 insertions(+), 5 deletions(-) diff --git a/2.10/Source/Global.pas b/2.10/Source/Global.pas index 9cd4918..d2fb608 100644 --- a/2.10/Source/Global.pas +++ b/2.10/Source/Global.pas @@ -141,6 +141,7 @@ var mutantMinTransforms, mutantMaxTransforms: integer; KeepBackground: boolean; randGradient: Integer; + randGradientFile: string; defFlameFile: string; PlaySoundOnRenderComplete: boolean; diff --git a/2.10/Source/Options.dfm b/2.10/Source/Options.dfm index e6f4c6c..db46665 100644 --- a/2.10/Source/Options.dfm +++ b/2.10/Source/Options.dfm @@ -991,11 +991,55 @@ object OptionsForm: TOptionsForm object TabSheet1: TTabSheet Caption = 'Gradient' ImageIndex = 5 + object btnGradientsFile: TSpeedButton + Left = 120 + Top = 121 + Width = 24 + Height = 24 + Hint = 'Browse...' + Flat = True + Font.Charset = ANSI_CHARSET + Font.Color = clWindowText + Font.Height = -11 + Font.Name = 'Arial' + Font.Style = [fsBold] + Glyph.Data = { + 36030000424D3603000000000000360000002800000010000000100000000100 + 18000000000000030000120B0000120B00000000000000000000FF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FF00000000000000000000000000000000000000000000 + 0000000000000000000000FF00FFFF00FFFF00FFFF00FFFF00FF000000000000 + 9FCFFF9FCFFF9FCFFF9FCFFF9FCFFF9FCFFF9FCFFF9FCFFF9FCFFF000000FF00 + FFFF00FFFF00FFFF00FF0000009FFFFF0000009FCFFF9FCFFF9FCFFF9FCFFF9F + CFFF9FCFFF9FCFFF9FCFFF9FCFFF000000FF00FFFF00FFFF00FF0000009FFFFF + 9FFFFF0000009FCFFF9FCFFF9FCFFF9FCFFF9FCFFF9FCFFF9FCFFF9FCFFF9FCF + FF000000FF00FFFF00FF0000009FFFFF9FFFFF9FFFFF0000009FCFFF9FCFFF9F + CFFF9FCFFF9FCFFF9FCFFF9FCFFF9FCFFF9FCFFF000000FF00FF0000009FFFFF + 9FFFFF9FFFFF9FFFFF0000000000000000000000000000000000000000000000 + 00000000000000FF00FF0000009FFFFF9FFFFF9FFFFF9FFFFF9FFFFF9FFFFF9F + FFFF9FFFFF9FFFFF000000FF00FFFF00FFFF00FFFF00FFFF00FF0000009FFFFF + 9FFFFF9FFFFF9FFFFF9FFFFF9FFFFF9FFFFF9FFFFF9FFFFF000000FF00FFFF00 + FFFF00FFFF00FFFF00FF0000009FFFFF9FFFFF9FFFFF00000000000000000000 + 0000000000000000000000FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF000000 + 000000000000FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF0000 + 00000000000000FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FF000000000000FF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF0C0C0CFF00FFFF00FFFF00FF0000 + 00FF00FF000000FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FF0B0B0B020202000000FF00FFFF00FFFF00FFFF00FFFF00FFFF00FF + FF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00 + FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF + 00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FFFF00FF} + ParentFont = False + ParentShowHint = False + ShowHint = True + OnClick = btnGradientsFileClick + end object grpGradient: TRadioGroup Left = 8 Top = 4 Width = 137 - Height = 97 + Height = 117 HelpContext = 1029 Caption = 'On random flame' ItemIndex = 0 @@ -1003,14 +1047,15 @@ object OptionsForm: TOptionsForm 'Use random preset' 'Use default' 'Use current' - 'Randomize') + 'Randomize' + 'Random from a file') TabOrder = 0 end object GroupBox3: TGroupBox Left = 153 Top = 4 Width = 281 - Height = 189 + Height = 229 Caption = 'Randomize' TabOrder = 2 object Label18: TLabel @@ -1235,7 +1280,7 @@ object OptionsForm: TOptionsForm end object GroupBox13: TGroupBox Left = 8 - Top = 106 + Top = 146 Width = 137 Height = 87 Caption = 'Smooth palette' @@ -1273,6 +1318,13 @@ object OptionsForm: TOptionsForm Text = '10000' end end + object txtGradientsFile: TEdit + Left = 8 + Top = 122 + Width = 110 + Height = 21 + TabOrder = 3 + end end object TabSheet6: TTabSheet Caption = 'UPR' diff --git a/2.10/Source/Options.pas b/2.10/Source/Options.pas index 04c9926..6a06e02 100644 --- a/2.10/Source/Options.pas +++ b/2.10/Source/Options.pas @@ -217,6 +217,8 @@ type chkOldPaletteFormat: TCheckBox; rgZoomingMode: TRadioGroup; chkShowAllXforms: TCheckBox; + txtGradientsFile: TEdit; + btnGradientsFile: TSpeedButton; procedure btnCancelClick(Sender: TObject); procedure FormShow(Sender: TObject); procedure btnOKClick(Sender: TObject); @@ -248,6 +250,7 @@ type procedure pnlHelpersColorClick(Sender: TObject); procedure btnBrowseSoundClick(Sender: TObject); procedure btnPlayClick(Sender: TObject); + procedure btnGradientsFileClick(Sender: TObject); private { Private declarations } @@ -375,6 +378,7 @@ begin { Gradient tab } grpGradient.ItemIndex := randGradient; + txtGradientsFile.Text := randGradientFile; udMinNodes.Position := MinNodes; udMaxNodes.Position := MaxNodes; udMinHue.Position := MinHue; @@ -507,6 +511,7 @@ begin {Gradient tab } randGradient := grpGradient.ItemIndex; + randGradientFile := txtGradientsFile.Text; MinNodes := udMinNodes.Position; MaxNodes := udMaxNodes.Position; MinHue := udMinHue.Position; @@ -788,5 +793,16 @@ begin sndPlaySound(pchar(SND_ALIAS_SYSTEMASTERISK), SND_ALIAS_ID or SND_NOSTOP or SND_ASYNC); end; +procedure TOptionsForm.btnGradientsFileClick(Sender: TObject); +begin + OpenDialog.Filter := 'Gradient files (*.ugr)|*.ugr'; + OpenDialog.InitialDir := ExtractFilePath(randGradientFile); + OpenDialog.FileName := ''; + if OpenDialog.Execute then + begin + txtGradientsFile.text := OpenDialog.FileName; + end; +end; + end. diff --git a/2.10/Source/Regstry.pas b/2.10/Source/Regstry.pas index be2af3e..6971989 100644 --- a/2.10/Source/Regstry.pas +++ b/2.10/Source/Regstry.pas @@ -373,6 +373,14 @@ begin begin MaxSat := 100; end; + if Registry.ValueExists('RandomGradientFile') then + begin + randGradientFile := Registry.ReadString('RandomGradientFile'); + end + else + begin + randGradientFile := '' + end; if Registry.ValueExists('ReferenceMode') then ReferenceMode := Registry.ReadInteger('ReferenceMode') else ReferenceMode := 0; @@ -621,6 +629,7 @@ begin MaxHue := 600; MaxSat := 100; MaxLum := 100; + randGradientFile := ''; BatchSize := 100; ScriptPath := DefaultPath + 'Scripts\'; defLibrary := DefaultPath + 'Scripts\Functions.asc'; @@ -1043,6 +1052,7 @@ begin Registry.WriteInteger('MaxHue', MaxHue); Registry.WriteInteger('MaxSat', MaxSat); Registry.WriteInteger('MaxLum', MaxLum); + Registry.WriteString('RandomGradientFile', randGradientFile); Registry.WriteInteger('BatchSize', BatchSize); Registry.WriteString('ScriptPath', ScriptPath); Registry.WriteInteger('ExportFileFormat', ExportFileFormat); diff --git a/2.10/Source/RndFlame.pas b/2.10/Source/RndFlame.pas index 54c0da8..f0b5180 100644 --- a/2.10/Source/RndFlame.pas +++ b/2.10/Source/RndFlame.pas @@ -28,10 +28,155 @@ function RandomFlame(SourceCP: TControlPoint= nil; algorithm: integer = 0): TCon implementation uses - SysUtils, Global, cmap, GradientHlpr, XFormMan; + SysUtils, Global, cmap, GradientHlpr, XFormMan, Classes; /////////////////////////////////////////////////////////////////////////////// +procedure RGBBlend(a, b: integer; var Palette: TColorMap); +{ Linear blend between to indices of a palette } +var + c, v: real; + vrange, range: real; + i: integer; +begin + if a = b then + begin + Exit; + end; + range := b - a; + vrange := Palette[b mod 256][0] - Palette[a mod 256][0]; + c := Palette[a mod 256][0]; + v := vrange / range; + for i := (a + 1) to (b - 1) do + begin + c := c + v; + Palette[i mod 256][0] := Round(c); + end; + vrange := Palette[b mod 256][1] - Palette[a mod 256][1]; + c := Palette[a mod 256][1]; + v := vrange / range; + for i := a + 1 to b - 1 do + begin + c := c + v; + Palette[i mod 256][1] := Round(c); + end; + vrange := Palette[b mod 256][2] - Palette[a mod 256][2]; + c := Palette[a mod 256][2]; + v := vrange / range; + for i := a + 1 to b - 1 do + begin + c := c + v; + Palette[i mod 256][2] := Round(c); + end; +end; + +function CreatePalette(strng: string): TColorMap; +{ Loads a palette from a gradient string } +var + Strings: TStringList; + index, i: integer; + Tokens: TStringList; + Indices, Colors: TStringList; + a, b: integer; +begin + Strings := TStringList.Create; + Tokens := TStringList.Create; + Indices := TStringList.Create; + Colors := TStringList.Create; + try + try + Strings.Text := strng; + if Pos('}', Strings.Text) = 0 then raise EFormatInvalid.Create('No closing brace'); + if Pos('{', Strings[0]) = 0 then raise EFormatInvalid.Create('No opening brace.'); + GetTokens(ReplaceTabs(strings.text), tokens); + Tokens.Text := Trim(Tokens.text); + i := 0; + while (Pos('}', Tokens[i]) = 0) and (Pos('opacity:', Lowercase(Tokens[i])) = 0) do + begin + if Pos('index=', LowerCase(Tokens[i])) <> 0 then + Indices.Add(GetVal(Tokens[i])) + else if Pos('color=', LowerCase(Tokens[i])) <> 0 then + Colors.Add(GetVal(Tokens[i])); + inc(i) + end; + for i := 0 to 255 do + begin + Result[i][0] := 0; + Result[i][1] := 0; + Result[i][2] := 0; + end; + if Indices.Count = 0 then raise EFormatInvalid.Create('No color info'); + for i := 0 to Indices.Count - 1 do + begin + try + index := StrToInt(Indices[i]); + while index < 0 do inc(index, 400); + index := Round(Index * (255 / 399)); + indices[i] := IntToStr(index); + assert(index>=0); + assert(index<256); + Result[index][0] := StrToInt(Colors[i]) mod 256; + Result[index][1] := trunc(StrToInt(Colors[i]) / 256) mod 256; + Result[index][2] := trunc(StrToInt(Colors[i]) / 65536); + except + end; + end; + i := 1; + repeat + a := StrToInt(Trim(Indices[i - 1])); + b := StrToInt(Trim(Indices[i])); + RGBBlend(a, b, Result); + inc(i); + until i = Indices.Count; + if (Indices[0] <> '0') or (Indices[Indices.Count - 1] <> '255') then + begin + a := StrToInt(Trim(Indices[Indices.Count - 1])); + b := StrToInt(Trim(Indices[0])) + 256; + RGBBlend(a, b, Result); + end; + except on EFormatInvalid do + begin +// Result := False; + end; + end; + finally + Tokens.Free; + Strings.Free; + Indices.Free; + Colors.Free; + end; +end; + +procedure GetGradientFileGradientsNames(const filename: string; var NamesList: TStringList); +var + i, p: integer; + Title: string; + FStrings: TStringList; +begin + FStrings := TStringList.Create; + FStrings.LoadFromFile(filename); + try + if (Pos('{', FStrings.Text) <> 0) then + begin + for i := 0 to FStrings.Count - 1 do + begin + p := Pos('{', FStrings[i]); + if (p <> 0) and (Pos('(3D)', FStrings[i]) = 0) then + begin + Title := Trim(Copy(FStrings[i], 1, p - 1)); + if Title <> '' then + NamesList.Add(Trim(Copy(FStrings[i], 1, p - 1))); + end; + end; + end; + finally + FStrings.Free; + end; +end; + procedure RandomGradient(SourceCP, DestCP: TControlPoint); +var + tmpGrad: string; + tmpGrdList: TStringList; begin case randGradient of 0: @@ -57,6 +202,20 @@ begin end; 3: DestCP.cmap := GradientHelper.RandomGradient; + 4: + if FileExists(randGradientFile) then + begin + tmpGrdList := TStringList.Create; + GetGradientFileGradientsNames(randGradientFile, tmpGrdList); + tmpGrad := GetGradient(randGradientFile, tmpGrdList.Strings[random(tmpGrdList.Count)]); + DestCP.cmap := CreatePalette(tmpGrad); + tmpGrdList.Free; + end else + begin + cmap_index := Random(NRCMAPS); + GetCMap(cmap_index, 1, DestCP.cmap); + DestCP.cmapIndex := cmap_index; + end; end; end;